aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
committerMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
commit2d8ad8719591fa803b0d589ed057fa46f49b7155 (patch)
tree4ae051577dad1161c91dafbf4207bb10a9dc91bb /drivers/scsi/mpt2sas
parent9b4ce7bce5f30712fd926ab4599a803314a07719 (diff)
parentc56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (diff)
Merge commit 'v2.6.38-rc1' into kbuild/packaging
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/Kconfig3
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h36
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h236
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_history.txt98
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h48
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h200
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h6
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_sas.h13
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h51
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c479
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h95
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c68
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c480
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_debug.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c2251
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c910
17 files changed, 3858 insertions, 1120 deletions
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
index 70c4c2467dd..bbb7e4bf30a 100644
--- a/drivers/scsi/mpt2sas/Kconfig
+++ b/drivers/scsi/mpt2sas/Kconfig
@@ -2,7 +2,7 @@
2# Kernel configuration file for the MPT2SAS 2# Kernel configuration file for the MPT2SAS
3# 3#
4# This code is based on drivers/scsi/mpt2sas/Kconfig 4# This code is based on drivers/scsi/mpt2sas/Kconfig
5# Copyright (C) 2007-2009 LSI Corporation 5# Copyright (C) 2007-2010 LSI Corporation
6# (mailto:DL-MPTFusionLinux@lsi.com) 6# (mailto:DL-MPTFusionLinux@lsi.com)
7 7
8# This program is free software; you can redistribute it and/or 8# This program is free software; you can redistribute it and/or
@@ -44,6 +44,7 @@ config SCSI_MPT2SAS
44 tristate "LSI MPT Fusion SAS 2.0 Device Driver" 44 tristate "LSI MPT Fusion SAS 2.0 Device Driver"
45 depends on PCI && SCSI 45 depends on PCI && SCSI
46 select SCSI_SAS_ATTRS 46 select SCSI_SAS_ATTRS
47 select RAID_ATTRS
47 ---help--- 48 ---help---
48 This driver supports PCI-Express SAS 6Gb/s Host Adapters. 49 This driver supports PCI-Express SAS 6Gb/s Host Adapters.
49 50
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index 91416810529..8be75e65f76 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2.h 5 * Name: mpi2.h
@@ -8,7 +8,7 @@
8 * scatter/gather formats. 8 * scatter/gather formats.
9 * Creation Date: June 21, 2006 9 * Creation Date: June 21, 2006
10 * 10 *
11 * mpi2.h Version: 02.00.13 11 * mpi2.h Version: 02.00.16
12 * 12 *
13 * Version History 13 * Version History
14 * --------------- 14 * ---------------
@@ -53,6 +53,16 @@
53 * bytes reserved. 53 * bytes reserved.
54 * Added RAID Accelerator functionality. 54 * Added RAID Accelerator functionality.
55 * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT. 55 * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT.
56 * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT.
57 * Added MSI-x index mask and shift for Reply Post Host
58 * Index register.
59 * Added function code for Host Based Discovery Action.
60 * 02-10-10 02.00.15 Bumped MPI2_HEADER_VERSION_UNIT.
61 * Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL.
62 * Added defines for product-specific range of message
63 * function codes, 0xF0 to 0xFF.
64 * 05-12-10 02.00.16 Bumped MPI2_HEADER_VERSION_UNIT.
65 * Added alternative defines for the SGE Direction bit.
56 * -------------------------------------------------------------------------- 66 * --------------------------------------------------------------------------
57 */ 67 */
58 68
@@ -78,7 +88,7 @@
78#define MPI2_VERSION_02_00 (0x0200) 88#define MPI2_VERSION_02_00 (0x0200)
79 89
80/* versioning for this MPI header set */ 90/* versioning for this MPI header set */
81#define MPI2_HEADER_VERSION_UNIT (0x0D) 91#define MPI2_HEADER_VERSION_UNIT (0x10)
82#define MPI2_HEADER_VERSION_DEV (0x00) 92#define MPI2_HEADER_VERSION_DEV (0x00)
83#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) 93#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
84#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) 94#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@@ -232,9 +242,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
232#define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048) 242#define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048)
233 243
234/* 244/*
235 * Offset for the Reply Descriptor Post Queue 245 * Defines for the Reply Descriptor Post Queue
236 */ 246 */
237#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) 247#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C)
248#define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF)
249#define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000)
250#define MPI2_RPHI_MSIX_INDEX_SHIFT (24)
238 251
239/* 252/*
240 * Defines for the HCBSize and address 253 * Defines for the HCBSize and address
@@ -466,8 +479,6 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
466/***************************************************************************** 479/*****************************************************************************
467* 480*
468* Message Functions 481* Message Functions
469* 0x80 -> 0x8F reserved for private message use per product
470*
471* 482*
472*****************************************************************************/ 483*****************************************************************************/
473 484
@@ -497,12 +508,20 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
497#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */ 508#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */
498#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */ 509#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */
499#define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator*/ 510#define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator*/
511/* Host Based Discovery Action */
512#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F)
513/* Power Management Control */
514#define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30)
515/* beginning of product-specific range */
516#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0)
517/* end of product-specific range */
518#define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC (0xFF)
519
500 520
501 521
502 522
503/* Doorbell functions */ 523/* Doorbell functions */
504#define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) 524#define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40)
505/* #define MPI2_FUNCTION_IO_UNIT_RESET (0x41) */
506#define MPI2_FUNCTION_HANDSHAKE (0x42) 525#define MPI2_FUNCTION_HANDSHAKE (0x42)
507 526
508 527
@@ -912,6 +931,9 @@ typedef struct _MPI2_MPI_SGE_UNION
912#define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00) 931#define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00)
913#define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04) 932#define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04)
914 933
934#define MPI2_SGE_FLAGS_DEST (MPI2_SGE_FLAGS_IOC_TO_HOST)
935#define MPI2_SGE_FLAGS_SOURCE (MPI2_SGE_FLAGS_HOST_TO_IOC)
936
915/* Address Size */ 937/* Address Size */
916 938
917#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00) 939#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index 1611c57a6fd..d76a6584760 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_cnfg.h 5 * Name: mpi2_cnfg.h
6 * Title: MPI Configuration messages and pages 6 * Title: MPI Configuration messages and pages
7 * Creation Date: November 10, 2006 7 * Creation Date: November 10, 2006
8 * 8 *
9 * mpi2_cnfg.h Version: 02.00.12 9 * mpi2_cnfg.h Version: 02.00.15
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -107,6 +107,24 @@
107 * to SAS Device Page 0 Flags field. 107 * to SAS Device Page 0 Flags field.
108 * Added PhyInfo defines for power condition. 108 * Added PhyInfo defines for power condition.
109 * Added Ethernet configuration pages. 109 * Added Ethernet configuration pages.
110 * 10-28-09 02.00.13 Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY.
111 * Added SAS PHY Page 4 structure and defines.
112 * 02-10-10 02.00.14 Modified the comments for the configuration page
113 * structures that contain an array of data. The host
114 * should use the "count" field in the page data (e.g. the
115 * NumPhys field) to determine the number of valid elements
116 * in the array.
117 * Added/modified some MPI2_MFGPAGE_DEVID_SAS defines.
118 * Added PowerManagementCapabilities to IO Unit Page 7.
119 * Added PortWidthModGroup field to
120 * MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS.
121 * Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines.
122 * Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines.
123 * Added MPI2_CONFIG_PAGE_SASIOUNIT_8 and related defines.
124 * 05-12-10 02.00.15 Added MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT
125 * define.
126 * Added MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE define.
127 * Added MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY define.
110 * -------------------------------------------------------------------------- 128 * --------------------------------------------------------------------------
111 */ 129 */
112 130
@@ -319,7 +337,7 @@ typedef struct _MPI2_CONFIG_REQUEST
319#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06) 337#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06)
320#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07) 338#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07)
321 339
322/* values for SGLFlags field are in the SGL section of mpi2.h */ 340/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
323 341
324 342
325/* Config Reply Message */ 343/* Config Reply Message */
@@ -365,14 +383,19 @@ typedef struct _MPI2_CONFIG_REPLY
365#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) 383#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064)
366#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) 384#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065)
367 385
386#define MPI2_MFGPAGE_DEVID_SSS6200 (0x007E)
387
368#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) 388#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080)
369#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) 389#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081)
370#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) 390#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082)
371#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083) 391#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083)
372#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084) 392#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084)
373#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085) 393#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085)
374#define MPI2_MFGPAGE_DEVID_SAS2208_7 (0x0086) 394#define MPI2_MFGPAGE_DEVID_SAS2308_1 (0x0086)
375#define MPI2_MFGPAGE_DEVID_SAS2208_8 (0x0087) 395#define MPI2_MFGPAGE_DEVID_SAS2308_2 (0x0087)
396#define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E)
397
398
376 399
377 400
378/* Manufacturing Page 0 */ 401/* Manufacturing Page 0 */
@@ -538,7 +561,7 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_4
538 561
539/* 562/*
540 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 563 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
541 * one and check Header.PageLength or NumPhys at runtime. 564 * one and check the value returned for NumPhys at runtime.
542 */ 565 */
543#ifndef MPI2_MAN_PAGE_5_PHY_ENTRIES 566#ifndef MPI2_MAN_PAGE_5_PHY_ENTRIES
544#define MPI2_MAN_PAGE_5_PHY_ENTRIES (1) 567#define MPI2_MAN_PAGE_5_PHY_ENTRIES (1)
@@ -616,7 +639,7 @@ typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO
616 639
617/* 640/*
618 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 641 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
619 * one and check NumPhys at runtime. 642 * one and check the value returned for NumPhys at runtime.
620 */ 643 */
621#ifndef MPI2_MANPAGE7_CONNECTOR_INFO_MAX 644#ifndef MPI2_MANPAGE7_CONNECTOR_INFO_MAX
622#define MPI2_MANPAGE7_CONNECTOR_INFO_MAX (1) 645#define MPI2_MANPAGE7_CONNECTOR_INFO_MAX (1)
@@ -712,7 +735,9 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
712#define MPI2_IOUNITPAGE1_PAGEVERSION (0x04) 735#define MPI2_IOUNITPAGE1_PAGEVERSION (0x04)
713 736
714/* IO Unit Page 1 Flags defines */ 737/* IO Unit Page 1 Flags defines */
738#define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800)
715#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) 739#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600)
740#define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT (9)
716#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) 741#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000)
717#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) 742#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200)
718#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400) 743#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400)
@@ -728,7 +753,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
728 753
729/* 754/*
730 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 755 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
731 * one and check Header.PageLength at runtime. 756 * one and check the value returned for GPIOCount at runtime.
732 */ 757 */
733#ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX 758#ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX
734#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1) 759#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1)
@@ -757,7 +782,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3
757 782
758/* 783/*
759 * Upper layer code (drivers, utilities, etc.) should leave this define set to 784 * Upper layer code (drivers, utilities, etc.) should leave this define set to
760 * one and check Header.PageLength or NumDmaEngines at runtime. 785 * one and check the value returned for NumDmaEngines at runtime.
761 */ 786 */
762#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES 787#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES
763#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES (1) 788#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES (1)
@@ -820,7 +845,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
820 U8 PCIeWidth; /* 0x06 */ 845 U8 PCIeWidth; /* 0x06 */
821 U8 PCIeSpeed; /* 0x07 */ 846 U8 PCIeSpeed; /* 0x07 */
822 U32 ProcessorState; /* 0x08 */ 847 U32 ProcessorState; /* 0x08 */
823 U32 Reserved2; /* 0x0C */ 848 U32 PowerManagementCapabilities; /* 0x0C */
824 U16 IOCTemperature; /* 0x10 */ 849 U16 IOCTemperature; /* 0x10 */
825 U8 IOCTemperatureUnits; /* 0x12 */ 850 U8 IOCTemperatureUnits; /* 0x12 */
826 U8 IOCSpeed; /* 0x13 */ 851 U8 IOCSpeed; /* 0x13 */
@@ -828,7 +853,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
828} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7, 853} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
829 Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t; 854 Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t;
830 855
831#define MPI2_IOUNITPAGE7_PAGEVERSION (0x00) 856#define MPI2_IOUNITPAGE7_PAGEVERSION (0x01)
832 857
833/* defines for IO Unit Page 7 PCIeWidth field */ 858/* defines for IO Unit Page 7 PCIeWidth field */
834#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01) 859#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01)
@@ -849,6 +874,14 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
849#define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01) 874#define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01)
850#define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02) 875#define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02)
851 876
877/* defines for IO Unit Page 7 PowerManagementCapabilities field */
878#define MPI2_IOUNITPAGE7_PMCAP_12_5_PCT_IOCSPEED (0x00000400)
879#define MPI2_IOUNITPAGE7_PMCAP_25_0_PCT_IOCSPEED (0x00000200)
880#define MPI2_IOUNITPAGE7_PMCAP_50_0_PCT_IOCSPEED (0x00000100)
881#define MPI2_IOUNITPAGE7_PMCAP_PCIE_WIDTH_CHANGE (0x00000008)
882#define MPI2_IOUNITPAGE7_PMCAP_PCIE_SPEED_CHANGE (0x00000004)
883
884
852/* defines for IO Unit Page 7 IOCTemperatureUnits field */ 885/* defines for IO Unit Page 7 IOCTemperatureUnits field */
853#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00) 886#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00)
854#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01) 887#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01)
@@ -1192,7 +1225,7 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_3
1192 1225
1193/* 1226/*
1194 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1227 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1195 * one and check Header.PageLength or NumPhys at runtime. 1228 * one and check the value returned for NumPhys at runtime.
1196 */ 1229 */
1197#ifndef MPI2_BIOS_PAGE_4_PHY_ENTRIES 1230#ifndef MPI2_BIOS_PAGE_4_PHY_ENTRIES
1198#define MPI2_BIOS_PAGE_4_PHY_ENTRIES (1) 1231#define MPI2_BIOS_PAGE_4_PHY_ENTRIES (1)
@@ -1266,7 +1299,7 @@ typedef struct _MPI2_RAIDVOL0_SETTINGS
1266 1299
1267/* 1300/*
1268 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1301 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1269 * one and check Header.PageLength at runtime. 1302 * one and check the value returned for NumPhysDisks at runtime.
1270 */ 1303 */
1271#ifndef MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX 1304#ifndef MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX
1272#define MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX (1) 1305#define MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX (1)
@@ -1323,6 +1356,7 @@ typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0
1323#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000) 1356#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000)
1324#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000) 1357#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000)
1325#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x00010000) 1358#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x00010000)
1359#define MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT (0x00000080)
1326#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040) 1360#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040)
1327#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020) 1361#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020)
1328#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000) 1362#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000)
@@ -1445,11 +1479,15 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0
1445#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03) 1479#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03)
1446#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04) 1480#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04)
1447#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05) 1481#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05)
1482#define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE (0x06)
1448#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF) 1483#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF)
1449 1484
1450/* PhysDiskAttributes defines */ 1485/* PhysDiskAttributes defines */
1486#define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK (0x0C)
1451#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08) 1487#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08)
1452#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE (0x04) 1488#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE (0x04)
1489
1490#define MPI2_PHYSDISK0_ATTRIB_PROTOCOL_MASK (0x03)
1453#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02) 1491#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02)
1454#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01) 1492#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01)
1455 1493
@@ -1468,7 +1506,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0
1468 1506
1469/* 1507/*
1470 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1508 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1471 * one and check Header.PageLength or NumPhysDiskPaths at runtime. 1509 * one and check the value returned for NumPhysDiskPaths at runtime.
1472 */ 1510 */
1473#ifndef MPI2_RAID_PHYS_DISK1_PATH_MAX 1511#ifndef MPI2_RAID_PHYS_DISK1_PATH_MAX
1474#define MPI2_RAID_PHYS_DISK1_PATH_MAX (1) 1512#define MPI2_RAID_PHYS_DISK1_PATH_MAX (1)
@@ -1521,6 +1559,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
1521#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03) 1559#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03)
1522#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04) 1560#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04)
1523#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS (0x05) 1561#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS (0x05)
1562#define MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY (0x06)
1524#define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08) 1563#define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08)
1525#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09) 1564#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09)
1526#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A) 1565#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A)
@@ -1547,6 +1586,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
1547#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) 1586#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000)
1548 1587
1549#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000) 1588#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000)
1589#define MPI2_SAS_PHYINFO_SHIFT_PHY_POWER_CONDITION (27)
1550#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) 1590#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000)
1551#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) 1591#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000)
1552#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) 1592#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000)
@@ -1630,7 +1670,7 @@ typedef struct _MPI2_SAS_IO_UNIT0_PHY_DATA
1630 1670
1631/* 1671/*
1632 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1672 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1633 * one and check Header.ExtPageLength or NumPhys at runtime. 1673 * one and check the value returned for NumPhys at runtime.
1634 */ 1674 */
1635#ifndef MPI2_SAS_IOUNIT0_PHY_MAX 1675#ifndef MPI2_SAS_IOUNIT0_PHY_MAX
1636#define MPI2_SAS_IOUNIT0_PHY_MAX (1) 1676#define MPI2_SAS_IOUNIT0_PHY_MAX (1)
@@ -1701,7 +1741,7 @@ typedef struct _MPI2_SAS_IO_UNIT1_PHY_DATA
1701 1741
1702/* 1742/*
1703 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1743 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1704 * one and check Header.ExtPageLength or NumPhys at runtime. 1744 * one and check the value returned for NumPhys at runtime.
1705 */ 1745 */
1706#ifndef MPI2_SAS_IOUNIT1_PHY_MAX 1746#ifndef MPI2_SAS_IOUNIT1_PHY_MAX
1707#define MPI2_SAS_IOUNIT1_PHY_MAX (1) 1747#define MPI2_SAS_IOUNIT1_PHY_MAX (1)
@@ -1792,7 +1832,7 @@ typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP
1792 1832
1793/* 1833/*
1794 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1834 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1795 * four and check Header.ExtPageLength or NumPhys at runtime. 1835 * one and check the value returned for NumPhys at runtime.
1796 */ 1836 */
1797#ifndef MPI2_SAS_IOUNIT4_PHY_MAX 1837#ifndef MPI2_SAS_IOUNIT4_PHY_MAX
1798#define MPI2_SAS_IOUNIT4_PHY_MAX (4) 1838#define MPI2_SAS_IOUNIT4_PHY_MAX (4)
@@ -1830,7 +1870,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4
1830 1870
1831typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS { 1871typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
1832 U8 ControlFlags; /* 0x00 */ 1872 U8 ControlFlags; /* 0x00 */
1833 U8 Reserved1; /* 0x01 */ 1873 U8 PortWidthModGroup; /* 0x01 */
1834 U16 InactivityTimerExponent; /* 0x02 */ 1874 U16 InactivityTimerExponent; /* 0x02 */
1835 U8 SATAPartialTimeout; /* 0x04 */ 1875 U8 SATAPartialTimeout; /* 0x04 */
1836 U8 Reserved2; /* 0x05 */ 1876 U8 Reserved2; /* 0x05 */
@@ -1850,6 +1890,9 @@ typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
1850#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02) 1890#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02)
1851#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01) 1891#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01)
1852 1892
1893/* defines for PortWidthModeGroup field */
1894#define MPI2_SASIOUNIT5_PWMG_DISABLE (0xFF)
1895
1853/* defines for InactivityTimerExponent field */ 1896/* defines for InactivityTimerExponent field */
1854#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000) 1897#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000)
1855#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12) 1898#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12)
@@ -1871,7 +1914,7 @@ typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
1871 1914
1872/* 1915/*
1873 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 1916 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1874 * one and check Header.ExtPageLength or NumPhys at runtime. 1917 * one and check the value returned for NumPhys at runtime.
1875 */ 1918 */
1876#ifndef MPI2_SAS_IOUNIT5_PHY_MAX 1919#ifndef MPI2_SAS_IOUNIT5_PHY_MAX
1877#define MPI2_SAS_IOUNIT5_PHY_MAX (1) 1920#define MPI2_SAS_IOUNIT5_PHY_MAX (1)
@@ -1889,7 +1932,132 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 {
1889 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5, 1932 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5,
1890 Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t; 1933 Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t;
1891 1934
1892#define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x00) 1935#define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x01)
1936
1937
1938/* SAS IO Unit Page 6 */
1939
1940typedef struct _MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS {
1941 U8 CurrentStatus; /* 0x00 */
1942 U8 CurrentModulation; /* 0x01 */
1943 U8 CurrentUtilization; /* 0x02 */
1944 U8 Reserved1; /* 0x03 */
1945 U32 Reserved2; /* 0x04 */
1946} MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS,
1947 MPI2_POINTER PTR_MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS,
1948 Mpi2SasIOUnit6PortWidthModGroupStatus_t,
1949 MPI2_POINTER pMpi2SasIOUnit6PortWidthModGroupStatus_t;
1950
1951/* defines for CurrentStatus field */
1952#define MPI2_SASIOUNIT6_STATUS_UNAVAILABLE (0x00)
1953#define MPI2_SASIOUNIT6_STATUS_UNCONFIGURED (0x01)
1954#define MPI2_SASIOUNIT6_STATUS_INVALID_CONFIG (0x02)
1955#define MPI2_SASIOUNIT6_STATUS_LINK_DOWN (0x03)
1956#define MPI2_SASIOUNIT6_STATUS_OBSERVATION_ONLY (0x04)
1957#define MPI2_SASIOUNIT6_STATUS_INACTIVE (0x05)
1958#define MPI2_SASIOUNIT6_STATUS_ACTIVE_IOUNIT (0x06)
1959#define MPI2_SASIOUNIT6_STATUS_ACTIVE_HOST (0x07)
1960
1961/* defines for CurrentModulation field */
1962#define MPI2_SASIOUNIT6_MODULATION_25_PERCENT (0x00)
1963#define MPI2_SASIOUNIT6_MODULATION_50_PERCENT (0x01)
1964#define MPI2_SASIOUNIT6_MODULATION_75_PERCENT (0x02)
1965#define MPI2_SASIOUNIT6_MODULATION_100_PERCENT (0x03)
1966
1967/*
1968 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1969 * one and check the value returned for NumGroups at runtime.
1970 */
1971#ifndef MPI2_SAS_IOUNIT6_GROUP_MAX
1972#define MPI2_SAS_IOUNIT6_GROUP_MAX (1)
1973#endif
1974
1975typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_6 {
1976 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1977 U32 Reserved1; /* 0x08 */
1978 U32 Reserved2; /* 0x0C */
1979 U8 NumGroups; /* 0x10 */
1980 U8 Reserved3; /* 0x11 */
1981 U16 Reserved4; /* 0x12 */
1982 MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS
1983 PortWidthModulationGroupStatus[MPI2_SAS_IOUNIT6_GROUP_MAX]; /* 0x14 */
1984} MPI2_CONFIG_PAGE_SASIOUNIT_6,
1985 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_6,
1986 Mpi2SasIOUnitPage6_t, MPI2_POINTER pMpi2SasIOUnitPage6_t;
1987
1988#define MPI2_SASIOUNITPAGE6_PAGEVERSION (0x00)
1989
1990
1991/* SAS IO Unit Page 7 */
1992
1993typedef struct _MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS {
1994 U8 Flags; /* 0x00 */
1995 U8 Reserved1; /* 0x01 */
1996 U16 Reserved2; /* 0x02 */
1997 U8 Threshold75Pct; /* 0x04 */
1998 U8 Threshold50Pct; /* 0x05 */
1999 U8 Threshold25Pct; /* 0x06 */
2000 U8 Reserved3; /* 0x07 */
2001} MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS,
2002 MPI2_POINTER PTR_MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS,
2003 Mpi2SasIOUnit7PortWidthModGroupSettings_t,
2004 MPI2_POINTER pMpi2SasIOUnit7PortWidthModGroupSettings_t;
2005
2006/* defines for Flags field */
2007#define MPI2_SASIOUNIT7_FLAGS_ENABLE_PORT_WIDTH_MODULATION (0x01)
2008
2009
2010/*
2011 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2012 * one and check the value returned for NumGroups at runtime.
2013 */
2014#ifndef MPI2_SAS_IOUNIT7_GROUP_MAX
2015#define MPI2_SAS_IOUNIT7_GROUP_MAX (1)
2016#endif
2017
2018typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_7 {
2019 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2020 U8 SamplingInterval; /* 0x08 */
2021 U8 WindowLength; /* 0x09 */
2022 U16 Reserved1; /* 0x0A */
2023 U32 Reserved2; /* 0x0C */
2024 U32 Reserved3; /* 0x10 */
2025 U8 NumGroups; /* 0x14 */
2026 U8 Reserved4; /* 0x15 */
2027 U16 Reserved5; /* 0x16 */
2028 MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS
2029 PortWidthModulationGroupSettings[MPI2_SAS_IOUNIT7_GROUP_MAX]; /* 0x18 */
2030} MPI2_CONFIG_PAGE_SASIOUNIT_7,
2031 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_7,
2032 Mpi2SasIOUnitPage7_t, MPI2_POINTER pMpi2SasIOUnitPage7_t;
2033
2034#define MPI2_SASIOUNITPAGE7_PAGEVERSION (0x00)
2035
2036
2037/* SAS IO Unit Page 8 */
2038
2039typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 {
2040 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2041 U32 Reserved1; /* 0x08 */
2042 U32 PowerManagementCapabilities;/* 0x0C */
2043 U32 Reserved2; /* 0x10 */
2044} MPI2_CONFIG_PAGE_SASIOUNIT_8,
2045 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_8,
2046 Mpi2SasIOUnitPage8_t, MPI2_POINTER pMpi2SasIOUnitPage8_t;
2047
2048#define MPI2_SASIOUNITPAGE8_PAGEVERSION (0x00)
2049
2050/* defines for PowerManagementCapabilities field */
2051#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD (0x000001000)
2052#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE (0x000000800)
2053#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE (0x000000400)
2054#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE (0x000000200)
2055#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE (0x000000100)
2056#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD (0x000000010)
2057#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE (0x000000008)
2058#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE (0x000000004)
2059#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE (0x000000002)
2060#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE (0x000000001)
1893 2061
1894 2062
1895 2063
@@ -2179,7 +2347,7 @@ typedef struct _MPI2_SASPHY2_PHY_EVENT {
2179 2347
2180/* 2348/*
2181 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 2349 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2182 * one and check Header.ExtPageLength or NumPhyEvents at runtime. 2350 * one and check the value returned for NumPhyEvents at runtime.
2183 */ 2351 */
2184#ifndef MPI2_SASPHY2_PHY_EVENT_MAX 2352#ifndef MPI2_SASPHY2_PHY_EVENT_MAX
2185#define MPI2_SASPHY2_PHY_EVENT_MAX (1) 2353#define MPI2_SASPHY2_PHY_EVENT_MAX (1)
@@ -2271,7 +2439,7 @@ typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG {
2271 2439
2272/* 2440/*
2273 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 2441 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2274 * one and check Header.ExtPageLength or NumPhyEvents at runtime. 2442 * one and check the value returned for NumPhyEvents at runtime.
2275 */ 2443 */
2276#ifndef MPI2_SASPHY3_PHY_EVENT_MAX 2444#ifndef MPI2_SASPHY3_PHY_EVENT_MAX
2277#define MPI2_SASPHY3_PHY_EVENT_MAX (1) 2445#define MPI2_SASPHY3_PHY_EVENT_MAX (1)
@@ -2291,6 +2459,26 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 {
2291#define MPI2_SASPHY3_PAGEVERSION (0x00) 2459#define MPI2_SASPHY3_PAGEVERSION (0x00)
2292 2460
2293 2461
2462/* SAS PHY Page 4 */
2463
2464typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_4 {
2465 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2466 U16 Reserved1; /* 0x08 */
2467 U8 Reserved2; /* 0x0A */
2468 U8 Flags; /* 0x0B */
2469 U8 InitialFrame[28]; /* 0x0C */
2470} MPI2_CONFIG_PAGE_SAS_PHY_4, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_4,
2471 Mpi2SasPhyPage4_t, MPI2_POINTER pMpi2SasPhyPage4_t;
2472
2473#define MPI2_SASPHY4_PAGEVERSION (0x00)
2474
2475/* values for the Flags field */
2476#define MPI2_SASPHY4_FLAGS_FRAME_VALID (0x02)
2477#define MPI2_SASPHY4_FLAGS_SATA_FRAME (0x01)
2478
2479
2480
2481
2294/**************************************************************************** 2482/****************************************************************************
2295* SAS Port Config Pages 2483* SAS Port Config Pages
2296****************************************************************************/ 2484****************************************************************************/
@@ -2362,7 +2550,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0
2362 2550
2363/* 2551/*
2364 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 2552 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2365 * one and check Header.ExtPageLength or NumPhys at runtime. 2553 * one and check the value returned for NumLogEntries at runtime.
2366 */ 2554 */
2367#ifndef MPI2_LOG_0_NUM_LOG_ENTRIES 2555#ifndef MPI2_LOG_0_NUM_LOG_ENTRIES
2368#define MPI2_LOG_0_NUM_LOG_ENTRIES (1) 2556#define MPI2_LOG_0_NUM_LOG_ENTRIES (1)
@@ -2412,7 +2600,7 @@ typedef struct _MPI2_CONFIG_PAGE_LOG_0
2412 2600
2413/* 2601/*
2414 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to 2602 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2415 * one and check Header.ExtPageLength or NumPhys at runtime. 2603 * one and check the value returned for NumElements at runtime.
2416 */ 2604 */
2417#ifndef MPI2_RAIDCONFIG0_MAX_ELEMENTS 2605#ifndef MPI2_RAIDCONFIG0_MAX_ELEMENTS
2418#define MPI2_RAIDCONFIG0_MAX_ELEMENTS (1) 2606#define MPI2_RAIDCONFIG0_MAX_ELEMENTS (1)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
index 65fcaa31cb3..b1e88f26b74 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
@@ -2,26 +2,27 @@
2 Fusion-MPT MPI 2.0 Header File Change History 2 Fusion-MPT MPI 2.0 Header File Change History
3 ============================== 3 ==============================
4 4
5 Copyright (c) 2000-2009 LSI Corporation. 5 Copyright (c) 2000-2010 LSI Corporation.
6 6
7 --------------------------------------- 7 ---------------------------------------
8 Header Set Release Version: 02.00.12 8 Header Set Release Version: 02.00.14
9 Header Set Release Date: 05-06-09 9 Header Set Release Date: 10-28-09
10 --------------------------------------- 10 ---------------------------------------
11 11
12 Filename Current version Prior version 12 Filename Current version Prior version
13 ---------- --------------- ------------- 13 ---------- --------------- -------------
14 mpi2.h 02.00.12 02.00.11 14 mpi2.h 02.00.14 02.00.13
15 mpi2_cnfg.h 02.00.11 02.00.10 15 mpi2_cnfg.h 02.00.13 02.00.12
16 mpi2_init.h 02.00.07 02.00.06 16 mpi2_init.h 02.00.08 02.00.07
17 mpi2_ioc.h 02.00.11 02.00.10 17 mpi2_ioc.h 02.00.13 02.00.12
18 mpi2_raid.h 02.00.03 02.00.03 18 mpi2_raid.h 02.00.04 02.00.04
19 mpi2_sas.h 02.00.02 02.00.02 19 mpi2_sas.h 02.00.03 02.00.02
20 mpi2_targ.h 02.00.03 02.00.03 20 mpi2_targ.h 02.00.03 02.00.03
21 mpi2_tool.h 02.00.03 02.00.02 21 mpi2_tool.h 02.00.04 02.00.04
22 mpi2_type.h 02.00.00 02.00.00 22 mpi2_type.h 02.00.00 02.00.00
23 mpi2_ra.h 02.00.00 23 mpi2_ra.h 02.00.00 02.00.00
24 mpi2_history.txt 02.00.11 02.00.12 24 mpi2_hbd.h 02.00.00
25 mpi2_history.txt 02.00.14 02.00.13
25 26
26 27
27 * Date Version Description 28 * Date Version Description
@@ -65,6 +66,11 @@ mpi2.h
65 * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those 66 * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
66 * bytes reserved. 67 * bytes reserved.
67 * Added RAID Accelerator functionality. 68 * Added RAID Accelerator functionality.
69 * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT.
70 * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT.
71 * Added MSI-x index mask and shift for Reply Post Host
72 * Index register.
73 * Added function code for Host Based Discovery Action.
68 * -------------------------------------------------------------------------- 74 * --------------------------------------------------------------------------
69 75
70mpi2_cnfg.h 76mpi2_cnfg.h
@@ -155,6 +161,15 @@ mpi2_cnfg.h
155 * Added expander reduced functionality data to SAS 161 * Added expander reduced functionality data to SAS
156 * Expander Page 0. 162 * Expander Page 0.
157 * Added SAS PHY Page 2 and SAS PHY Page 3. 163 * Added SAS PHY Page 2 and SAS PHY Page 3.
164 * 07-30-09 02.00.12 Added IO Unit Page 7.
165 * Added new device ids.
166 * Added SAS IO Unit Page 5.
167 * Added partial and slumber power management capable flags
168 * to SAS Device Page 0 Flags field.
169 * Added PhyInfo defines for power condition.
170 * Added Ethernet configuration pages.
171 * 10-28-09 02.00.13 Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY.
172 * Added SAS PHY Page 4 structure and defines.
158 * -------------------------------------------------------------------------- 173 * --------------------------------------------------------------------------
159 174
160mpi2_init.h 175mpi2_init.h
@@ -172,6 +187,10 @@ mpi2_init.h
172 * Query Asynchronous Event. 187 * Query Asynchronous Event.
173 * Defined two new bits in the SlotStatus field of the SCSI 188 * Defined two new bits in the SlotStatus field of the SCSI
174 * Enclosure Processor Request and Reply. 189 * Enclosure Processor Request and Reply.
190 * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for
191 * both SCSI IO Error Reply and SCSI Task Management Reply.
192 * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
193 * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
175 * -------------------------------------------------------------------------- 194 * --------------------------------------------------------------------------
176 195
177mpi2_ioc.h 196mpi2_ioc.h
@@ -246,6 +265,20 @@ mpi2_ioc.h
246 * Added two new reason codes for SAS Device Status Change 265 * Added two new reason codes for SAS Device Status Change
247 * Event. 266 * Event.
248 * Added new event: SAS PHY Counter. 267 * Added new event: SAS PHY Counter.
268 * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure.
269 * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
270 * Added new product id family for 2208.
271 * 10-28-09 02.00.13 Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST.
272 * Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY.
273 * Added MinDevHandle field to MPI2_IOC_FACTS_REPLY.
274 * Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY.
275 * Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define.
276 * Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define.
277 * Added Host Based Discovery Phy Event data.
278 * Added defines for ProductID Product field
279 * (MPI2_FW_HEADER_PID_).
280 * Modified values for SAS ProductID Family
281 * (MPI2_FW_HEADER_PID_FAMILY_).
249 * -------------------------------------------------------------------------- 282 * --------------------------------------------------------------------------
250 283
251mpi2_raid.h 284mpi2_raid.h
@@ -256,6 +289,9 @@ mpi2_raid.h
256 * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that 289 * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
257 * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT 290 * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
258 * can be sized by the build environment. 291 * can be sized by the build environment.
292 * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
293 * VolumeCreationFlags and marked the old one as obsolete.
294 * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
259 * -------------------------------------------------------------------------- 295 * --------------------------------------------------------------------------
260 296
261mpi2_sas.h 297mpi2_sas.h
@@ -264,6 +300,9 @@ mpi2_sas.h
264 * Control Request. 300 * Control Request.
265 * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control 301 * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control
266 * Request. 302 * Request.
303 * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
304 * to MPI2_SGE_IO_UNION since it supports chained SGLs.
305 * 05-12-10 02.00.04 Modified some comments.
267 * -------------------------------------------------------------------------- 306 * --------------------------------------------------------------------------
268 307
269mpi2_targ.h 308mpi2_targ.h
@@ -283,6 +322,11 @@ mpi2_tool.h
283 * structures and defines. 322 * structures and defines.
284 * 02-29-08 02.00.02 Modified various names to make them 32-character unique. 323 * 02-29-08 02.00.02 Modified various names to make them 32-character unique.
285 * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. 324 * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool.
325 * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request
326 * and reply messages.
327 * Added MPI2_DIAG_BUF_TYPE_EXTENDED.
328 * Incremented MPI2_DIAG_BUF_TYPE_COUNT.
329 * 05-12-10 02.00.05 Added Diagnostic Data Upload tool.
286 * -------------------------------------------------------------------------- 330 * --------------------------------------------------------------------------
287 331
288mpi2_type.h 332mpi2_type.h
@@ -293,20 +337,26 @@ mpi2_ra.h
293 * 05-06-09 02.00.00 Initial version. 337 * 05-06-09 02.00.00 Initial version.
294 * -------------------------------------------------------------------------- 338 * --------------------------------------------------------------------------
295 339
340mpi2_hbd.h
341 * 10-28-09 02.00.00 Initial version.
342 * --------------------------------------------------------------------------
343
344
296mpi2_history.txt Parts list history 345mpi2_history.txt Parts list history
297 346
298Filename 02.00.12 347Filename 02.00.14 02.00.13 02.00.12
299---------- -------- 348---------- -------- -------- --------
300mpi2.h 02.00.12 349mpi2.h 02.00.14 02.00.13 02.00.12
301mpi2_cnfg.h 02.00.11 350mpi2_cnfg.h 02.00.13 02.00.12 02.00.11
302mpi2_init.h 02.00.07 351mpi2_init.h 02.00.08 02.00.07 02.00.07
303mpi2_ioc.h 02.00.11 352mpi2_ioc.h 02.00.13 02.00.12 02.00.11
304mpi2_raid.h 02.00.03 353mpi2_raid.h 02.00.04 02.00.04 02.00.03
305mpi2_sas.h 02.00.02 354mpi2_sas.h 02.00.03 02.00.02 02.00.02
306mpi2_targ.h 02.00.03 355mpi2_targ.h 02.00.03 02.00.03 02.00.03
307mpi2_tool.h 02.00.03 356mpi2_tool.h 02.00.04 02.00.04 02.00.03
308mpi2_type.h 02.00.00 357mpi2_type.h 02.00.00 02.00.00 02.00.00
309mpi2_ra.h 02.00.00 358mpi2_ra.h 02.00.00 02.00.00 02.00.00
359mpi2_hbd.h 02.00.00
310 360
311Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 361Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06
312---------- -------- -------- -------- -------- -------- -------- 362---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
index 563e56d2e94..20e6b886934 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_init.h 5 * Name: mpi2_init.h
6 * Title: MPI SCSI initiator mode messages and structures 6 * Title: MPI SCSI initiator mode messages and structures
7 * Creation Date: June 23, 2006 7 * Creation Date: June 23, 2006
8 * 8 *
9 * mpi2_init.h Version: 02.00.07 9 * mpi2_init.h Version: 02.00.10
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -27,6 +27,12 @@
27 * Query Asynchronous Event. 27 * Query Asynchronous Event.
28 * Defined two new bits in the SlotStatus field of the SCSI 28 * Defined two new bits in the SlotStatus field of the SCSI
29 * Enclosure Processor Request and Reply. 29 * Enclosure Processor Request and Reply.
30 * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for
31 * both SCSI IO Error Reply and SCSI Task Management Reply.
32 * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
33 * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
34 * 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it.
35 * 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request.
30 * -------------------------------------------------------------------------- 36 * --------------------------------------------------------------------------
31 */ 37 */
32 38
@@ -53,20 +59,6 @@ typedef struct
53} MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32, 59} MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32,
54 Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t; 60 Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t;
55 61
56/* TBD: I don't think this is needed for MPI2/Gen2 */
57#if 0
58typedef struct
59{
60 U8 CDB[16]; /* 0x00 */
61 U32 DataLength; /* 0x10 */
62 U32 PrimaryReferenceTag; /* 0x14 */
63 U16 PrimaryApplicationTag; /* 0x18 */
64 U16 PrimaryApplicationTagMask; /* 0x1A */
65 U32 TransferLength; /* 0x1C */
66} MPI2_SCSI_IO32_CDB_EEDP16, MPI2_POINTER PTR_MPI2_SCSI_IO32_CDB_EEDP16,
67 Mpi2ScsiIo32CdbEedp16_t, MPI2_POINTER pMpi2ScsiIo32CdbEedp16_t;
68#endif
69
70typedef union 62typedef union
71{ 63{
72 U8 CDB32[32]; 64 U8 CDB32[32];
@@ -107,7 +99,13 @@ typedef struct _MPI2_SCSI_IO_REQUEST
107 U8 LUN[8]; /* 0x34 */ 99 U8 LUN[8]; /* 0x34 */
108 U32 Control; /* 0x3C */ 100 U32 Control; /* 0x3C */
109 MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */ 101 MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
102
103#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /* typically this is left undefined */
104 MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion;
105#endif
106
110 MPI2_SGE_IO_UNION SGL; /* 0x60 */ 107 MPI2_SGE_IO_UNION SGL; /* 0x60 */
108
111} MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST, 109} MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST,
112 Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t; 110 Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t;
113 111
@@ -254,6 +252,11 @@ typedef struct _MPI2_SCSI_IO_REPLY
254#define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02) 252#define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02)
255#define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01) 253#define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01)
256 254
255/* masks and shifts for the ResponseInfo field */
256
257#define MPI2_SCSI_RI_MASK_REASONCODE (0x000000FF)
258#define MPI2_SCSI_RI_SHIFT_REASONCODE (0)
259
257#define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF) 260#define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF)
258 261
259 262
@@ -327,6 +330,7 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY
327 U16 IOCStatus; /* 0x0E */ 330 U16 IOCStatus; /* 0x0E */
328 U32 IOCLogInfo; /* 0x10 */ 331 U32 IOCLogInfo; /* 0x10 */
329 U32 TerminationCount; /* 0x14 */ 332 U32 TerminationCount; /* 0x14 */
333 U32 ResponseInfo; /* 0x18 */
330} MPI2_SCSI_TASK_MANAGE_REPLY, 334} MPI2_SCSI_TASK_MANAGE_REPLY,
331 MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY, 335 MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY,
332 Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t; 336 Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t;
@@ -339,8 +343,20 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY
339#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05) 343#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05)
340#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08) 344#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08)
341#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09) 345#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09)
346#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A)
342#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80) 347#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80)
343 348
349/* masks and shifts for the ResponseInfo field */
350
351#define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE (0x000000FF)
352#define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE (0)
353#define MPI2_SCSITASKMGMT_RI_MASK_ARI2 (0x0000FF00)
354#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2 (8)
355#define MPI2_SCSITASKMGMT_RI_MASK_ARI1 (0x00FF0000)
356#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1 (16)
357#define MPI2_SCSITASKMGMT_RI_MASK_ARI0 (0xFF000000)
358#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0 (24)
359
344 360
345/**************************************************************************** 361/****************************************************************************
346* SCSI Enclosure Processor messages 362* SCSI Enclosure Processor messages
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index ea51ce86869..761cbdb8a03 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_ioc.h 5 * Name: mpi2_ioc.h
6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages 6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
7 * Creation Date: October 11, 2006 7 * Creation Date: October 11, 2006
8 * 8 *
9 * mpi2_ioc.h Version: 02.00.12 9 * mpi2_ioc.h Version: 02.00.15
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -87,6 +87,22 @@
87 * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure. 87 * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure.
88 * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. 88 * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
89 * Added new product id family for 2208. 89 * Added new product id family for 2208.
90 * 10-28-09 02.00.13 Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST.
91 * Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY.
92 * Added MinDevHandle field to MPI2_IOC_FACTS_REPLY.
93 * Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY.
94 * Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define.
95 * Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define.
96 * Added Host Based Discovery Phy Event data.
97 * Added defines for ProductID Product field
98 * (MPI2_FW_HEADER_PID_).
99 * Modified values for SAS ProductID Family
100 * (MPI2_FW_HEADER_PID_FAMILY_).
101 * 02-10-10 02.00.14 Added SAS Quiesce Event structure and defines.
102 * Added PowerManagementControl Request structures and
103 * defines.
104 * 05-12-10 02.00.15 Marked Task Set Full Event as obsolete.
105 * Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define.
90 * -------------------------------------------------------------------------- 106 * --------------------------------------------------------------------------
91 */ 107 */
92 108
@@ -119,8 +135,10 @@ typedef struct _MPI2_IOC_INIT_REQUEST
119 U16 MsgVersion; /* 0x0C */ 135 U16 MsgVersion; /* 0x0C */
120 U16 HeaderVersion; /* 0x0E */ 136 U16 HeaderVersion; /* 0x0E */
121 U32 Reserved5; /* 0x10 */ 137 U32 Reserved5; /* 0x10 */
122 U32 Reserved6; /* 0x14 */ 138 U16 Reserved6; /* 0x14 */
123 U16 Reserved7; /* 0x18 */ 139 U8 Reserved7; /* 0x16 */
140 U8 HostMSIxVectors; /* 0x17 */
141 U16 Reserved8; /* 0x18 */
124 U16 SystemRequestFrameSize; /* 0x1A */ 142 U16 SystemRequestFrameSize; /* 0x1A */
125 U16 ReplyDescriptorPostQueueDepth; /* 0x1C */ 143 U16 ReplyDescriptorPostQueueDepth; /* 0x1C */
126 U16 ReplyFreeQueueDepth; /* 0x1E */ 144 U16 ReplyFreeQueueDepth; /* 0x1E */
@@ -215,7 +233,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
215 U8 MaxChainDepth; /* 0x14 */ 233 U8 MaxChainDepth; /* 0x14 */
216 U8 WhoInit; /* 0x15 */ 234 U8 WhoInit; /* 0x15 */
217 U8 NumberOfPorts; /* 0x16 */ 235 U8 NumberOfPorts; /* 0x16 */
218 U8 Reserved2; /* 0x17 */ 236 U8 MaxMSIxVectors; /* 0x17 */
219 U16 RequestCredit; /* 0x18 */ 237 U16 RequestCredit; /* 0x18 */
220 U16 ProductID; /* 0x1A */ 238 U16 ProductID; /* 0x1A */
221 U32 IOCCapabilities; /* 0x1C */ 239 U32 IOCCapabilities; /* 0x1C */
@@ -233,7 +251,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY
233 U8 MaxVolumes; /* 0x37 */ 251 U8 MaxVolumes; /* 0x37 */
234 U16 MaxDevHandle; /* 0x38 */ 252 U16 MaxDevHandle; /* 0x38 */
235 U16 MaxPersistentEntries; /* 0x3A */ 253 U16 MaxPersistentEntries; /* 0x3A */
236 U32 Reserved4; /* 0x3C */ 254 U16 MinDevHandle; /* 0x3C */
255 U16 Reserved4; /* 0x3E */
237} MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY, 256} MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY,
238 Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t; 257 Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t;
239 258
@@ -269,6 +288,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
269/* ProductID field uses MPI2_FW_HEADER_PID_ */ 288/* ProductID field uses MPI2_FW_HEADER_PID_ */
270 289
271/* IOCCapabilities */ 290/* IOCCapabilities */
291#define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY (0x00010000)
272#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) 292#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000)
273#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) 293#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000)
274#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) 294#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000)
@@ -438,7 +458,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
438#define MPI2_EVENT_STATE_CHANGE (0x0002) 458#define MPI2_EVENT_STATE_CHANGE (0x0002)
439#define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005) 459#define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005)
440#define MPI2_EVENT_EVENT_CHANGE (0x000A) 460#define MPI2_EVENT_EVENT_CHANGE (0x000A)
441#define MPI2_EVENT_TASK_SET_FULL (0x000E) 461#define MPI2_EVENT_TASK_SET_FULL (0x000E) /* obsolete */
442#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F) 462#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F)
443#define MPI2_EVENT_IR_OPERATION_STATUS (0x0014) 463#define MPI2_EVENT_IR_OPERATION_STATUS (0x0014)
444#define MPI2_EVENT_SAS_DISCOVERY (0x0016) 464#define MPI2_EVENT_SAS_DISCOVERY (0x0016)
@@ -453,6 +473,8 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
453#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) 473#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021)
454#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) 474#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022)
455#define MPI2_EVENT_GPIO_INTERRUPT (0x0023) 475#define MPI2_EVENT_GPIO_INTERRUPT (0x0023)
476#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY (0x0024)
477#define MPI2_EVENT_SAS_QUIESCE (0x0025)
456 478
457 479
458/* Log Entry Added Event data */ 480/* Log Entry Added Event data */
@@ -497,6 +519,7 @@ typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
497 MPI2_POINTER pMpi2EventDataHardResetReceived_t; 519 MPI2_POINTER pMpi2EventDataHardResetReceived_t;
498 520
499/* Task Set Full Event data */ 521/* Task Set Full Event data */
522/* this event is obsolete */
500 523
501typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL 524typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL
502{ 525{
@@ -793,6 +816,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
793 MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t; 816 MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t;
794 817
795/* values for the ExpStatus field */ 818/* values for the ExpStatus field */
819#define MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER (0x00)
796#define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01) 820#define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01)
797#define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02) 821#define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02)
798#define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03) 822#define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03)
@@ -810,6 +834,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
810#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03) 834#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03)
811#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04) 835#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04)
812#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS (0x05) 836#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS (0x05)
837#define MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY (0x06)
813#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08) 838#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08)
814#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09) 839#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09)
815#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A) 840#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A)
@@ -878,6 +903,60 @@ typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER {
878 * */ 903 * */
879 904
880 905
906/* SAS Quiesce Event data */
907
908typedef struct _MPI2_EVENT_DATA_SAS_QUIESCE {
909 U8 ReasonCode; /* 0x00 */
910 U8 Reserved1; /* 0x01 */
911 U16 Reserved2; /* 0x02 */
912 U32 Reserved3; /* 0x04 */
913} MPI2_EVENT_DATA_SAS_QUIESCE,
914 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_QUIESCE,
915 Mpi2EventDataSasQuiesce_t, MPI2_POINTER pMpi2EventDataSasQuiesce_t;
916
917/* SAS Quiesce Event data ReasonCode values */
918#define MPI2_EVENT_SAS_QUIESCE_RC_STARTED (0x01)
919#define MPI2_EVENT_SAS_QUIESCE_RC_COMPLETED (0x02)
920
921
922/* Host Based Discovery Phy Event data */
923
924typedef struct _MPI2_EVENT_HBD_PHY_SAS {
925 U8 Flags; /* 0x00 */
926 U8 NegotiatedLinkRate; /* 0x01 */
927 U8 PhyNum; /* 0x02 */
928 U8 PhysicalPort; /* 0x03 */
929 U32 Reserved1; /* 0x04 */
930 U8 InitialFrame[28]; /* 0x08 */
931} MPI2_EVENT_HBD_PHY_SAS, MPI2_POINTER PTR_MPI2_EVENT_HBD_PHY_SAS,
932 Mpi2EventHbdPhySas_t, MPI2_POINTER pMpi2EventHbdPhySas_t;
933
934/* values for the Flags field */
935#define MPI2_EVENT_HBD_SAS_FLAGS_FRAME_VALID (0x02)
936#define MPI2_EVENT_HBD_SAS_FLAGS_SATA_FRAME (0x01)
937
938/* use MPI2_SAS_NEG_LINK_RATE_ defines from mpi2_cnfg.h for
939 * the NegotiatedLinkRate field */
940
941typedef union _MPI2_EVENT_HBD_DESCRIPTOR {
942 MPI2_EVENT_HBD_PHY_SAS Sas;
943} MPI2_EVENT_HBD_DESCRIPTOR, MPI2_POINTER PTR_MPI2_EVENT_HBD_DESCRIPTOR,
944 Mpi2EventHbdDescriptor_t, MPI2_POINTER pMpi2EventHbdDescriptor_t;
945
946typedef struct _MPI2_EVENT_DATA_HBD_PHY {
947 U8 DescriptorType; /* 0x00 */
948 U8 Reserved1; /* 0x01 */
949 U16 Reserved2; /* 0x02 */
950 U32 Reserved3; /* 0x04 */
951 MPI2_EVENT_HBD_DESCRIPTOR Descriptor; /* 0x08 */
952} MPI2_EVENT_DATA_HBD_PHY, MPI2_POINTER PTR_MPI2_EVENT_DATA_HBD_PHY,
953 Mpi2EventDataHbdPhy_t, MPI2_POINTER pMpi2EventDataMpi2EventDataHbdPhy_t;
954
955/* values for the DescriptorType field */
956#define MPI2_EVENT_HBD_DT_SAS (0x01)
957
958
959
881/**************************************************************************** 960/****************************************************************************
882* EventAck message 961* EventAck message
883****************************************************************************/ 962****************************************************************************/
@@ -951,6 +1030,7 @@ typedef struct _MPI2_FW_DOWNLOAD_REQUEST
951#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07) 1030#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07)
952#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08) 1031#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08)
953#define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID (0x09) 1032#define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID (0x09)
1033#define MPI2_FW_DOWNLOAD_ITYPE_COMPLETE (0x0A)
954#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B) 1034#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
955 1035
956/* FWDownload TransactionContext Element */ 1036/* FWDownload TransactionContext Element */
@@ -1126,13 +1206,16 @@ typedef struct _MPI2_FW_IMAGE_HEADER
1126#define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000) 1206#define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000)
1127#define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000) 1207#define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000)
1128 1208
1129#define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00) 1209#define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00)
1130#define MPI2_FW_HEADER_PID_PROD_A (0x0000) 1210#define MPI2_FW_HEADER_PID_PROD_A (0x0000)
1211#define MPI2_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200)
1212#define MPI2_FW_HEADER_PID_PROD_IR_SCSI (0x0700)
1213
1131 1214
1132#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) 1215#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF)
1133/* SAS */ 1216/* SAS */
1134#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0010) 1217#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0013)
1135#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0011) 1218#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0014)
1136 1219
1137/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */ 1220/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
1138 1221
@@ -1348,5 +1431,100 @@ typedef struct _MPI2_INIT_IMAGE_FOOTER
1348#define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET (0x14) 1431#define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET (0x14)
1349 1432
1350 1433
1434/****************************************************************************
1435* PowerManagementControl message
1436****************************************************************************/
1437
1438/* PowerManagementControl Request message */
1439typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST {
1440 U8 Feature; /* 0x00 */
1441 U8 Reserved1; /* 0x01 */
1442 U8 ChainOffset; /* 0x02 */
1443 U8 Function; /* 0x03 */
1444 U16 Reserved2; /* 0x04 */
1445 U8 Reserved3; /* 0x06 */
1446 U8 MsgFlags; /* 0x07 */
1447 U8 VP_ID; /* 0x08 */
1448 U8 VF_ID; /* 0x09 */
1449 U16 Reserved4; /* 0x0A */
1450 U8 Parameter1; /* 0x0C */
1451 U8 Parameter2; /* 0x0D */
1452 U8 Parameter3; /* 0x0E */
1453 U8 Parameter4; /* 0x0F */
1454 U32 Reserved5; /* 0x10 */
1455 U32 Reserved6; /* 0x14 */
1456} MPI2_PWR_MGMT_CONTROL_REQUEST, MPI2_POINTER PTR_MPI2_PWR_MGMT_CONTROL_REQUEST,
1457 Mpi2PwrMgmtControlRequest_t, MPI2_POINTER pMpi2PwrMgmtControlRequest_t;
1458
1459/* defines for the Feature field */
1460#define MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND (0x01)
1461#define MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION (0x02)
1462#define MPI2_PM_CONTROL_FEATURE_PCIE_LINK (0x03)
1463#define MPI2_PM_CONTROL_FEATURE_IOC_SPEED (0x04)
1464#define MPI2_PM_CONTROL_FEATURE_MIN_PRODUCT_SPECIFIC (0x80)
1465#define MPI2_PM_CONTROL_FEATURE_MAX_PRODUCT_SPECIFIC (0xFF)
1466
1467/* parameter usage for the MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND Feature */
1468/* Parameter1 contains a PHY number */
1469/* Parameter2 indicates power condition action using these defines */
1470#define MPI2_PM_CONTROL_PARAM2_PARTIAL (0x01)
1471#define MPI2_PM_CONTROL_PARAM2_SLUMBER (0x02)
1472#define MPI2_PM_CONTROL_PARAM2_EXIT_PWR_MGMT (0x03)
1473/* Parameter3 and Parameter4 are reserved */
1474
1475/* parameter usage for the MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION
1476 * Feature */
1477/* Parameter1 contains SAS port width modulation group number */
1478/* Parameter2 indicates IOC action using these defines */
1479#define MPI2_PM_CONTROL_PARAM2_REQUEST_OWNERSHIP (0x01)
1480#define MPI2_PM_CONTROL_PARAM2_CHANGE_MODULATION (0x02)
1481#define MPI2_PM_CONTROL_PARAM2_RELINQUISH_OWNERSHIP (0x03)
1482/* Parameter3 indicates desired modulation level using these defines */
1483#define MPI2_PM_CONTROL_PARAM3_25_PERCENT (0x00)
1484#define MPI2_PM_CONTROL_PARAM3_50_PERCENT (0x01)
1485#define MPI2_PM_CONTROL_PARAM3_75_PERCENT (0x02)
1486#define MPI2_PM_CONTROL_PARAM3_100_PERCENT (0x03)
1487/* Parameter4 is reserved */
1488
1489/* parameter usage for the MPI2_PM_CONTROL_FEATURE_PCIE_LINK Feature */
1490/* Parameter1 indicates desired PCIe link speed using these defines */
1491#define MPI2_PM_CONTROL_PARAM1_PCIE_2_5_GBPS (0x00)
1492#define MPI2_PM_CONTROL_PARAM1_PCIE_5_0_GBPS (0x01)
1493#define MPI2_PM_CONTROL_PARAM1_PCIE_8_0_GBPS (0x02)
1494/* Parameter2 indicates desired PCIe link width using these defines */
1495#define MPI2_PM_CONTROL_PARAM2_WIDTH_X1 (0x01)
1496#define MPI2_PM_CONTROL_PARAM2_WIDTH_X2 (0x02)
1497#define MPI2_PM_CONTROL_PARAM2_WIDTH_X4 (0x04)
1498#define MPI2_PM_CONTROL_PARAM2_WIDTH_X8 (0x08)
1499/* Parameter3 and Parameter4 are reserved */
1500
1501/* parameter usage for the MPI2_PM_CONTROL_FEATURE_IOC_SPEED Feature */
1502/* Parameter1 indicates desired IOC hardware clock speed using these defines */
1503#define MPI2_PM_CONTROL_PARAM1_FULL_IOC_SPEED (0x01)
1504#define MPI2_PM_CONTROL_PARAM1_HALF_IOC_SPEED (0x02)
1505#define MPI2_PM_CONTROL_PARAM1_QUARTER_IOC_SPEED (0x04)
1506#define MPI2_PM_CONTROL_PARAM1_EIGHTH_IOC_SPEED (0x08)
1507/* Parameter2, Parameter3, and Parameter4 are reserved */
1508
1509
1510/* PowerManagementControl Reply message */
1511typedef struct _MPI2_PWR_MGMT_CONTROL_REPLY {
1512 U8 Feature; /* 0x00 */
1513 U8 Reserved1; /* 0x01 */
1514 U8 MsgLength; /* 0x02 */
1515 U8 Function; /* 0x03 */
1516 U16 Reserved2; /* 0x04 */
1517 U8 Reserved3; /* 0x06 */
1518 U8 MsgFlags; /* 0x07 */
1519 U8 VP_ID; /* 0x08 */
1520 U8 VF_ID; /* 0x09 */
1521 U16 Reserved4; /* 0x0A */
1522 U16 Reserved5; /* 0x0C */
1523 U16 IOCStatus; /* 0x0E */
1524 U32 IOCLogInfo; /* 0x10 */
1525} MPI2_PWR_MGMT_CONTROL_REPLY, MPI2_POINTER PTR_MPI2_PWR_MGMT_CONTROL_REPLY,
1526 Mpi2PwrMgmtControlReply_t, MPI2_POINTER pMpi2PwrMgmtControlReply_t;
1527
1528
1351#endif 1529#endif
1352 1530
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
index 5160c33d2a0..bd61a7b60a2 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2008 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_raid.h 5 * Name: mpi2_raid.h
6 * Title: MPI Integrated RAID messages and structures 6 * Title: MPI Integrated RAID messages and structures
7 * Creation Date: April 26, 2007 7 * Creation Date: April 26, 2007
8 * 8 *
9 * mpi2_raid.h Version: 02.00.04 9 * mpi2_raid.h Version: 02.00.05
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -22,6 +22,7 @@
22 * can be sized by the build environment. 22 * can be sized by the build environment.
23 * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of 23 * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
24 * VolumeCreationFlags and marked the old one as obsolete. 24 * VolumeCreationFlags and marked the old one as obsolete.
25 * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
25 * -------------------------------------------------------------------------- 26 * --------------------------------------------------------------------------
26 */ 27 */
27 28
@@ -260,6 +261,7 @@ typedef struct _MPI2_RAID_VOL_INDICATOR
260#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) 261#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
261#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002) 262#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002)
262#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003) 263#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003)
264#define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004)
263 265
264 266
265/* RAID Action Reply ActionData union */ 267/* RAID Action Reply ActionData union */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
index 8a42b136cf5..608f6d6e6fc 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2007 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_sas.h 5 * Name: mpi2_sas.h
6 * Title: MPI Serial Attached SCSI structures and definitions 6 * Title: MPI Serial Attached SCSI structures and definitions
7 * Creation Date: February 9, 2007 7 * Creation Date: February 9, 2007
8 * 8 *
9 * mpi2.h Version: 02.00.02 9 * mpi2_sas.h Version: 02.00.04
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -18,6 +18,9 @@
18 * Control Request. 18 * Control Request.
19 * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control 19 * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control
20 * Request. 20 * Request.
21 * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
22 * to MPI2_SGE_IO_UNION since it supports chained SGLs.
23 * 05-12-10 02.00.04 Modified some comments.
21 * -------------------------------------------------------------------------- 24 * --------------------------------------------------------------------------
22 */ 25 */
23 26
@@ -108,7 +111,7 @@ typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST
108/* values for PassthroughFlags field */ 111/* values for PassthroughFlags field */
109#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) 112#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
110 113
111/* values for SGLFlags field are in the SGL section of mpi2.h */ 114/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
112 115
113 116
114/* SMP Passthrough Reply Message */ 117/* SMP Passthrough Reply Message */
@@ -160,7 +163,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
160 U32 Reserved4; /* 0x14 */ 163 U32 Reserved4; /* 0x14 */
161 U32 DataLength; /* 0x18 */ 164 U32 DataLength; /* 0x18 */
162 U8 CommandFIS[20]; /* 0x1C */ 165 U8 CommandFIS[20]; /* 0x1C */
163 MPI2_SIMPLE_SGE_UNION SGL; /* 0x20 */ 166 MPI2_SGE_IO_UNION SGL; /* 0x20 */
164} MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST, 167} MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST,
165 Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t; 168 Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t;
166 169
@@ -172,7 +175,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
172#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002) 175#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002)
173#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001) 176#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001)
174 177
175/* values for SGLFlags field are in the SGL section of mpi2.h */ 178/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
176 179
177 180
178/* SATA Passthrough Reply Message */ 181/* SATA Passthrough Reply Message */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
index 73fcdbf9263..5c6e3a67bb9 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2009 LSI Corporation. 2 * Copyright (c) 2000-2010 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_tool.h 5 * Name: mpi2_tool.h
6 * Title: MPI diagnostic tool structures and definitions 6 * Title: MPI diagnostic tool structures and definitions
7 * Creation Date: March 26, 2007 7 * Creation Date: March 26, 2007
8 * 8 *
9 * mpi2_tool.h Version: 02.00.04 9 * mpi2_tool.h Version: 02.00.05
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -22,6 +22,7 @@
22 * and reply messages. 22 * and reply messages.
23 * Added MPI2_DIAG_BUF_TYPE_EXTENDED. 23 * Added MPI2_DIAG_BUF_TYPE_EXTENDED.
24 * Incremented MPI2_DIAG_BUF_TYPE_COUNT. 24 * Incremented MPI2_DIAG_BUF_TYPE_COUNT.
25 * 05-12-10 02.00.05 Added Diagnostic Data Upload tool.
25 * -------------------------------------------------------------------------- 26 * --------------------------------------------------------------------------
26 */ 27 */
27 28
@@ -37,6 +38,7 @@
37/* defines for the Tools */ 38/* defines for the Tools */
38#define MPI2_TOOLBOX_CLEAN_TOOL (0x00) 39#define MPI2_TOOLBOX_CLEAN_TOOL (0x00)
39#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) 40#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01)
41#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02)
40#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) 42#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03)
41#define MPI2_TOOLBOX_BEACON_TOOL (0x05) 43#define MPI2_TOOLBOX_BEACON_TOOL (0x05)
42#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) 44#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06)
@@ -102,8 +104,7 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
102* Toolbox Memory Move request 104* Toolbox Memory Move request
103****************************************************************************/ 105****************************************************************************/
104 106
105typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST 107typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST {
106{
107 U8 Tool; /* 0x00 */ 108 U8 Tool; /* 0x00 */
108 U8 Reserved1; /* 0x01 */ 109 U8 Reserved1; /* 0x01 */
109 U8 ChainOffset; /* 0x02 */ 110 U8 ChainOffset; /* 0x02 */
@@ -120,6 +121,44 @@ typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
120 121
121 122
122/**************************************************************************** 123/****************************************************************************
124* Toolbox Diagnostic Data Upload request
125****************************************************************************/
126
127typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST {
128 U8 Tool; /* 0x00 */
129 U8 Reserved1; /* 0x01 */
130 U8 ChainOffset; /* 0x02 */
131 U8 Function; /* 0x03 */
132 U16 Reserved2; /* 0x04 */
133 U8 Reserved3; /* 0x06 */
134 U8 MsgFlags; /* 0x07 */
135 U8 VP_ID; /* 0x08 */
136 U8 VF_ID; /* 0x09 */
137 U16 Reserved4; /* 0x0A */
138 U8 SGLFlags; /* 0x0C */
139 U8 Reserved5; /* 0x0D */
140 U16 Reserved6; /* 0x0E */
141 U32 Flags; /* 0x10 */
142 U32 DataLength; /* 0x14 */
143 MPI2_SGE_SIMPLE_UNION SGL; /* 0x18 */
144} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
145MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
146Mpi2ToolboxDiagDataUploadRequest_t,
147MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t;
148
149/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
150
151
152typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER {
153 U32 DiagDataLength; /* 00h */
154 U8 FormatCode; /* 04h */
155 U8 Reserved1; /* 05h */
156 U16 Reserved2; /* 06h */
157} MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER,
158Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t;
159
160
161/****************************************************************************
123* Toolbox ISTWI Read Write Tool 162* Toolbox ISTWI Read Write Tool
124****************************************************************************/ 163****************************************************************************/
125 164
@@ -162,7 +201,7 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
162#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) 201#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11)
163#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) 202#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12)
164 203
165/* values for SGLFlags field are in the SGL section of mpi2.h */ 204/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
166 205
167 206
168/* Toolbox ISTWI Read Write Tool reply message */ 207/* Toolbox ISTWI Read Write Tool reply message */
@@ -248,7 +287,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
248 Mpi2ToolboxDiagnosticCliRequest_t, 287 Mpi2ToolboxDiagnosticCliRequest_t,
249 MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t; 288 MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t;
250 289
251/* values for SGLFlags field are in the SGL section of mpi2.h */ 290/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
252 291
253 292
254/* Toolbox Diagnostic CLI Tool reply message */ 293/* Toolbox Diagnostic CLI Tool reply message */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 89d02401b9e..b2a817055b8 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -58,13 +58,13 @@
58#include <linux/sort.h> 58#include <linux/sort.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/time.h> 60#include <linux/time.h>
61#include <linux/aer.h>
61 62
62#include "mpt2sas_base.h" 63#include "mpt2sas_base.h"
63 64
64static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; 65static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
65 66
66#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ 67#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
67#define MPT2SAS_MAX_REQUEST_QUEUE 600 /* maximum controller queue depth */
68 68
69static int max_queue_depth = -1; 69static int max_queue_depth = -1;
70module_param(max_queue_depth, int, 0); 70module_param(max_queue_depth, int, 0);
@@ -78,6 +78,10 @@ static int msix_disable = -1;
78module_param(msix_disable, int, 0); 78module_param(msix_disable, int, 0);
79MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); 79MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
80 80
81static int missing_delay[2] = {-1, -1};
82module_param_array(missing_delay, int, NULL, 0);
83MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
84
81/* diag_buffer_enable is bitwise 85/* diag_buffer_enable is bitwise
82 * bit 0 set = TRACE 86 * bit 0 set = TRACE
83 * bit 1 set = SNAPSHOT 87 * bit 1 set = SNAPSHOT
@@ -94,6 +98,10 @@ int mpt2sas_fwfault_debug;
94MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " 98MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
95 "and halt firmware - (default=0)"); 99 "and halt firmware - (default=0)");
96 100
101static int disable_discovery = -1;
102module_param(disable_discovery, int, 0);
103MODULE_PARM_DESC(disable_discovery, " disable discovery ");
104
97/** 105/**
98 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. 106 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
99 * 107 *
@@ -107,8 +115,7 @@ _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
107 if (ret) 115 if (ret)
108 return ret; 116 return ret;
109 117
110 printk(KERN_INFO "setting logging_level(0x%08x)\n", 118 printk(KERN_INFO "setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug);
111 mpt2sas_fwfault_debug);
112 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) 119 list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
113 ioc->fwfault_debug = mpt2sas_fwfault_debug; 120 ioc->fwfault_debug = mpt2sas_fwfault_debug;
114 return 0; 121 return 0;
@@ -286,6 +293,9 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
286 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION) 293 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION)
287 return; 294 return;
288 295
296 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
297 return;
298
289 switch (ioc_status) { 299 switch (ioc_status) {
290 300
291/**************************************************************************** 301/****************************************************************************
@@ -508,9 +518,6 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
508 case MPI2_EVENT_EVENT_CHANGE: 518 case MPI2_EVENT_EVENT_CHANGE:
509 desc = "Event Change"; 519 desc = "Event Change";
510 break; 520 break;
511 case MPI2_EVENT_TASK_SET_FULL:
512 desc = "Task Set Full";
513 break;
514 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 521 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
515 desc = "Device Status Change"; 522 desc = "Device Status Change";
516 break; 523 break;
@@ -518,8 +525,18 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
518 desc = "IR Operation Status"; 525 desc = "IR Operation Status";
519 break; 526 break;
520 case MPI2_EVENT_SAS_DISCOVERY: 527 case MPI2_EVENT_SAS_DISCOVERY:
521 desc = "Discovery"; 528 {
522 break; 529 Mpi2EventDataSasDiscovery_t *event_data =
530 (Mpi2EventDataSasDiscovery_t *)mpi_reply->EventData;
531 printk(MPT2SAS_INFO_FMT "Discovery: (%s)", ioc->name,
532 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
533 "start" : "stop");
534 if (event_data->DiscoveryStatus)
535 printk("discovery_status(0x%08x)",
536 le32_to_cpu(event_data->DiscoveryStatus));
537 printk("\n");
538 return;
539 }
523 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 540 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
524 desc = "SAS Broadcast Primitive"; 541 desc = "SAS Broadcast Primitive";
525 break; 542 break;
@@ -741,7 +758,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid)
741 if (smid < ioc->internal_smid) { 758 if (smid < ioc->internal_smid) {
742 i = smid - ioc->hi_priority_smid; 759 i = smid - ioc->hi_priority_smid;
743 cb_idx = ioc->hpr_lookup[i].cb_idx; 760 cb_idx = ioc->hpr_lookup[i].cb_idx;
744 } else { 761 } else if (smid <= ioc->hba_queue_depth) {
745 i = smid - ioc->internal_smid; 762 i = smid - ioc->internal_smid;
746 cb_idx = ioc->internal_lookup[i].cb_idx; 763 cb_idx = ioc->internal_lookup[i].cb_idx;
747 } 764 }
@@ -831,6 +848,7 @@ _base_interrupt(int irq, void *bus_id)
831 return IRQ_NONE; 848 return IRQ_NONE;
832 849
833 completed_cmds = 0; 850 completed_cmds = 0;
851 cb_idx = 0xFF;
834 do { 852 do {
835 rd.word = rpf->Words; 853 rd.word = rpf->Words;
836 if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) 854 if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
@@ -843,6 +861,9 @@ _base_interrupt(int irq, void *bus_id)
843 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 861 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
844 reply = le32_to_cpu 862 reply = le32_to_cpu
845 (rpf->AddressReply.ReplyFrameAddress); 863 (rpf->AddressReply.ReplyFrameAddress);
864 if (reply > ioc->reply_dma_max_address ||
865 reply < ioc->reply_dma_min_address)
866 reply = 0;
846 } else if (request_desript_type == 867 } else if (request_desript_type ==
847 MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER) 868 MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER)
848 goto next; 869 goto next;
@@ -1222,8 +1243,10 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1222 u32 memap_sz; 1243 u32 memap_sz;
1223 u32 pio_sz; 1244 u32 pio_sz;
1224 int i, r = 0; 1245 int i, r = 0;
1246 u64 pio_chip = 0;
1247 u64 chip_phys = 0;
1225 1248
1226 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", 1249 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n",
1227 ioc->name, __func__)); 1250 ioc->name, __func__));
1228 1251
1229 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); 1252 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
@@ -1242,6 +1265,9 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1242 goto out_fail; 1265 goto out_fail;
1243 } 1266 }
1244 1267
1268 /* AER (Advanced Error Reporting) hooks */
1269 pci_enable_pcie_error_reporting(pdev);
1270
1245 pci_set_master(pdev); 1271 pci_set_master(pdev);
1246 1272
1247 if (_base_config_dma_addressing(ioc, pdev) != 0) { 1273 if (_base_config_dma_addressing(ioc, pdev) != 0) {
@@ -1252,22 +1278,26 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1252 } 1278 }
1253 1279
1254 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) { 1280 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) {
1255 if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { 1281 if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
1256 if (pio_sz) 1282 if (pio_sz)
1257 continue; 1283 continue;
1258 ioc->pio_chip = pci_resource_start(pdev, i); 1284 pio_chip = (u64)pci_resource_start(pdev, i);
1259 pio_sz = pci_resource_len(pdev, i); 1285 pio_sz = pci_resource_len(pdev, i);
1260 } else { 1286 } else {
1261 if (memap_sz) 1287 if (memap_sz)
1262 continue; 1288 continue;
1263 ioc->chip_phys = pci_resource_start(pdev, i); 1289 /* verify memory resource is valid before using */
1264 memap_sz = pci_resource_len(pdev, i); 1290 if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
1265 ioc->chip = ioremap(ioc->chip_phys, memap_sz); 1291 ioc->chip_phys = pci_resource_start(pdev, i);
1266 if (ioc->chip == NULL) { 1292 chip_phys = (u64)ioc->chip_phys;
1267 printk(MPT2SAS_ERR_FMT "unable to map adapter " 1293 memap_sz = pci_resource_len(pdev, i);
1268 "memory!\n", ioc->name); 1294 ioc->chip = ioremap(ioc->chip_phys, memap_sz);
1269 r = -EINVAL; 1295 if (ioc->chip == NULL) {
1270 goto out_fail; 1296 printk(MPT2SAS_ERR_FMT "unable to map "
1297 "adapter memory!\n", ioc->name);
1298 r = -EINVAL;
1299 goto out_fail;
1300 }
1271 } 1301 }
1272 } 1302 }
1273 } 1303 }
@@ -1280,10 +1310,13 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1280 printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n", 1310 printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n",
1281 ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : 1311 ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" :
1282 "IO-APIC enabled"), ioc->pci_irq); 1312 "IO-APIC enabled"), ioc->pci_irq);
1283 printk(MPT2SAS_INFO_FMT "iomem(0x%lx), mapped(0x%p), size(%d)\n", 1313 printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n",
1284 ioc->name, ioc->chip_phys, ioc->chip, memap_sz); 1314 ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz);
1285 printk(MPT2SAS_INFO_FMT "ioport(0x%lx), size(%d)\n", 1315 printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n",
1286 ioc->name, ioc->pio_chip, pio_sz); 1316 ioc->name, (unsigned long long)pio_chip, pio_sz);
1317
1318 /* Save PCI configuration state for recovery from PCI AER/EEH errors */
1319 pci_save_state(pdev);
1287 1320
1288 return 0; 1321 return 0;
1289 1322
@@ -1293,6 +1326,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1293 ioc->chip_phys = 0; 1326 ioc->chip_phys = 0;
1294 ioc->pci_irq = -1; 1327 ioc->pci_irq = -1;
1295 pci_release_selected_regions(ioc->pdev, ioc->bars); 1328 pci_release_selected_regions(ioc->pdev, ioc->bars);
1329 pci_disable_pcie_error_reporting(pdev);
1296 pci_disable_device(pdev); 1330 pci_disable_device(pdev);
1297 return r; 1331 return r;
1298} 1332}
@@ -1459,6 +1493,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1459{ 1493{
1460 unsigned long flags; 1494 unsigned long flags;
1461 int i; 1495 int i;
1496 struct chain_tracker *chain_req, *next;
1462 1497
1463 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 1498 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1464 if (smid >= ioc->hi_priority_smid) { 1499 if (smid >= ioc->hi_priority_smid) {
@@ -1481,6 +1516,14 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1481 1516
1482 /* scsiio queue */ 1517 /* scsiio queue */
1483 i = smid - 1; 1518 i = smid - 1;
1519 if (!list_empty(&ioc->scsi_lookup[i].chain_list)) {
1520 list_for_each_entry_safe(chain_req, next,
1521 &ioc->scsi_lookup[i].chain_list, tracker_list) {
1522 list_del_init(&chain_req->tracker_list);
1523 list_add_tail(&chain_req->tracker_list,
1524 &ioc->free_chain_list);
1525 }
1526 }
1484 ioc->scsi_lookup[i].cb_idx = 0xFF; 1527 ioc->scsi_lookup[i].cb_idx = 0xFF;
1485 ioc->scsi_lookup[i].scmd = NULL; 1528 ioc->scsi_lookup[i].scmd = NULL;
1486 list_add_tail(&ioc->scsi_lookup[i].tracker_list, 1529 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
@@ -1789,6 +1832,97 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
1789} 1832}
1790 1833
1791/** 1834/**
1835 * _base_update_missing_delay - change the missing delay timers
1836 * @ioc: per adapter object
1837 * @device_missing_delay: amount of time till device is reported missing
1838 * @io_missing_delay: interval IO is returned when there is a missing device
1839 *
1840 * Return nothing.
1841 *
1842 * Passed on the command line, this function will modify the device missing
1843 * delay, as well as the io missing delay. This should be called at driver
1844 * load time.
1845 */
1846static void
1847_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
1848 u16 device_missing_delay, u8 io_missing_delay)
1849{
1850 u16 dmd, dmd_new, dmd_orignal;
1851 u8 io_missing_delay_original;
1852 u16 sz;
1853 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1854 Mpi2ConfigReply_t mpi_reply;
1855 u8 num_phys = 0;
1856 u16 ioc_status;
1857
1858 mpt2sas_config_get_number_hba_phys(ioc, &num_phys);
1859 if (!num_phys)
1860 return;
1861
1862 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys *
1863 sizeof(Mpi2SasIOUnit1PhyData_t));
1864 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1865 if (!sas_iounit_pg1) {
1866 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1867 ioc->name, __FILE__, __LINE__, __func__);
1868 goto out;
1869 }
1870 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1871 sas_iounit_pg1, sz))) {
1872 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1873 ioc->name, __FILE__, __LINE__, __func__);
1874 goto out;
1875 }
1876 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1877 MPI2_IOCSTATUS_MASK;
1878 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1879 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1880 ioc->name, __FILE__, __LINE__, __func__);
1881 goto out;
1882 }
1883
1884 /* device missing delay */
1885 dmd = sas_iounit_pg1->ReportDeviceMissingDelay;
1886 if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
1887 dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
1888 else
1889 dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1890 dmd_orignal = dmd;
1891 if (device_missing_delay > 0x7F) {
1892 dmd = (device_missing_delay > 0x7F0) ? 0x7F0 :
1893 device_missing_delay;
1894 dmd = dmd / 16;
1895 dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16;
1896 } else
1897 dmd = device_missing_delay;
1898 sas_iounit_pg1->ReportDeviceMissingDelay = dmd;
1899
1900 /* io missing delay */
1901 io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay;
1902 sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay;
1903
1904 if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1905 sz)) {
1906 if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
1907 dmd_new = (dmd &
1908 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
1909 else
1910 dmd_new =
1911 dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1912 printk(MPT2SAS_INFO_FMT "device_missing_delay: old(%d), "
1913 "new(%d)\n", ioc->name, dmd_orignal, dmd_new);
1914 printk(MPT2SAS_INFO_FMT "ioc_missing_delay: old(%d), "
1915 "new(%d)\n", ioc->name, io_missing_delay_original,
1916 io_missing_delay);
1917 ioc->device_missing_delay = dmd_new;
1918 ioc->io_missing_delay = io_missing_delay;
1919 }
1920
1921out:
1922 kfree(sas_iounit_pg1);
1923}
1924
1925/**
1792 * _base_static_config_pages - static start of day config pages 1926 * _base_static_config_pages - static start of day config pages
1793 * @ioc: per adapter object 1927 * @ioc: per adapter object
1794 * 1928 *
@@ -1825,6 +1959,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
1825 MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; 1959 MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
1826 ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); 1960 ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags);
1827 mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); 1961 mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
1962
1828} 1963}
1829 1964
1830/** 1965/**
@@ -1838,7 +1973,9 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
1838static void 1973static void
1839_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) 1974_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1840{ 1975{
1841 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1976 int i;
1977
1978 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1842 __func__)); 1979 __func__));
1843 1980
1844 if (ioc->request) { 1981 if (ioc->request) {
@@ -1896,9 +2033,26 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1896 ioc->config_page, ioc->config_page_dma); 2033 ioc->config_page, ioc->config_page_dma);
1897 } 2034 }
1898 2035
1899 kfree(ioc->scsi_lookup); 2036 if (ioc->scsi_lookup) {
2037 free_pages((ulong)ioc->scsi_lookup, ioc->scsi_lookup_pages);
2038 ioc->scsi_lookup = NULL;
2039 }
1900 kfree(ioc->hpr_lookup); 2040 kfree(ioc->hpr_lookup);
1901 kfree(ioc->internal_lookup); 2041 kfree(ioc->internal_lookup);
2042 if (ioc->chain_lookup) {
2043 for (i = 0; i < ioc->chain_depth; i++) {
2044 if (ioc->chain_lookup[i].chain_buffer)
2045 pci_pool_free(ioc->chain_dma_pool,
2046 ioc->chain_lookup[i].chain_buffer,
2047 ioc->chain_lookup[i].chain_buffer_dma);
2048 }
2049 if (ioc->chain_dma_pool)
2050 pci_pool_destroy(ioc->chain_dma_pool);
2051 }
2052 if (ioc->chain_lookup) {
2053 free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
2054 ioc->chain_lookup = NULL;
2055 }
1902} 2056}
1903 2057
1904 2058
@@ -1920,8 +2074,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1920 u32 sz, total_sz; 2074 u32 sz, total_sz;
1921 u32 retry_sz; 2075 u32 retry_sz;
1922 u16 max_request_credit; 2076 u16 max_request_credit;
2077 int i;
1923 2078
1924 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 2079 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1925 __func__)); 2080 __func__));
1926 2081
1927 retry_sz = 0; 2082 retry_sz = 0;
@@ -1937,14 +2092,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1937 } 2092 }
1938 2093
1939 /* command line tunables for max controller queue depth */ 2094 /* command line tunables for max controller queue depth */
1940 if (max_queue_depth != -1) { 2095 if (max_queue_depth != -1)
1941 max_request_credit = (max_queue_depth < facts->RequestCredit) 2096 max_request_credit = (max_queue_depth < facts->RequestCredit)
1942 ? max_queue_depth : facts->RequestCredit; 2097 ? max_queue_depth : facts->RequestCredit;
1943 } else { 2098 else
1944 max_request_credit = (facts->RequestCredit > 2099 max_request_credit = facts->RequestCredit;
1945 MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE :
1946 facts->RequestCredit;
1947 }
1948 2100
1949 ioc->hba_queue_depth = max_request_credit; 2101 ioc->hba_queue_depth = max_request_credit;
1950 ioc->hi_priority_depth = facts->HighPriorityCredit; 2102 ioc->hi_priority_depth = facts->HighPriorityCredit;
@@ -2050,7 +2202,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2050 * "frame for smid=0 2202 * "frame for smid=0
2051 */ 2203 */
2052 ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth; 2204 ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth;
2053 sz = ((ioc->scsiio_depth + 1 + ioc->chain_depth) * ioc->request_sz); 2205 sz = ((ioc->scsiio_depth + 1) * ioc->request_sz);
2054 2206
2055 /* hi-priority queue */ 2207 /* hi-priority queue */
2056 sz += (ioc->hi_priority_depth * ioc->request_sz); 2208 sz += (ioc->hi_priority_depth * ioc->request_sz);
@@ -2091,28 +2243,22 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2091 ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * 2243 ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth *
2092 ioc->request_sz); 2244 ioc->request_sz);
2093 2245
2094 ioc->chain = ioc->internal + (ioc->internal_depth *
2095 ioc->request_sz);
2096 ioc->chain_dma = ioc->internal_dma + (ioc->internal_depth *
2097 ioc->request_sz);
2098 2246
2099 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): " 2247 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
2100 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, 2248 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
2101 ioc->request, ioc->hba_queue_depth, ioc->request_sz, 2249 ioc->request, ioc->hba_queue_depth, ioc->request_sz,
2102 (ioc->hba_queue_depth * ioc->request_sz)/1024)); 2250 (ioc->hba_queue_depth * ioc->request_sz)/1024));
2103 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth"
2104 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain,
2105 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
2106 ioc->request_sz))/1024));
2107 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n", 2251 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n",
2108 ioc->name, (unsigned long long) ioc->request_dma)); 2252 ioc->name, (unsigned long long) ioc->request_dma));
2109 total_sz += sz; 2253 total_sz += sz;
2110 2254
2111 ioc->scsi_lookup = kcalloc(ioc->scsiio_depth, 2255 sz = ioc->scsiio_depth * sizeof(struct request_tracker);
2112 sizeof(struct request_tracker), GFP_KERNEL); 2256 ioc->scsi_lookup_pages = get_order(sz);
2257 ioc->scsi_lookup = (struct request_tracker *)__get_free_pages(
2258 GFP_KERNEL, ioc->scsi_lookup_pages);
2113 if (!ioc->scsi_lookup) { 2259 if (!ioc->scsi_lookup) {
2114 printk(MPT2SAS_ERR_FMT "scsi_lookup: kcalloc failed\n", 2260 printk(MPT2SAS_ERR_FMT "scsi_lookup: get_free_pages failed, "
2115 ioc->name); 2261 "sz(%d)\n", ioc->name, (int)sz);
2116 goto out; 2262 goto out;
2117 } 2263 }
2118 2264
@@ -2120,6 +2266,38 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2120 "depth(%d)\n", ioc->name, ioc->request, 2266 "depth(%d)\n", ioc->name, ioc->request,
2121 ioc->scsiio_depth)); 2267 ioc->scsiio_depth));
2122 2268
2269 /* loop till the allocation succeeds */
2270 do {
2271 sz = ioc->chain_depth * sizeof(struct chain_tracker);
2272 ioc->chain_pages = get_order(sz);
2273 ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
2274 GFP_KERNEL, ioc->chain_pages);
2275 if (ioc->chain_lookup == NULL)
2276 ioc->chain_depth -= 100;
2277 } while (ioc->chain_lookup == NULL);
2278 ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
2279 ioc->request_sz, 16, 0);
2280 if (!ioc->chain_dma_pool) {
2281 printk(MPT2SAS_ERR_FMT "chain_dma_pool: pci_pool_create "
2282 "failed\n", ioc->name);
2283 goto out;
2284 }
2285 for (i = 0; i < ioc->chain_depth; i++) {
2286 ioc->chain_lookup[i].chain_buffer = pci_pool_alloc(
2287 ioc->chain_dma_pool , GFP_KERNEL,
2288 &ioc->chain_lookup[i].chain_buffer_dma);
2289 if (!ioc->chain_lookup[i].chain_buffer) {
2290 ioc->chain_depth = i;
2291 goto chain_done;
2292 }
2293 total_sz += ioc->request_sz;
2294 }
2295chain_done:
2296 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool depth"
2297 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
2298 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
2299 ioc->request_sz))/1024));
2300
2123 /* initialize hi-priority queue smid's */ 2301 /* initialize hi-priority queue smid's */
2124 ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, 2302 ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
2125 sizeof(struct request_tracker), GFP_KERNEL); 2303 sizeof(struct request_tracker), GFP_KERNEL);
@@ -2186,6 +2364,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2186 ioc->name); 2364 ioc->name);
2187 goto out; 2365 goto out;
2188 } 2366 }
2367 ioc->reply_dma_min_address = (u32)(ioc->reply_dma);
2368 ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz;
2189 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth" 2369 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth"
2190 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply, 2370 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply,
2191 ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024)); 2371 ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024));
@@ -2267,7 +2447,6 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2267 return 0; 2447 return 0;
2268 2448
2269 out: 2449 out:
2270 _base_release_memory_pools(ioc);
2271 return -ENOMEM; 2450 return -ENOMEM;
2272} 2451}
2273 2452
@@ -2346,7 +2525,7 @@ _base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout,
2346 do { 2525 do {
2347 int_status = readl(&ioc->chip->HostInterruptStatus); 2526 int_status = readl(&ioc->chip->HostInterruptStatus);
2348 if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { 2527 if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
2349 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 2528 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
2350 "successfull count(%d), timeout(%d)\n", ioc->name, 2529 "successfull count(%d), timeout(%d)\n", ioc->name,
2351 __func__, count, timeout)); 2530 __func__, count, timeout));
2352 return 0; 2531 return 0;
@@ -2387,7 +2566,7 @@ _base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout,
2387 do { 2566 do {
2388 int_status = readl(&ioc->chip->HostInterruptStatus); 2567 int_status = readl(&ioc->chip->HostInterruptStatus);
2389 if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { 2568 if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) {
2390 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 2569 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
2391 "successfull count(%d), timeout(%d)\n", ioc->name, 2570 "successfull count(%d), timeout(%d)\n", ioc->name,
2392 __func__, count, timeout)); 2571 __func__, count, timeout));
2393 return 0; 2572 return 0;
@@ -2435,7 +2614,7 @@ _base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout,
2435 do { 2614 do {
2436 doorbell_reg = readl(&ioc->chip->Doorbell); 2615 doorbell_reg = readl(&ioc->chip->Doorbell);
2437 if (!(doorbell_reg & MPI2_DOORBELL_USED)) { 2616 if (!(doorbell_reg & MPI2_DOORBELL_USED)) {
2438 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 2617 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
2439 "successfull count(%d), timeout(%d)\n", ioc->name, 2618 "successfull count(%d), timeout(%d)\n", ioc->name,
2440 __func__, count, timeout)); 2619 __func__, count, timeout));
2441 return 0; 2620 return 0;
@@ -2609,9 +2788,9 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes,
2609 2788
2610 if (ioc->logging_level & MPT_DEBUG_INIT) { 2789 if (ioc->logging_level & MPT_DEBUG_INIT) {
2611 mfp = (u32 *)reply; 2790 mfp = (u32 *)reply;
2612 printk(KERN_DEBUG "\toffset:data\n"); 2791 printk(KERN_INFO "\toffset:data\n");
2613 for (i = 0; i < reply_bytes/4; i++) 2792 for (i = 0; i < reply_bytes/4; i++)
2614 printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4, 2793 printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4,
2615 le32_to_cpu(mfp[i])); 2794 le32_to_cpu(mfp[i]));
2616 } 2795 }
2617 return 0; 2796 return 0;
@@ -2644,7 +2823,7 @@ mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
2644 void *request; 2823 void *request;
2645 u16 wait_state_count; 2824 u16 wait_state_count;
2646 2825
2647 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 2826 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
2648 __func__)); 2827 __func__));
2649 2828
2650 mutex_lock(&ioc->base_cmds.mutex); 2829 mutex_lock(&ioc->base_cmds.mutex);
@@ -2749,7 +2928,7 @@ mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
2749 void *request; 2928 void *request;
2750 u16 wait_state_count; 2929 u16 wait_state_count;
2751 2930
2752 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 2931 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
2753 __func__)); 2932 __func__));
2754 2933
2755 mutex_lock(&ioc->base_cmds.mutex); 2934 mutex_lock(&ioc->base_cmds.mutex);
@@ -2837,7 +3016,7 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag)
2837 Mpi2PortFactsReply_t mpi_reply, *pfacts; 3016 Mpi2PortFactsReply_t mpi_reply, *pfacts;
2838 int mpi_reply_sz, mpi_request_sz, r; 3017 int mpi_reply_sz, mpi_request_sz, r;
2839 3018
2840 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3019 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
2841 __func__)); 3020 __func__));
2842 3021
2843 mpi_reply_sz = sizeof(Mpi2PortFactsReply_t); 3022 mpi_reply_sz = sizeof(Mpi2PortFactsReply_t);
@@ -2879,7 +3058,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2879 Mpi2IOCFactsReply_t mpi_reply, *facts; 3058 Mpi2IOCFactsReply_t mpi_reply, *facts;
2880 int mpi_reply_sz, mpi_request_sz, r; 3059 int mpi_reply_sz, mpi_request_sz, r;
2881 3060
2882 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3061 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
2883 __func__)); 3062 __func__));
2884 3063
2885 mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); 3064 mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t);
@@ -2951,7 +3130,7 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2951 struct timeval current_time; 3130 struct timeval current_time;
2952 u16 ioc_status; 3131 u16 ioc_status;
2953 3132
2954 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3133 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
2955 __func__)); 3134 __func__));
2956 3135
2957 memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t)); 3136 memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t));
@@ -3004,17 +3183,17 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3004 * since epoch ~ midnight January 1, 1970. 3183 * since epoch ~ midnight January 1, 1970.
3005 */ 3184 */
3006 do_gettimeofday(&current_time); 3185 do_gettimeofday(&current_time);
3007 mpi_request.TimeStamp = (current_time.tv_sec * 1000) + 3186 mpi_request.TimeStamp = cpu_to_le64((u64)current_time.tv_sec * 1000 +
3008 (current_time.tv_usec >> 3); 3187 (current_time.tv_usec / 1000));
3009 3188
3010 if (ioc->logging_level & MPT_DEBUG_INIT) { 3189 if (ioc->logging_level & MPT_DEBUG_INIT) {
3011 u32 *mfp; 3190 u32 *mfp;
3012 int i; 3191 int i;
3013 3192
3014 mfp = (u32 *)&mpi_request; 3193 mfp = (u32 *)&mpi_request;
3015 printk(KERN_DEBUG "\toffset:data\n"); 3194 printk(KERN_INFO "\toffset:data\n");
3016 for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) 3195 for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++)
3017 printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4, 3196 printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4,
3018 le32_to_cpu(mfp[i])); 3197 le32_to_cpu(mfp[i]));
3019 } 3198 }
3020 3199
@@ -3093,7 +3272,7 @@ _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3093 r = -ETIME; 3272 r = -ETIME;
3094 goto out; 3273 goto out;
3095 } else 3274 } else
3096 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n", 3275 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n",
3097 ioc->name, __func__)); 3276 ioc->name, __func__));
3098 3277
3099 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL, 3278 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL,
@@ -3153,7 +3332,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3153 int r = 0; 3332 int r = 0;
3154 int i; 3333 int i;
3155 3334
3156 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3335 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3157 __func__)); 3336 __func__));
3158 3337
3159 if (ioc->base_cmds.status & MPT2_CMD_PENDING) { 3338 if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
@@ -3177,7 +3356,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3177 mpi_request->VP_ID = 0; 3356 mpi_request->VP_ID = 0;
3178 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3357 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3179 mpi_request->EventMasks[i] = 3358 mpi_request->EventMasks[i] =
3180 le32_to_cpu(ioc->event_masks[i]); 3359 cpu_to_le32(ioc->event_masks[i]);
3181 mpt2sas_base_put_smid_default(ioc, smid); 3360 mpt2sas_base_put_smid_default(ioc, smid);
3182 init_completion(&ioc->base_cmds.done); 3361 init_completion(&ioc->base_cmds.done);
3183 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); 3362 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
@@ -3191,7 +3370,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3191 else 3370 else
3192 r = -ETIME; 3371 r = -ETIME;
3193 } else 3372 } else
3194 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n", 3373 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n",
3195 ioc->name, __func__)); 3374 ioc->name, __func__));
3196 ioc->base_cmds.status = MPT2_CMD_NOT_USED; 3375 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
3197 return r; 3376 return r;
@@ -3253,7 +3432,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3253 3432
3254 _base_save_msix_table(ioc); 3433 _base_save_msix_table(ioc);
3255 3434
3256 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "clear interrupts\n", 3435 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n",
3257 ioc->name)); 3436 ioc->name));
3258 3437
3259 count = 0; 3438 count = 0;
@@ -3261,7 +3440,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3261 /* Write magic sequence to WriteSequence register 3440 /* Write magic sequence to WriteSequence register
3262 * Loop until in diagnostic mode 3441 * Loop until in diagnostic mode
3263 */ 3442 */
3264 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "write magic " 3443 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "write magic "
3265 "sequence\n", ioc->name)); 3444 "sequence\n", ioc->name));
3266 writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); 3445 writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
3267 writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence); 3446 writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence);
@@ -3281,7 +3460,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3281 goto out; 3460 goto out;
3282 3461
3283 host_diagnostic = readl(&ioc->chip->HostDiagnostic); 3462 host_diagnostic = readl(&ioc->chip->HostDiagnostic);
3284 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "wrote magic " 3463 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "wrote magic "
3285 "sequence: count(%d), host_diagnostic(0x%08x)\n", 3464 "sequence: count(%d), host_diagnostic(0x%08x)\n",
3286 ioc->name, count, host_diagnostic)); 3465 ioc->name, count, host_diagnostic));
3287 3466
@@ -3289,7 +3468,7 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3289 3468
3290 hcb_size = readl(&ioc->chip->HCBSize); 3469 hcb_size = readl(&ioc->chip->HCBSize);
3291 3470
3292 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "diag reset: issued\n", 3471 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "diag reset: issued\n",
3293 ioc->name)); 3472 ioc->name));
3294 writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, 3473 writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
3295 &ioc->chip->HostDiagnostic); 3474 &ioc->chip->HostDiagnostic);
@@ -3316,29 +3495,29 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3316 3495
3317 if (host_diagnostic & MPI2_DIAG_HCB_MODE) { 3496 if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
3318 3497
3319 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter " 3498 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter "
3320 "assuming the HCB Address points to good F/W\n", 3499 "assuming the HCB Address points to good F/W\n",
3321 ioc->name)); 3500 ioc->name));
3322 host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK; 3501 host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
3323 host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW; 3502 host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
3324 writel(host_diagnostic, &ioc->chip->HostDiagnostic); 3503 writel(host_diagnostic, &ioc->chip->HostDiagnostic);
3325 3504
3326 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT 3505 drsprintk(ioc, printk(MPT2SAS_INFO_FMT
3327 "re-enable the HCDW\n", ioc->name)); 3506 "re-enable the HCDW\n", ioc->name));
3328 writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE, 3507 writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE,
3329 &ioc->chip->HCBSize); 3508 &ioc->chip->HCBSize);
3330 } 3509 }
3331 3510
3332 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter\n", 3511 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "restart the adapter\n",
3333 ioc->name)); 3512 ioc->name));
3334 writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET, 3513 writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET,
3335 &ioc->chip->HostDiagnostic); 3514 &ioc->chip->HostDiagnostic);
3336 3515
3337 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "disable writes to the " 3516 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "disable writes to the "
3338 "diagnostic register\n", ioc->name)); 3517 "diagnostic register\n", ioc->name));
3339 writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); 3518 writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
3340 3519
3341 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "Wait for FW to go to the " 3520 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "Wait for FW to go to the "
3342 "READY state\n", ioc->name)); 3521 "READY state\n", ioc->name));
3343 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20, 3522 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20,
3344 sleep_flag); 3523 sleep_flag);
@@ -3370,19 +3549,23 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3370 enum reset_type type) 3549 enum reset_type type)
3371{ 3550{
3372 u32 ioc_state; 3551 u32 ioc_state;
3552 int rc;
3373 3553
3374 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3554 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3375 __func__)); 3555 __func__));
3376 3556
3557 if (ioc->pci_error_recovery)
3558 return 0;
3559
3377 ioc_state = mpt2sas_base_get_iocstate(ioc, 0); 3560 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
3378 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: ioc_state(0x%08x)\n", 3561 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n",
3379 ioc->name, __func__, ioc_state)); 3562 ioc->name, __func__, ioc_state));
3380 3563
3381 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) 3564 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY)
3382 return 0; 3565 return 0;
3383 3566
3384 if (ioc_state & MPI2_DOORBELL_USED) { 3567 if (ioc_state & MPI2_DOORBELL_USED) {
3385 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell " 3568 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "unexpected doorbell "
3386 "active!\n", ioc->name)); 3569 "active!\n", ioc->name));
3387 goto issue_diag_reset; 3570 goto issue_diag_reset;
3388 } 3571 }
@@ -3398,11 +3581,15 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3398 3581
3399 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) 3582 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL)
3400 if (!(_base_send_ioc_reset(ioc, 3583 if (!(_base_send_ioc_reset(ioc,
3401 MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) 3584 MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) {
3585 ioc->ioc_reset_count++;
3402 return 0; 3586 return 0;
3587 }
3403 3588
3404 issue_diag_reset: 3589 issue_diag_reset:
3405 return _base_diag_reset(ioc, CAN_SLEEP); 3590 rc = _base_diag_reset(ioc, CAN_SLEEP);
3591 ioc->ioc_reset_count++;
3592 return rc;
3406} 3593}
3407 3594
3408/** 3595/**
@@ -3421,7 +3608,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3421 u16 smid; 3608 u16 smid;
3422 struct _tr_list *delayed_tr, *delayed_tr_next; 3609 struct _tr_list *delayed_tr, *delayed_tr_next;
3423 3610
3424 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3611 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3425 __func__)); 3612 __func__));
3426 3613
3427 /* clean the delayed target reset list */ 3614 /* clean the delayed target reset list */
@@ -3431,11 +3618,18 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3431 kfree(delayed_tr); 3618 kfree(delayed_tr);
3432 } 3619 }
3433 3620
3621 list_for_each_entry_safe(delayed_tr, delayed_tr_next,
3622 &ioc->delayed_tr_volume_list, list) {
3623 list_del(&delayed_tr->list);
3624 kfree(delayed_tr);
3625 }
3626
3434 /* initialize the scsi lookup free list */ 3627 /* initialize the scsi lookup free list */
3435 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 3628 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3436 INIT_LIST_HEAD(&ioc->free_list); 3629 INIT_LIST_HEAD(&ioc->free_list);
3437 smid = 1; 3630 smid = 1;
3438 for (i = 0; i < ioc->scsiio_depth; i++, smid++) { 3631 for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
3632 INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list);
3439 ioc->scsi_lookup[i].cb_idx = 0xFF; 3633 ioc->scsi_lookup[i].cb_idx = 0xFF;
3440 ioc->scsi_lookup[i].smid = smid; 3634 ioc->scsi_lookup[i].smid = smid;
3441 ioc->scsi_lookup[i].scmd = NULL; 3635 ioc->scsi_lookup[i].scmd = NULL;
@@ -3462,6 +3656,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3462 list_add_tail(&ioc->internal_lookup[i].tracker_list, 3656 list_add_tail(&ioc->internal_lookup[i].tracker_list,
3463 &ioc->internal_free_list); 3657 &ioc->internal_free_list);
3464 } 3658 }
3659
3660 /* chain pool */
3661 INIT_LIST_HEAD(&ioc->free_chain_list);
3662 for (i = 0; i < ioc->chain_depth; i++)
3663 list_add_tail(&ioc->chain_lookup[i].tracker_list,
3664 &ioc->free_chain_list);
3665
3465 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 3666 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3466 3667
3467 /* initialize Reply Free Queue */ 3668 /* initialize Reply Free Queue */
@@ -3492,6 +3693,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3492 if (sleep_flag == CAN_SLEEP) 3693 if (sleep_flag == CAN_SLEEP)
3493 _base_static_config_pages(ioc); 3694 _base_static_config_pages(ioc);
3494 3695
3696 if (ioc->wait_for_port_enable_to_complete) {
3697 if (diag_buffer_enable != 0)
3698 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
3699 if (disable_discovery > 0)
3700 return r;
3701 }
3702
3495 r = _base_send_port_enable(ioc, sleep_flag); 3703 r = _base_send_port_enable(ioc, sleep_flag);
3496 if (r) 3704 if (r)
3497 return r; 3705 return r;
@@ -3510,11 +3718,13 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3510{ 3718{
3511 struct pci_dev *pdev = ioc->pdev; 3719 struct pci_dev *pdev = ioc->pdev;
3512 3720
3513 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3721 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3514 __func__)); 3722 __func__));
3515 3723
3516 _base_mask_interrupts(ioc); 3724 _base_mask_interrupts(ioc);
3725 ioc->shost_recovery = 1;
3517 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 3726 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3727 ioc->shost_recovery = 0;
3518 if (ioc->pci_irq) { 3728 if (ioc->pci_irq) {
3519 synchronize_irq(pdev->irq); 3729 synchronize_irq(pdev->irq);
3520 free_irq(ioc->pci_irq, ioc); 3730 free_irq(ioc->pci_irq, ioc);
@@ -3525,6 +3735,7 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3525 ioc->pci_irq = -1; 3735 ioc->pci_irq = -1;
3526 ioc->chip_phys = 0; 3736 ioc->chip_phys = 0;
3527 pci_release_selected_regions(ioc->pdev, ioc->bars); 3737 pci_release_selected_regions(ioc->pdev, ioc->bars);
3738 pci_disable_pcie_error_reporting(pdev);
3528 pci_disable_device(pdev); 3739 pci_disable_device(pdev);
3529 return; 3740 return;
3530} 3741}
@@ -3540,7 +3751,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3540{ 3751{
3541 int r, i; 3752 int r, i;
3542 3753
3543 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3754 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3544 __func__)); 3755 __func__));
3545 3756
3546 r = mpt2sas_base_map_resources(ioc); 3757 r = mpt2sas_base_map_resources(ioc);
@@ -3558,8 +3769,10 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3558 3769
3559 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, 3770 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
3560 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL); 3771 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
3561 if (!ioc->pfacts) 3772 if (!ioc->pfacts) {
3773 r = -ENOMEM;
3562 goto out_free_resources; 3774 goto out_free_resources;
3775 }
3563 3776
3564 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) { 3777 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
3565 r = _base_get_port_facts(ioc, i, CAN_SLEEP); 3778 r = _base_get_port_facts(ioc, i, CAN_SLEEP);
@@ -3573,6 +3786,19 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3573 3786
3574 init_waitqueue_head(&ioc->reset_wq); 3787 init_waitqueue_head(&ioc->reset_wq);
3575 3788
3789 /* allocate memory pd handle bitmask list */
3790 ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
3791 if (ioc->facts.MaxDevHandle % 8)
3792 ioc->pd_handles_sz++;
3793 ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
3794 GFP_KERNEL);
3795 if (!ioc->pd_handles) {
3796 r = -ENOMEM;
3797 goto out_free_resources;
3798 }
3799
3800 ioc->fwfault_debug = mpt2sas_fwfault_debug;
3801
3576 /* base internal command bits */ 3802 /* base internal command bits */
3577 mutex_init(&ioc->base_cmds.mutex); 3803 mutex_init(&ioc->base_cmds.mutex);
3578 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 3804 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
@@ -3600,9 +3826,27 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3600 3826
3601 /* ctl module internal command bits */ 3827 /* ctl module internal command bits */
3602 ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 3828 ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3829 ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
3603 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 3830 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
3604 mutex_init(&ioc->ctl_cmds.mutex); 3831 mutex_init(&ioc->ctl_cmds.mutex);
3605 3832
3833 if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
3834 !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
3835 !ioc->config_cmds.reply || !ioc->ctl_cmds.reply ||
3836 !ioc->ctl_cmds.sense) {
3837 r = -ENOMEM;
3838 goto out_free_resources;
3839 }
3840
3841 if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
3842 !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
3843 !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) {
3844 r = -ENOMEM;
3845 goto out_free_resources;
3846 }
3847
3848 init_completion(&ioc->shost_recovery_done);
3849
3606 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3850 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3607 ioc->event_masks[i] = -1; 3851 ioc->event_masks[i] = -1;
3608 3852
@@ -3616,15 +3860,16 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3616 _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME); 3860 _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME);
3617 _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); 3861 _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK);
3618 _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); 3862 _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
3619 _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL);
3620 _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); 3863 _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
3621 r = _base_make_ioc_operational(ioc, CAN_SLEEP); 3864 r = _base_make_ioc_operational(ioc, CAN_SLEEP);
3622 if (r) 3865 if (r)
3623 goto out_free_resources; 3866 goto out_free_resources;
3624 3867
3868 if (missing_delay[0] != -1 && missing_delay[1] != -1)
3869 _base_update_missing_delay(ioc, missing_delay[0],
3870 missing_delay[1]);
3871
3625 mpt2sas_base_start_watchdog(ioc); 3872 mpt2sas_base_start_watchdog(ioc);
3626 if (diag_buffer_enable != 0)
3627 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
3628 return 0; 3873 return 0;
3629 3874
3630 out_free_resources: 3875 out_free_resources:
@@ -3633,15 +3878,19 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3633 mpt2sas_base_free_resources(ioc); 3878 mpt2sas_base_free_resources(ioc);
3634 _base_release_memory_pools(ioc); 3879 _base_release_memory_pools(ioc);
3635 pci_set_drvdata(ioc->pdev, NULL); 3880 pci_set_drvdata(ioc->pdev, NULL);
3881 kfree(ioc->pd_handles);
3636 kfree(ioc->tm_cmds.reply); 3882 kfree(ioc->tm_cmds.reply);
3637 kfree(ioc->transport_cmds.reply); 3883 kfree(ioc->transport_cmds.reply);
3884 kfree(ioc->scsih_cmds.reply);
3638 kfree(ioc->config_cmds.reply); 3885 kfree(ioc->config_cmds.reply);
3639 kfree(ioc->base_cmds.reply); 3886 kfree(ioc->base_cmds.reply);
3640 kfree(ioc->ctl_cmds.reply); 3887 kfree(ioc->ctl_cmds.reply);
3888 kfree(ioc->ctl_cmds.sense);
3641 kfree(ioc->pfacts); 3889 kfree(ioc->pfacts);
3642 ioc->ctl_cmds.reply = NULL; 3890 ioc->ctl_cmds.reply = NULL;
3643 ioc->base_cmds.reply = NULL; 3891 ioc->base_cmds.reply = NULL;
3644 ioc->tm_cmds.reply = NULL; 3892 ioc->tm_cmds.reply = NULL;
3893 ioc->scsih_cmds.reply = NULL;
3645 ioc->transport_cmds.reply = NULL; 3894 ioc->transport_cmds.reply = NULL;
3646 ioc->config_cmds.reply = NULL; 3895 ioc->config_cmds.reply = NULL;
3647 ioc->pfacts = NULL; 3896 ioc->pfacts = NULL;
@@ -3659,18 +3908,21 @@ void
3659mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) 3908mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3660{ 3909{
3661 3910
3662 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3911 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3663 __func__)); 3912 __func__));
3664 3913
3665 mpt2sas_base_stop_watchdog(ioc); 3914 mpt2sas_base_stop_watchdog(ioc);
3666 mpt2sas_base_free_resources(ioc); 3915 mpt2sas_base_free_resources(ioc);
3667 _base_release_memory_pools(ioc); 3916 _base_release_memory_pools(ioc);
3668 pci_set_drvdata(ioc->pdev, NULL); 3917 pci_set_drvdata(ioc->pdev, NULL);
3918 kfree(ioc->pd_handles);
3669 kfree(ioc->pfacts); 3919 kfree(ioc->pfacts);
3670 kfree(ioc->ctl_cmds.reply); 3920 kfree(ioc->ctl_cmds.reply);
3921 kfree(ioc->ctl_cmds.sense);
3671 kfree(ioc->base_cmds.reply); 3922 kfree(ioc->base_cmds.reply);
3672 kfree(ioc->tm_cmds.reply); 3923 kfree(ioc->tm_cmds.reply);
3673 kfree(ioc->transport_cmds.reply); 3924 kfree(ioc->transport_cmds.reply);
3925 kfree(ioc->scsih_cmds.reply);
3674 kfree(ioc->config_cmds.reply); 3926 kfree(ioc->config_cmds.reply);
3675} 3927}
3676 3928
@@ -3691,11 +3943,11 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
3691{ 3943{
3692 switch (reset_phase) { 3944 switch (reset_phase) {
3693 case MPT2_IOC_PRE_RESET: 3945 case MPT2_IOC_PRE_RESET:
3694 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 3946 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
3695 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); 3947 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
3696 break; 3948 break;
3697 case MPT2_IOC_AFTER_RESET: 3949 case MPT2_IOC_AFTER_RESET:
3698 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 3950 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
3699 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); 3951 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
3700 if (ioc->transport_cmds.status & MPT2_CMD_PENDING) { 3952 if (ioc->transport_cmds.status & MPT2_CMD_PENDING) {
3701 ioc->transport_cmds.status |= MPT2_CMD_RESET; 3953 ioc->transport_cmds.status |= MPT2_CMD_RESET;
@@ -3710,12 +3962,12 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
3710 if (ioc->config_cmds.status & MPT2_CMD_PENDING) { 3962 if (ioc->config_cmds.status & MPT2_CMD_PENDING) {
3711 ioc->config_cmds.status |= MPT2_CMD_RESET; 3963 ioc->config_cmds.status |= MPT2_CMD_RESET;
3712 mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); 3964 mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid);
3713 ioc->config_cmds.smid = USHORT_MAX; 3965 ioc->config_cmds.smid = USHRT_MAX;
3714 complete(&ioc->config_cmds.done); 3966 complete(&ioc->config_cmds.done);
3715 } 3967 }
3716 break; 3968 break;
3717 case MPT2_IOC_DONE_RESET: 3969 case MPT2_IOC_DONE_RESET:
3718 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 3970 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
3719 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 3971 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
3720 break; 3972 break;
3721 } 3973 }
@@ -3757,7 +4009,7 @@ _wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3757 return; 4009 return;
3758 4010
3759 /* wait for pending commands to complete */ 4011 /* wait for pending commands to complete */
3760 wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 3 * HZ); 4012 wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ);
3761} 4013}
3762 4014
3763/** 4015/**
@@ -3775,19 +4027,37 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3775 int r; 4027 int r;
3776 unsigned long flags; 4028 unsigned long flags;
3777 4029
3778 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 4030 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
3779 __func__)); 4031 __func__));
3780 4032
4033 if (ioc->pci_error_recovery) {
4034 printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n",
4035 ioc->name, __func__);
4036 r = 0;
4037 goto out;
4038 }
4039
3781 if (mpt2sas_fwfault_debug) 4040 if (mpt2sas_fwfault_debug)
3782 mpt2sas_halt_firmware(ioc); 4041 mpt2sas_halt_firmware(ioc);
3783 4042
3784 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 4043 /* TODO - What we really should be doing is pulling
3785 if (ioc->shost_recovery) { 4044 * out all the code associated with NO_SLEEP; its never used.
3786 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 4045 * That is legacy code from mpt fusion driver, ported over.
3787 printk(MPT2SAS_ERR_FMT "%s: busy\n", 4046 * I will leave this BUG_ON here for now till its been resolved.
3788 ioc->name, __func__); 4047 */
3789 return -EBUSY; 4048 BUG_ON(sleep_flag == NO_SLEEP);
4049
4050 /* wait for an active reset in progress to complete */
4051 if (!mutex_trylock(&ioc->reset_in_progress_mutex)) {
4052 do {
4053 ssleep(1);
4054 } while (ioc->shost_recovery == 1);
4055 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
4056 __func__));
4057 return ioc->ioc_reset_in_progress_status;
3790 } 4058 }
4059
4060 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3791 ioc->shost_recovery = 1; 4061 ioc->shost_recovery = 1;
3792 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 4062 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3793 4063
@@ -3802,14 +4072,17 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3802 if (!r) 4072 if (!r)
3803 _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); 4073 _base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
3804 out: 4074 out:
3805 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: %s\n", 4075 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: %s\n",
3806 ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED"))); 4076 ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));
3807 4077
3808 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 4078 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
4079 ioc->ioc_reset_in_progress_status = r;
3809 ioc->shost_recovery = 0; 4080 ioc->shost_recovery = 0;
4081 complete(&ioc->shost_recovery_done);
3810 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 4082 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
4083 mutex_unlock(&ioc->reset_in_progress_mutex);
3811 4084
3812 if (!r) 4085 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
3813 _base_reset_handler(ioc, MPT2_IOC_RUNNING); 4086 __func__));
3814 return r; 4087 return r;
3815} 4088}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index bb4f14656af..283568c6fb0 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -69,10 +69,10 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "03.100.03.00" 72#define MPT2SAS_DRIVER_VERSION "07.100.00.00"
73#define MPT2SAS_MAJOR_VERSION 03 73#define MPT2SAS_MAJOR_VERSION 07
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 03 75#define MPT2SAS_BUILD_VERSION 00
76#define MPT2SAS_RELEASE_VERSION 00 76#define MPT2SAS_RELEASE_VERSION 00
77 77
78/* 78/*
@@ -119,13 +119,11 @@
119#define MPT2_IOC_PRE_RESET 1 /* prior to host reset */ 119#define MPT2_IOC_PRE_RESET 1 /* prior to host reset */
120#define MPT2_IOC_AFTER_RESET 2 /* just after host reset */ 120#define MPT2_IOC_AFTER_RESET 2 /* just after host reset */
121#define MPT2_IOC_DONE_RESET 3 /* links re-initialized */ 121#define MPT2_IOC_DONE_RESET 3 /* links re-initialized */
122#define MPT2_IOC_RUNNING 4 /* shost running */
123 122
124/* 123/*
125 * logging format 124 * logging format
126 */ 125 */
127#define MPT2SAS_FMT "%s: " 126#define MPT2SAS_FMT "%s: "
128#define MPT2SAS_DEBUG_FMT KERN_DEBUG MPT2SAS_FMT
129#define MPT2SAS_INFO_FMT KERN_INFO MPT2SAS_FMT 127#define MPT2SAS_INFO_FMT KERN_INFO MPT2SAS_FMT
130#define MPT2SAS_NOTE_FMT KERN_NOTICE MPT2SAS_FMT 128#define MPT2SAS_NOTE_FMT KERN_NOTICE MPT2SAS_FMT
131#define MPT2SAS_WARN_FMT KERN_WARNING MPT2SAS_FMT 129#define MPT2SAS_WARN_FMT KERN_WARNING MPT2SAS_FMT
@@ -249,6 +247,7 @@ struct MPT2SAS_DEVICE {
249 * @mutex: mutex 247 * @mutex: mutex
250 * @done: completion 248 * @done: completion
251 * @reply: reply message pointer 249 * @reply: reply message pointer
250 * @sense: sense data
252 * @status: MPT2_CMD_XXX status 251 * @status: MPT2_CMD_XXX status
253 * @smid: system message id 252 * @smid: system message id
254 */ 253 */
@@ -256,20 +255,11 @@ struct _internal_cmd {
256 struct mutex mutex; 255 struct mutex mutex;
257 struct completion done; 256 struct completion done;
258 void *reply; 257 void *reply;
258 void *sense;
259 u16 status; 259 u16 status;
260 u16 smid; 260 u16 smid;
261}; 261};
262 262
263/*
264 * SAS Topology Structures
265 */
266
267#define MPTSAS_STATE_TR_SEND 0x0001
268#define MPTSAS_STATE_TR_COMPLETE 0x0002
269#define MPTSAS_STATE_CNTRL_SEND 0x0004
270#define MPTSAS_STATE_CNTRL_COMPLETE 0x0008
271
272#define MPT2SAS_REQ_SAS_CNTRL 0x0010
273 263
274/** 264/**
275 * struct _sas_device - attached device information 265 * struct _sas_device - attached device information
@@ -287,7 +277,7 @@ struct _internal_cmd {
287 * @id: target id 277 * @id: target id
288 * @channel: target channel 278 * @channel: target channel
289 * @slot: number number 279 * @slot: number number
290 * @hidden_raid_component: set to 1 when this is a raid member 280 * @phy: phy identifier provided in sas device page 0
291 * @responding: used in _scsih_sas_device_mark_responding 281 * @responding: used in _scsih_sas_device_mark_responding
292 */ 282 */
293struct _sas_device { 283struct _sas_device {
@@ -305,9 +295,8 @@ struct _sas_device {
305 int id; 295 int id;
306 int channel; 296 int channel;
307 u16 slot; 297 u16 slot;
308 u8 hidden_raid_component; 298 u8 phy;
309 u8 responding; 299 u8 responding;
310 u16 state;
311}; 300};
312 301
313/** 302/**
@@ -323,6 +312,7 @@ struct _sas_device {
323 * @device_info: bitfield provides detailed info about the hidden components 312 * @device_info: bitfield provides detailed info about the hidden components
324 * @num_pds: number of hidden raid components 313 * @num_pds: number of hidden raid components
325 * @responding: used in _scsih_raid_device_mark_responding 314 * @responding: used in _scsih_raid_device_mark_responding
315 * @percent_complete: resync percent complete
326 */ 316 */
327struct _raid_device { 317struct _raid_device {
328 struct list_head list; 318 struct list_head list;
@@ -336,6 +326,7 @@ struct _raid_device {
336 u32 device_info; 326 u32 device_info;
337 u8 num_pds; 327 u8 num_pds;
338 u8 responding; 328 u8 responding;
329 u8 percent_complete;
339}; 330};
340 331
341/** 332/**
@@ -376,6 +367,7 @@ struct _sas_port {
376 * @phy_id: unique phy id 367 * @phy_id: unique phy id
377 * @handle: device handle for this phy 368 * @handle: device handle for this phy
378 * @attached_handle: device handle for attached device 369 * @attached_handle: device handle for attached device
370 * @phy_belongs_to_port: port has been created for this phy
379 */ 371 */
380struct _sas_phy { 372struct _sas_phy {
381 struct list_head port_siblings; 373 struct list_head port_siblings;
@@ -385,6 +377,7 @@ struct _sas_phy {
385 u8 phy_id; 377 u8 phy_id;
386 u16 handle; 378 u16 handle;
387 u16 attached_handle; 379 u16 attached_handle;
380 u8 phy_belongs_to_port;
388}; 381};
389 382
390/** 383/**
@@ -426,6 +419,18 @@ enum reset_type {
426}; 419};
427 420
428/** 421/**
422 * struct chain_tracker - firmware chain tracker
423 * @chain_buffer: chain buffer
424 * @chain_buffer_dma: physical address
425 * @tracker_list: list of free request (ioc->free_chain_list)
426 */
427struct chain_tracker {
428 void *chain_buffer;
429 dma_addr_t chain_buffer_dma;
430 struct list_head tracker_list;
431};
432
433/**
429 * struct request_tracker - firmware request tracker 434 * struct request_tracker - firmware request tracker
430 * @smid: system message id 435 * @smid: system message id
431 * @scmd: scsi request pointer 436 * @scmd: scsi request pointer
@@ -437,6 +442,7 @@ struct request_tracker {
437 u16 smid; 442 u16 smid;
438 struct scsi_cmnd *scmd; 443 struct scsi_cmnd *scmd;
439 u8 cb_idx; 444 u8 cb_idx;
445 struct list_head chain_list;
440 struct list_head tracker_list; 446 struct list_head tracker_list;
441}; 447};
442 448
@@ -464,7 +470,6 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
464 * @pdev: pci pdev object 470 * @pdev: pci pdev object
465 * @chip: memory mapped register space 471 * @chip: memory mapped register space
466 * @chip_phys: physical addrss prior to mapping 472 * @chip_phys: physical addrss prior to mapping
467 * @pio_chip: I/O mapped register space
468 * @logging_level: see mpt2sas_debug.h 473 * @logging_level: see mpt2sas_debug.h
469 * @fwfault_debug: debuging FW timeouts 474 * @fwfault_debug: debuging FW timeouts
470 * @ir_firmware: IR firmware present 475 * @ir_firmware: IR firmware present
@@ -483,8 +488,9 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
483 * @shost_recovery: host reset in progress 488 * @shost_recovery: host reset in progress
484 * @ioc_reset_in_progress_lock: 489 * @ioc_reset_in_progress_lock:
485 * @ioc_link_reset_in_progress: phy/hard reset in progress 490 * @ioc_link_reset_in_progress: phy/hard reset in progress
486 * @ignore_loginfos: ignore loginfos during task managment 491 * @ignore_loginfos: ignore loginfos during task management
487 * @remove_host: flag for when driver unloads, to avoid sending dev resets 492 * @remove_host: flag for when driver unloads, to avoid sending dev resets
493 * @pci_error_recovery: flag to prevent ioc access until slot reset completes
488 * @wait_for_port_enable_to_complete: 494 * @wait_for_port_enable_to_complete:
489 * @msix_enable: flag indicating msix is enabled 495 * @msix_enable: flag indicating msix is enabled
490 * @msix_vector_count: number msix vectors 496 * @msix_vector_count: number msix vectors
@@ -497,6 +503,8 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
497 * @ctl_cb_idx: clt internal commands 503 * @ctl_cb_idx: clt internal commands
498 * @base_cb_idx: base internal commands 504 * @base_cb_idx: base internal commands
499 * @config_cb_idx: base internal commands 505 * @config_cb_idx: base internal commands
506 * @tm_tr_cb_idx : device removal target reset handshake
507 * @tm_tr_volume_cb_idx : volume removal target reset
500 * @base_cmds: 508 * @base_cmds:
501 * @transport_cmds: 509 * @transport_cmds:
502 * @scsih_cmds: 510 * @scsih_cmds:
@@ -525,6 +533,9 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
525 * @sas_device_lock: 533 * @sas_device_lock:
526 * @io_missing_delay: time for IO completed by fw when PDR enabled 534 * @io_missing_delay: time for IO completed by fw when PDR enabled
527 * @device_missing_delay: time for device missing by fw when PDR enabled 535 * @device_missing_delay: time for device missing by fw when PDR enabled
536 * @sas_id : used for setting volume target IDs
537 * @pd_handles : bitmask for PD handles
538 * @pd_handles_sz : size of pd_handle bitmask
528 * @config_page_sz: config page size 539 * @config_page_sz: config page size
529 * @config_page: reserve memory for config page payload 540 * @config_page: reserve memory for config page payload
530 * @config_page_dma: 541 * @config_page_dma:
@@ -577,6 +588,8 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
577 * @reply_post_free_dma: 588 * @reply_post_free_dma:
578 * @reply_post_free_dma_pool: 589 * @reply_post_free_dma_pool:
579 * @reply_post_host_index: head index in the pool where FW completes IO 590 * @reply_post_host_index: head index in the pool where FW completes IO
591 * @delayed_tr_list: target reset link list
592 * @delayed_tr_volume_list: volume target reset link list
580 */ 593 */
581struct MPT2SAS_ADAPTER { 594struct MPT2SAS_ADAPTER {
582 struct list_head list; 595 struct list_head list;
@@ -587,8 +600,7 @@ struct MPT2SAS_ADAPTER {
587 char tmp_string[MPT_STRING_LENGTH]; 600 char tmp_string[MPT_STRING_LENGTH];
588 struct pci_dev *pdev; 601 struct pci_dev *pdev;
589 Mpi2SystemInterfaceRegs_t __iomem *chip; 602 Mpi2SystemInterfaceRegs_t __iomem *chip;
590 unsigned long chip_phys; 603 resource_size_t chip_phys;
591 unsigned long pio_chip;
592 int logging_level; 604 int logging_level;
593 int fwfault_debug; 605 int fwfault_debug;
594 u8 ir_firmware; 606 u8 ir_firmware;
@@ -603,7 +615,6 @@ struct MPT2SAS_ADAPTER {
603 /* fw event handler */ 615 /* fw event handler */
604 char firmware_event_name[20]; 616 char firmware_event_name[20];
605 struct workqueue_struct *firmware_event_thread; 617 struct workqueue_struct *firmware_event_thread;
606 u8 fw_events_off;
607 spinlock_t fw_event_lock; 618 spinlock_t fw_event_lock;
608 struct list_head fw_event_list; 619 struct list_head fw_event_list;
609 620
@@ -611,16 +622,23 @@ struct MPT2SAS_ADAPTER {
611 int aen_event_read_flag; 622 int aen_event_read_flag;
612 u8 broadcast_aen_busy; 623 u8 broadcast_aen_busy;
613 u8 shost_recovery; 624 u8 shost_recovery;
625
626 struct mutex reset_in_progress_mutex;
627 struct completion shost_recovery_done;
614 spinlock_t ioc_reset_in_progress_lock; 628 spinlock_t ioc_reset_in_progress_lock;
615 u8 ioc_link_reset_in_progress; 629 u8 ioc_link_reset_in_progress;
630 int ioc_reset_in_progress_status;
631
616 u8 ignore_loginfos; 632 u8 ignore_loginfos;
617 u8 remove_host; 633 u8 remove_host;
634 u8 pci_error_recovery;
618 u8 wait_for_port_enable_to_complete; 635 u8 wait_for_port_enable_to_complete;
619 636
620 u8 msix_enable; 637 u8 msix_enable;
621 u16 msix_vector_count; 638 u16 msix_vector_count;
622 u32 *msix_table; 639 u32 *msix_table;
623 u32 *msix_table_backup; 640 u32 *msix_table_backup;
641 u32 ioc_reset_count;
624 642
625 /* internal commands, callback index */ 643 /* internal commands, callback index */
626 u8 scsi_io_cb_idx; 644 u8 scsi_io_cb_idx;
@@ -631,6 +649,7 @@ struct MPT2SAS_ADAPTER {
631 u8 base_cb_idx; 649 u8 base_cb_idx;
632 u8 config_cb_idx; 650 u8 config_cb_idx;
633 u8 tm_tr_cb_idx; 651 u8 tm_tr_cb_idx;
652 u8 tm_tr_volume_cb_idx;
634 u8 tm_sas_control_cb_idx; 653 u8 tm_sas_control_cb_idx;
635 struct _internal_cmd base_cmds; 654 struct _internal_cmd base_cmds;
636 struct _internal_cmd transport_cmds; 655 struct _internal_cmd transport_cmds;
@@ -674,6 +693,9 @@ struct MPT2SAS_ADAPTER {
674 u16 device_missing_delay; 693 u16 device_missing_delay;
675 int sas_id; 694 int sas_id;
676 695
696 void *pd_handles;
697 u16 pd_handles_sz;
698
677 /* config page */ 699 /* config page */
678 u16 config_page_sz; 700 u16 config_page_sz;
679 void *config_page; 701 void *config_page;
@@ -688,19 +710,22 @@ struct MPT2SAS_ADAPTER {
688 dma_addr_t request_dma; 710 dma_addr_t request_dma;
689 u32 request_dma_sz; 711 u32 request_dma_sz;
690 struct request_tracker *scsi_lookup; 712 struct request_tracker *scsi_lookup;
691 spinlock_t scsi_lookup_lock; 713 ulong scsi_lookup_pages;
714 spinlock_t scsi_lookup_lock;
692 struct list_head free_list; 715 struct list_head free_list;
693 int pending_io_count; 716 int pending_io_count;
694 wait_queue_head_t reset_wq; 717 wait_queue_head_t reset_wq;
695 718
696 /* chain */ 719 /* chain */
697 u8 *chain; 720 struct chain_tracker *chain_lookup;
698 dma_addr_t chain_dma; 721 struct list_head free_chain_list;
722 struct dma_pool *chain_dma_pool;
723 ulong chain_pages;
699 u16 max_sges_in_main_message; 724 u16 max_sges_in_main_message;
700 u16 max_sges_in_chain_message; 725 u16 max_sges_in_chain_message;
701 u16 chains_needed_per_io; 726 u16 chains_needed_per_io;
702 u16 chain_offset_value_for_main_message; 727 u16 chain_offset_value_for_main_message;
703 u16 chain_depth; 728 u32 chain_depth;
704 729
705 /* hi-priority queue */ 730 /* hi-priority queue */
706 u16 hi_priority_smid; 731 u16 hi_priority_smid;
@@ -727,6 +752,8 @@ struct MPT2SAS_ADAPTER {
727 u16 reply_sz; 752 u16 reply_sz;
728 u8 *reply; 753 u8 *reply;
729 dma_addr_t reply_dma; 754 dma_addr_t reply_dma;
755 u32 reply_dma_max_address;
756 u32 reply_dma_min_address;
730 struct dma_pool *reply_dma_pool; 757 struct dma_pool *reply_dma_pool;
731 758
732 /* reply free queue */ 759 /* reply free queue */
@@ -744,6 +771,7 @@ struct MPT2SAS_ADAPTER {
744 u32 reply_post_host_index; 771 u32 reply_post_host_index;
745 772
746 struct list_head delayed_tr_list; 773 struct list_head delayed_tr_list;
774 struct list_head delayed_tr_volume_list;
747 775
748 /* diag buffer support */ 776 /* diag buffer support */
749 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; 777 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
@@ -754,6 +782,8 @@ struct MPT2SAS_ADAPTER {
754 Mpi2ManufacturingPage10_t manu_pg10; 782 Mpi2ManufacturingPage10_t manu_pg10;
755 u32 product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23]; 783 u32 product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23];
756 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; 784 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
785 u32 ring_buffer_offset;
786 u32 ring_buffer_sz;
757}; 787};
758 788
759typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 789typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
@@ -814,10 +844,13 @@ void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
814/* scsih shared API */ 844/* scsih shared API */
815u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 845u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
816 u32 reply); 846 u32 reply);
817void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, 847int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
818 u8 type, u16 smid_task, ulong timeout); 848 uint channel, uint id, uint lun, u8 type, u16 smid_task,
849 ulong timeout, struct scsi_cmnd *scmd);
819void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 850void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
820void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 851void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
852void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
853void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
821struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, 854struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
822 u16 handle); 855 u16 handle);
823struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER 856struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER
@@ -853,6 +886,8 @@ int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
853 *mpi_reply, Mpi2IOUnitPage1_t *config_page); 886 *mpi_reply, Mpi2IOUnitPage1_t *config_page);
854int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 887int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
855 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); 888 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
889int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
890 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
856int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 891int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
857 *mpi_reply, Mpi2IOCPage8_t *config_page); 892 *mpi_reply, Mpi2IOCPage8_t *config_page);
858int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 893int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 594a389c652..6afd67b324f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -2,7 +2,7 @@
2 * This module provides common API for accessing firmware configuration pages 2 * This module provides common API for accessing firmware configuration pages
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -51,6 +51,7 @@
51#include <linux/workqueue.h> 51#include <linux/workqueue.h>
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/pci.h> 53#include <linux/pci.h>
54#include <linux/slab.h>
54 55
55#include "mpt2sas_base.h" 56#include "mpt2sas_base.h"
56 57
@@ -158,7 +159,7 @@ _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
158 if (!desc) 159 if (!desc)
159 return; 160 return;
160 161
161 printk(MPT2SAS_DEBUG_FMT "%s: %s(%d), action(%d), form(0x%08x), " 162 printk(MPT2SAS_INFO_FMT "%s: %s(%d), action(%d), form(0x%08x), "
162 "smid(%d)\n", ioc->name, calling_function_name, desc, 163 "smid(%d)\n", ioc->name, calling_function_name, desc,
163 mpi_request->Header.PageNumber, mpi_request->Action, 164 mpi_request->Header.PageNumber, mpi_request->Action,
164 le32_to_cpu(mpi_request->PageAddress), smid); 165 le32_to_cpu(mpi_request->PageAddress), smid);
@@ -167,7 +168,7 @@ _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
167 return; 168 return;
168 169
169 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) 170 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
170 printk(MPT2SAS_DEBUG_FMT 171 printk(MPT2SAS_INFO_FMT
171 "\tiocstatus(0x%04x), loginfo(0x%08x)\n", 172 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
172 ioc->name, le16_to_cpu(mpi_reply->IOCStatus), 173 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
173 le32_to_cpu(mpi_reply->IOCLogInfo)); 174 le32_to_cpu(mpi_reply->IOCLogInfo));
@@ -257,7 +258,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
257#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 258#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
258 _config_display_some_debug(ioc, smid, "config_done", mpi_reply); 259 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
259#endif 260#endif
260 ioc->config_cmds.smid = USHORT_MAX; 261 ioc->config_cmds.smid = USHRT_MAX;
261 complete(&ioc->config_cmds.done); 262 complete(&ioc->config_cmds.done);
262 return 1; 263 return 1;
263} 264}
@@ -324,7 +325,9 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
324 if (r != 0) 325 if (r != 0)
325 goto out; 326 goto out;
326 if (mpi_request->Action == 327 if (mpi_request->Action ==
327 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT) { 328 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
329 mpi_request->Action ==
330 MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
328 ioc->base_add_sg_single(&mpi_request->PageBufferSGE, 331 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
329 MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, 332 MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
330 mem.page_dma); 333 mem.page_dma);
@@ -398,7 +401,7 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
398 if (ioc->config_cmds.smid == smid) 401 if (ioc->config_cmds.smid == smid)
399 mpt2sas_base_free_smid(ioc, smid); 402 mpt2sas_base_free_smid(ioc, smid);
400 if ((ioc->shost_recovery) || (ioc->config_cmds.status & 403 if ((ioc->shost_recovery) || (ioc->config_cmds.status &
401 MPT2_CMD_RESET)) 404 MPT2_CMD_RESET) || ioc->pci_error_recovery)
402 goto retry_config; 405 goto retry_config;
403 issue_host_reset = 1; 406 issue_host_reset = 1;
404 r = -EFAULT; 407 r = -EFAULT;
@@ -882,7 +885,7 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
882} 885}
883 886
884/** 887/**
885 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0 888 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
886 * @ioc: per adapter object 889 * @ioc: per adapter object
887 * @mpi_reply: reply mf payload returned from firmware 890 * @mpi_reply: reply mf payload returned from firmware
888 * @config_page: contents of the config page 891 * @config_page: contents of the config page
@@ -907,7 +910,7 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
907 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 910 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
908 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 911 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
909 mpi_request.Header.PageNumber = 1; 912 mpi_request.Header.PageNumber = 1;
910 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 913 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
911 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); 914 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
912 r = _config_request(ioc, &mpi_request, mpi_reply, 915 r = _config_request(ioc, &mpi_request, mpi_reply,
913 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 916 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
@@ -922,6 +925,49 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
922} 925}
923 926
924/** 927/**
928 * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1
929 * @ioc: per adapter object
930 * @mpi_reply: reply mf payload returned from firmware
931 * @config_page: contents of the config page
932 * @sz: size of buffer passed in config_page
933 * Context: sleep.
934 *
935 * Calling function should call config_get_number_hba_phys prior to
936 * this function, so enough memory is allocated for config_page.
937 *
938 * Returns 0 for success, non-zero for failure.
939 */
940int
941mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
942 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
943{
944 Mpi2ConfigRequest_t mpi_request;
945 int r;
946
947 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
948 mpi_request.Function = MPI2_FUNCTION_CONFIG;
949 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
950 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
951 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
952 mpi_request.Header.PageNumber = 1;
953 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
954 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
955 r = _config_request(ioc, &mpi_request, mpi_reply,
956 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
957 if (r)
958 goto out;
959
960 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
961 _config_request(ioc, &mpi_request, mpi_reply,
962 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
963 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
964 r = _config_request(ioc, &mpi_request, mpi_reply,
965 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
966 out:
967 return r;
968}
969
970/**
925 * mpt2sas_config_get_expander_pg0 - obtain expander page 0 971 * mpt2sas_config_get_expander_pg0 - obtain expander page 0
926 * @ioc: per adapter object 972 * @ioc: per adapter object
927 * @mpi_reply: reply mf payload returned from firmware 973 * @mpi_reply: reply mf payload returned from firmware
@@ -1344,12 +1390,12 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1344 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 1390 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1345 goto out; 1391 goto out;
1346 for (i = 0; i < config_page->NumElements; i++) { 1392 for (i = 0; i < config_page->NumElements; i++) {
1347 if ((config_page->ConfigElement[i].ElementFlags & 1393 if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) &
1348 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) != 1394 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
1349 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT) 1395 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
1350 continue; 1396 continue;
1351 if (config_page->ConfigElement[i].PhysDiskDevHandle == 1397 if (le16_to_cpu(config_page->ConfigElement[i].
1352 pd_handle) { 1398 PhysDiskDevHandle) == pd_handle) {
1353 *volume_handle = le16_to_cpu(config_page-> 1399 *volume_handle = le16_to_cpu(config_page->
1354 ConfigElement[i].VolDevHandle); 1400 ConfigElement[i].VolDevHandle);
1355 r = 0; 1401 r = 0;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 84a124f8e21..e92b77af548 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -3,7 +3,7 @@
3 * controllers 3 * controllers
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -51,7 +51,7 @@
51#include <linux/types.h> 51#include <linux/types.h>
52#include <linux/pci.h> 52#include <linux/pci.h>
53#include <linux/delay.h> 53#include <linux/delay.h>
54#include <linux/smp_lock.h> 54#include <linux/mutex.h>
55#include <linux/compat.h> 55#include <linux/compat.h>
56#include <linux/poll.h> 56#include <linux/poll.h>
57 57
@@ -61,6 +61,7 @@
61#include "mpt2sas_base.h" 61#include "mpt2sas_base.h"
62#include "mpt2sas_ctl.h" 62#include "mpt2sas_ctl.h"
63 63
64static DEFINE_MUTEX(_ctl_mutex);
64static struct fasync_struct *async_queue; 65static struct fasync_struct *async_queue;
65static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait); 66static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait);
66 67
@@ -82,6 +83,32 @@ enum block_state {
82 83
83#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 84#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
84/** 85/**
86 * _ctl_sas_device_find_by_handle - sas device search
87 * @ioc: per adapter object
88 * @handle: sas device handle (assigned by firmware)
89 * Context: Calling function should acquire ioc->sas_device_lock
90 *
91 * This searches for sas_device based on sas_address, then return sas_device
92 * object.
93 */
94static struct _sas_device *
95_ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
96{
97 struct _sas_device *sas_device, *r;
98
99 r = NULL;
100 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
101 if (sas_device->handle != handle)
102 continue;
103 r = sas_device;
104 goto out;
105 }
106
107 out:
108 return r;
109}
110
111/**
85 * _ctl_display_some_debug - debug routine 112 * _ctl_display_some_debug - debug routine
86 * @ioc: per adapter object 113 * @ioc: per adapter object
87 * @smid: system request message index 114 * @smid: system request message index
@@ -188,14 +215,14 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
188 if (!desc) 215 if (!desc)
189 return; 216 return;
190 217
191 printk(MPT2SAS_DEBUG_FMT "%s: %s, smid(%d)\n", 218 printk(MPT2SAS_INFO_FMT "%s: %s, smid(%d)\n",
192 ioc->name, calling_function_name, desc, smid); 219 ioc->name, calling_function_name, desc, smid);
193 220
194 if (!mpi_reply) 221 if (!mpi_reply)
195 return; 222 return;
196 223
197 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) 224 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
198 printk(MPT2SAS_DEBUG_FMT 225 printk(MPT2SAS_INFO_FMT
199 "\tiocstatus(0x%04x), loginfo(0x%08x)\n", 226 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
200 ioc->name, le16_to_cpu(mpi_reply->IOCStatus), 227 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
201 le32_to_cpu(mpi_reply->IOCLogInfo)); 228 le32_to_cpu(mpi_reply->IOCLogInfo));
@@ -205,8 +232,24 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
205 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { 232 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
206 Mpi2SCSIIOReply_t *scsi_reply = 233 Mpi2SCSIIOReply_t *scsi_reply =
207 (Mpi2SCSIIOReply_t *)mpi_reply; 234 (Mpi2SCSIIOReply_t *)mpi_reply;
235 struct _sas_device *sas_device = NULL;
236 unsigned long flags;
237
238 spin_lock_irqsave(&ioc->sas_device_lock, flags);
239 sas_device = _ctl_sas_device_find_by_handle(ioc,
240 le16_to_cpu(scsi_reply->DevHandle));
241 if (sas_device) {
242 printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), "
243 "phy(%d)\n", ioc->name, (unsigned long long)
244 sas_device->sas_address, sas_device->phy);
245 printk(MPT2SAS_WARN_FMT
246 "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
247 ioc->name, sas_device->enclosure_logical_id,
248 sas_device->slot);
249 }
250 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
208 if (scsi_reply->SCSIState || scsi_reply->SCSIStatus) 251 if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
209 printk(MPT2SAS_DEBUG_FMT 252 printk(MPT2SAS_INFO_FMT
210 "\tscsi_state(0x%02x), scsi_status" 253 "\tscsi_state(0x%02x), scsi_status"
211 "(0x%02x)\n", ioc->name, 254 "(0x%02x)\n", ioc->name,
212 scsi_reply->SCSIState, 255 scsi_reply->SCSIState,
@@ -233,6 +276,9 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
233 u32 reply) 276 u32 reply)
234{ 277{
235 MPI2DefaultReply_t *mpi_reply; 278 MPI2DefaultReply_t *mpi_reply;
279 Mpi2SCSIIOReply_t *scsiio_reply;
280 const void *sense_data;
281 u32 sz;
236 282
237 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) 283 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
238 return 1; 284 return 1;
@@ -243,6 +289,20 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
243 if (mpi_reply) { 289 if (mpi_reply) {
244 memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); 290 memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
245 ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID; 291 ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID;
292 /* get sense data */
293 if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
294 mpi_reply->Function ==
295 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
296 scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply;
297 if (scsiio_reply->SCSIState &
298 MPI2_SCSI_STATE_AUTOSENSE_VALID) {
299 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
300 le32_to_cpu(scsiio_reply->SenseCount));
301 sense_data = mpt2sas_base_get_sense_buffer(ioc,
302 smid);
303 memcpy(ioc->ctl_cmds.sense, sense_data, sz);
304 }
305 }
246 } 306 }
247#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 307#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
248 _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); 308 _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
@@ -392,7 +452,7 @@ mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
392 452
393 switch (reset_phase) { 453 switch (reset_phase) {
394 case MPT2_IOC_PRE_RESET: 454 case MPT2_IOC_PRE_RESET:
395 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 455 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
396 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); 456 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
397 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { 457 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
398 if (!(ioc->diag_buffer_status[i] & 458 if (!(ioc->diag_buffer_status[i] &
@@ -405,7 +465,7 @@ mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
405 } 465 }
406 break; 466 break;
407 case MPT2_IOC_AFTER_RESET: 467 case MPT2_IOC_AFTER_RESET:
408 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 468 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
409 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); 469 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
410 if (ioc->ctl_cmds.status & MPT2_CMD_PENDING) { 470 if (ioc->ctl_cmds.status & MPT2_CMD_PENDING) {
411 ioc->ctl_cmds.status |= MPT2_CMD_RESET; 471 ioc->ctl_cmds.status |= MPT2_CMD_RESET;
@@ -414,7 +474,7 @@ mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
414 } 474 }
415 break; 475 break;
416 case MPT2_IOC_DONE_RESET: 476 case MPT2_IOC_DONE_RESET:
417 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 477 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
418 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 478 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
419 479
420 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { 480 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
@@ -531,9 +591,9 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
531 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 591 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
532 592
533 if (!found) { 593 if (!found) {
534 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 594 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
535 "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name, 595 "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name,
536 desc, tm_request->DevHandle, lun)); 596 desc, le16_to_cpu(tm_request->DevHandle), lun));
537 tm_reply = ioc->ctl_cmds.reply; 597 tm_reply = ioc->ctl_cmds.reply;
538 tm_reply->DevHandle = tm_request->DevHandle; 598 tm_reply->DevHandle = tm_request->DevHandle;
539 tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 599 tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
@@ -549,9 +609,10 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
549 return 1; 609 return 1;
550 } 610 }
551 611
552 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 612 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
553 "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name, 613 "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name,
554 desc, tm_request->DevHandle, lun, tm_request->TaskMID)); 614 desc, le16_to_cpu(tm_request->DevHandle), lun,
615 le16_to_cpu(tm_request->TaskMID)));
555 return 0; 616 return 0;
556} 617}
557 618
@@ -566,7 +627,7 @@ static long
566_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, 627_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
567 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state) 628 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state)
568{ 629{
569 MPI2RequestHeader_t *mpi_request; 630 MPI2RequestHeader_t *mpi_request = NULL, *request;
570 MPI2DefaultReply_t *mpi_reply; 631 MPI2DefaultReply_t *mpi_reply;
571 u32 ioc_state; 632 u32 ioc_state;
572 u16 ioc_status; 633 u16 ioc_status;
@@ -575,7 +636,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
575 u8 issue_reset; 636 u8 issue_reset;
576 u32 sz; 637 u32 sz;
577 void *psge; 638 void *psge;
578 void *priv_sense = NULL;
579 void *data_out = NULL; 639 void *data_out = NULL;
580 dma_addr_t data_out_dma; 640 dma_addr_t data_out_dma;
581 size_t data_out_sz = 0; 641 size_t data_out_sz = 0;
@@ -620,36 +680,55 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
620 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 680 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
621 ioc->name, __func__); 681 ioc->name, __func__);
622 682
623 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL); 683 mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL);
624 if (!smid) { 684 if (!mpi_request) {
625 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 685 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a memory for "
626 ioc->name, __func__); 686 "mpi_request\n", ioc->name, __func__);
627 ret = -EAGAIN; 687 ret = -ENOMEM;
628 goto out; 688 goto out;
629 } 689 }
630 690
631 ret = 0;
632 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
633 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
634 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
635 ioc->ctl_cmds.smid = smid;
636 data_out_sz = karg.data_out_size;
637 data_in_sz = karg.data_in_size;
638
639 /* copy in request message frame from user */ 691 /* copy in request message frame from user */
640 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { 692 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) {
641 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, 693 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__,
642 __func__); 694 __func__);
643 ret = -EFAULT; 695 ret = -EFAULT;
644 mpt2sas_base_free_smid(ioc, smid);
645 goto out; 696 goto out;
646 } 697 }
647 698
699 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
700 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx);
701 if (!smid) {
702 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
703 ioc->name, __func__);
704 ret = -EAGAIN;
705 goto out;
706 }
707 } else {
708
709 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL);
710 if (!smid) {
711 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
712 ioc->name, __func__);
713 ret = -EAGAIN;
714 goto out;
715 }
716 }
717
718 ret = 0;
719 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
720 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
721 request = mpt2sas_base_get_msg_frame(ioc, smid);
722 memcpy(request, mpi_request, karg.data_sge_offset*4);
723 ioc->ctl_cmds.smid = smid;
724 data_out_sz = karg.data_out_size;
725 data_in_sz = karg.data_in_size;
726
648 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || 727 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
649 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { 728 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
650 if (!mpi_request->FunctionDependent1 || 729 if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
651 mpi_request->FunctionDependent1 > 730 le16_to_cpu(mpi_request->FunctionDependent1) >
652 cpu_to_le16(ioc->facts.MaxDevHandle)) { 731 ioc->facts.MaxDevHandle) {
653 ret = -EINVAL; 732 ret = -EINVAL;
654 mpt2sas_base_free_smid(ioc, smid); 733 mpt2sas_base_free_smid(ioc, smid);
655 goto out; 734 goto out;
@@ -690,7 +769,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
690 } 769 }
691 770
692 /* add scatter gather elements */ 771 /* add scatter gather elements */
693 psge = (void *)mpi_request + (karg.data_sge_offset*4); 772 psge = (void *)request + (karg.data_sge_offset*4);
694 773
695 if (!data_out_sz && !data_in_sz) { 774 if (!data_out_sz && !data_in_sz) {
696 mpt2sas_base_build_zero_len_sge(ioc, psge); 775 mpt2sas_base_build_zero_len_sge(ioc, psge);
@@ -738,19 +817,26 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
738 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: 817 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
739 { 818 {
740 Mpi2SCSIIORequest_t *scsiio_request = 819 Mpi2SCSIIORequest_t *scsiio_request =
741 (Mpi2SCSIIORequest_t *)mpi_request; 820 (Mpi2SCSIIORequest_t *)request;
821 scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
742 scsiio_request->SenseBufferLowAddress = 822 scsiio_request->SenseBufferLowAddress =
743 mpt2sas_base_get_sense_buffer_dma(ioc, smid); 823 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); 824 memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE);
745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE); 825 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
746 mpt2sas_base_put_smid_scsi_io(ioc, smid, 826 mpt2sas_base_put_smid_scsi_io(ioc, smid,
747 le16_to_cpu(mpi_request->FunctionDependent1)); 827 le16_to_cpu(mpi_request->FunctionDependent1));
828 else
829 mpt2sas_base_put_smid_default(ioc, smid);
748 break; 830 break;
749 } 831 }
750 case MPI2_FUNCTION_SCSI_TASK_MGMT: 832 case MPI2_FUNCTION_SCSI_TASK_MGMT:
751 { 833 {
752 Mpi2SCSITaskManagementRequest_t *tm_request = 834 Mpi2SCSITaskManagementRequest_t *tm_request =
753 (Mpi2SCSITaskManagementRequest_t *)mpi_request; 835 (Mpi2SCSITaskManagementRequest_t *)request;
836
837 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
838 "handle(0x%04x), task_type(0x%02x)\n", ioc->name,
839 le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
754 840
755 if (tm_request->TaskType == 841 if (tm_request->TaskType ==
756 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK || 842 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
@@ -762,7 +848,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
762 } 848 }
763 } 849 }
764 850
765 mutex_lock(&ioc->tm_cmds.mutex);
766 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu( 851 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu(
767 tm_request->DevHandle)); 852 tm_request->DevHandle));
768 mpt2sas_base_put_smid_hi_priority(ioc, smid); 853 mpt2sas_base_put_smid_hi_priority(ioc, smid);
@@ -818,7 +903,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
818 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 903 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
819 Mpi2SCSITaskManagementRequest_t *tm_request = 904 Mpi2SCSITaskManagementRequest_t *tm_request =
820 (Mpi2SCSITaskManagementRequest_t *)mpi_request; 905 (Mpi2SCSITaskManagementRequest_t *)mpi_request;
821 mutex_unlock(&ioc->tm_cmds.mutex);
822 mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu( 906 mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu(
823 tm_request->DevHandle)); 907 tm_request->DevHandle));
824 } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH || 908 } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH ||
@@ -845,7 +929,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
845 Mpi2SCSITaskManagementReply_t *tm_reply = 929 Mpi2SCSITaskManagementReply_t *tm_reply =
846 (Mpi2SCSITaskManagementReply_t *)mpi_reply; 930 (Mpi2SCSITaskManagementReply_t *)mpi_reply;
847 931
848 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: " 932 printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
849 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), " 933 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
850 "TerminationCount(0x%08x)\n", ioc->name, 934 "TerminationCount(0x%08x)\n", ioc->name,
851 le16_to_cpu(tm_reply->IOCStatus), 935 le16_to_cpu(tm_reply->IOCStatus),
@@ -881,7 +965,8 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
881 MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == 965 MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==
882 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 966 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
883 sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE); 967 sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE);
884 if (copy_to_user(karg.sense_data_ptr, priv_sense, sz)) { 968 if (copy_to_user(karg.sense_data_ptr,
969 ioc->ctl_cmds.sense, sz)) {
885 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 970 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
886 __LINE__, __func__); 971 __LINE__, __func__);
887 ret = -ENODATA; 972 ret = -ENODATA;
@@ -891,19 +976,19 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
891 976
892 issue_host_reset: 977 issue_host_reset:
893 if (issue_reset) { 978 if (issue_reset) {
979 ret = -ENODATA;
894 if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || 980 if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
895 mpi_request->Function == 981 mpi_request->Function ==
896 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 982 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
897 printk(MPT2SAS_INFO_FMT "issue target reset: handle " 983 printk(MPT2SAS_INFO_FMT "issue target reset: handle "
898 "= (0x%04x)\n", ioc->name, 984 "= (0x%04x)\n", ioc->name,
899 mpi_request->FunctionDependent1); 985 le16_to_cpu(mpi_request->FunctionDependent1));
900 mpt2sas_halt_firmware(ioc); 986 mpt2sas_halt_firmware(ioc);
901 mutex_lock(&ioc->tm_cmds.mutex);
902 mpt2sas_scsih_issue_tm(ioc, 987 mpt2sas_scsih_issue_tm(ioc,
903 mpi_request->FunctionDependent1, 0, 988 le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
904 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10); 989 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10,
990 NULL);
905 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 991 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
906 mutex_unlock(&ioc->tm_cmds.mutex);
907 } else 992 } else
908 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 993 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
909 FORCE_BIG_HAMMER); 994 FORCE_BIG_HAMMER);
@@ -920,6 +1005,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
920 pci_free_consistent(ioc->pdev, data_out_sz, data_out, 1005 pci_free_consistent(ioc->pdev, data_out_sz, data_out,
921 data_out_dma); 1006 data_out_dma);
922 1007
1008 kfree(mpi_request);
923 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 1009 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
924 mutex_unlock(&ioc->ctl_cmds.mutex); 1010 mutex_unlock(&ioc->ctl_cmds.mutex);
925 return ret; 1011 return ret;
@@ -944,7 +1030,7 @@ _ctl_getiocinfo(void __user *arg)
944 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1030 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
945 return -ENODEV; 1031 return -ENODEV;
946 1032
947 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1033 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
948 __func__)); 1034 __func__));
949 1035
950 memset(&karg, 0 , sizeof(karg)); 1036 memset(&karg, 0 , sizeof(karg));
@@ -992,7 +1078,7 @@ _ctl_eventquery(void __user *arg)
992 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1078 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
993 return -ENODEV; 1079 return -ENODEV;
994 1080
995 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1081 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
996 __func__)); 1082 __func__));
997 1083
998 karg.event_entries = MPT2SAS_CTL_EVENT_LOG_SIZE; 1084 karg.event_entries = MPT2SAS_CTL_EVENT_LOG_SIZE;
@@ -1025,7 +1111,7 @@ _ctl_eventenable(void __user *arg)
1025 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1111 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1026 return -ENODEV; 1112 return -ENODEV;
1027 1113
1028 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1114 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1029 __func__)); 1115 __func__));
1030 1116
1031 if (ioc->event_log) 1117 if (ioc->event_log)
@@ -1067,7 +1153,7 @@ _ctl_eventreport(void __user *arg)
1067 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1153 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1068 return -ENODEV; 1154 return -ENODEV;
1069 1155
1070 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1156 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1071 __func__)); 1157 __func__));
1072 1158
1073 number_bytes = karg.hdr.max_data_size - 1159 number_bytes = karg.hdr.max_data_size -
@@ -1112,7 +1198,7 @@ _ctl_do_reset(void __user *arg)
1112 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1198 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1113 return -ENODEV; 1199 return -ENODEV;
1114 1200
1115 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1201 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1116 __func__)); 1202 __func__));
1117 1203
1118 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1204 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
@@ -1213,7 +1299,7 @@ _ctl_btdh_mapping(void __user *arg)
1213 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1299 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1214 return -ENODEV; 1300 return -ENODEV;
1215 1301
1216 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1302 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1217 __func__)); 1303 __func__));
1218 1304
1219 rc = _ctl_btdh_search_sas_device(ioc, &karg); 1305 rc = _ctl_btdh_search_sas_device(ioc, &karg);
@@ -1282,7 +1368,7 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1282 u16 ioc_status; 1368 u16 ioc_status;
1283 u8 issue_reset = 0; 1369 u8 issue_reset = 0;
1284 1370
1285 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1371 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1286 __func__)); 1372 __func__));
1287 1373
1288 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { 1374 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
@@ -1370,9 +1456,10 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1370 mpi_request->VF_ID = 0; /* TODO */ 1456 mpi_request->VF_ID = 0; /* TODO */
1371 mpi_request->VP_ID = 0; 1457 mpi_request->VP_ID = 0;
1372 1458
1373 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), " 1459 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(0x%p), "
1374 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data, 1460 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
1375 (unsigned long long)request_data_dma, mpi_request->BufferLength)); 1461 (unsigned long long)request_data_dma,
1462 le32_to_cpu(mpi_request->BufferLength)));
1376 1463
1377 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++) 1464 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
1378 mpi_request->ProductSpecific[i] = 1465 mpi_request->ProductSpecific[i] =
@@ -1407,10 +1494,10 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1407 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { 1494 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1408 ioc->diag_buffer_status[buffer_type] |= 1495 ioc->diag_buffer_status[buffer_type] |=
1409 MPT2_DIAG_BUFFER_IS_REGISTERED; 1496 MPT2_DIAG_BUFFER_IS_REGISTERED;
1410 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n", 1497 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
1411 ioc->name, __func__)); 1498 ioc->name, __func__));
1412 } else { 1499 } else {
1413 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1500 printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
1414 "log_info(0x%08x)\n", ioc->name, __func__, 1501 "log_info(0x%08x)\n", ioc->name, __func__,
1415 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); 1502 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1416 rc = -EFAULT; 1503 rc = -EFAULT;
@@ -1534,7 +1621,7 @@ _ctl_diag_unregister(void __user *arg)
1534 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1621 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1535 return -ENODEV; 1622 return -ENODEV;
1536 1623
1537 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1624 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1538 __func__)); 1625 __func__));
1539 1626
1540 buffer_type = karg.unique_id & 0x000000ff; 1627 buffer_type = karg.unique_id & 0x000000ff;
@@ -1604,7 +1691,7 @@ _ctl_diag_query(void __user *arg)
1604 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1691 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1605 return -ENODEV; 1692 return -ENODEV;
1606 1693
1607 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1694 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1608 __func__)); 1695 __func__));
1609 1696
1610 karg.application_flags = 0; 1697 karg.application_flags = 0;
@@ -1682,7 +1769,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1682 int rc; 1769 int rc;
1683 unsigned long timeleft; 1770 unsigned long timeleft;
1684 1771
1685 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1772 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1686 __func__)); 1773 __func__));
1687 1774
1688 rc = 0; 1775 rc = 0;
@@ -1690,7 +1777,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1690 1777
1691 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1778 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1692 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1779 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1693 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 1780 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
1694 "skipping due to FAULT state\n", ioc->name, 1781 "skipping due to FAULT state\n", ioc->name,
1695 __func__)); 1782 __func__));
1696 rc = -EAGAIN; 1783 rc = -EAGAIN;
@@ -1752,10 +1839,10 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1752 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { 1839 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1753 ioc->diag_buffer_status[buffer_type] |= 1840 ioc->diag_buffer_status[buffer_type] |=
1754 MPT2_DIAG_BUFFER_IS_RELEASED; 1841 MPT2_DIAG_BUFFER_IS_RELEASED;
1755 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n", 1842 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
1756 ioc->name, __func__)); 1843 ioc->name, __func__));
1757 } else { 1844 } else {
1758 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1845 printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
1759 "log_info(0x%08x)\n", ioc->name, __func__, 1846 "log_info(0x%08x)\n", ioc->name, __func__,
1760 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); 1847 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1761 rc = -EFAULT; 1848 rc = -EFAULT;
@@ -1793,7 +1880,7 @@ _ctl_diag_release(void __user *arg, enum block_state state)
1793 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1880 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1794 return -ENODEV; 1881 return -ENODEV;
1795 1882
1796 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1883 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1797 __func__)); 1884 __func__));
1798 1885
1799 buffer_type = karg.unique_id & 0x000000ff; 1886 buffer_type = karg.unique_id & 0x000000ff;
@@ -1889,7 +1976,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1889 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1976 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1890 return -ENODEV; 1977 return -ENODEV;
1891 1978
1892 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1979 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1893 __func__)); 1980 __func__));
1894 1981
1895 buffer_type = karg.unique_id & 0x000000ff; 1982 buffer_type = karg.unique_id & 0x000000ff;
@@ -1920,7 +2007,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1920 } 2007 }
1921 2008
1922 diag_data = (void *)(request_data + karg.starting_offset); 2009 diag_data = (void *)(request_data + karg.starting_offset);
1923 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(%p), " 2010 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), "
1924 "offset(%d), sz(%d)\n", ioc->name, __func__, 2011 "offset(%d), sz(%d)\n", ioc->name, __func__,
1925 diag_data, karg.starting_offset, karg.bytes_to_read)); 2012 diag_data, karg.starting_offset, karg.bytes_to_read));
1926 2013
@@ -1935,11 +2022,11 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1935 if ((karg.flags & MPT2_FLAGS_REREGISTER) == 0) 2022 if ((karg.flags & MPT2_FLAGS_REREGISTER) == 0)
1936 return 0; 2023 return 0;
1937 2024
1938 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: Reregister " 2025 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: Reregister "
1939 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type)); 2026 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type));
1940 if ((ioc->diag_buffer_status[buffer_type] & 2027 if ((ioc->diag_buffer_status[buffer_type] &
1941 MPT2_DIAG_BUFFER_IS_RELEASED) == 0) { 2028 MPT2_DIAG_BUFFER_IS_RELEASED) == 0) {
1942 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 2029 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
1943 "buffer_type(0x%02x) is still registered\n", ioc->name, 2030 "buffer_type(0x%02x) is still registered\n", ioc->name,
1944 __func__, buffer_type)); 2031 __func__, buffer_type));
1945 return 0; 2032 return 0;
@@ -2013,10 +2100,10 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
2013 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { 2100 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
2014 ioc->diag_buffer_status[buffer_type] |= 2101 ioc->diag_buffer_status[buffer_type] |=
2015 MPT2_DIAG_BUFFER_IS_REGISTERED; 2102 MPT2_DIAG_BUFFER_IS_REGISTERED;
2016 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n", 2103 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
2017 ioc->name, __func__)); 2104 ioc->name, __func__));
2018 } else { 2105 } else {
2019 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 2106 printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
2020 "log_info(0x%08x)\n", ioc->name, __func__, 2107 "log_info(0x%08x)\n", ioc->name, __func__,
2021 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); 2108 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
2022 rc = -EFAULT; 2109 rc = -EFAULT;
@@ -2070,7 +2157,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
2070 !ioc) 2157 !ioc)
2071 return -ENODEV; 2158 return -ENODEV;
2072 2159
2073 if (ioc->shost_recovery) 2160 if (ioc->shost_recovery || ioc->pci_error_recovery)
2074 return -EAGAIN; 2161 return -EAGAIN;
2075 2162
2076 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) { 2163 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
@@ -2133,7 +2220,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
2133 !ioc) 2220 !ioc)
2134 return -ENODEV; 2221 return -ENODEV;
2135 2222
2136 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT 2223 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT
2137 "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); 2224 "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
2138 break; 2225 break;
2139 } 2226 }
@@ -2152,9 +2239,9 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2152{ 2239{
2153 long ret; 2240 long ret;
2154 2241
2155 lock_kernel(); 2242 mutex_lock(&_ctl_mutex);
2156 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); 2243 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
2157 unlock_kernel(); 2244 mutex_unlock(&_ctl_mutex);
2158 return ret; 2245 return ret;
2159} 2246}
2160 2247
@@ -2189,7 +2276,7 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
2189 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc) 2276 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
2190 return -ENODEV; 2277 return -ENODEV;
2191 2278
2192 if (ioc->shost_recovery) 2279 if (ioc->shost_recovery || ioc->pci_error_recovery)
2193 return -EAGAIN; 2280 return -EAGAIN;
2194 2281
2195 memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); 2282 memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
@@ -2202,14 +2289,10 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
2202 karg.data_out_size = karg32.data_out_size; 2289 karg.data_out_size = karg32.data_out_size;
2203 karg.max_sense_bytes = karg32.max_sense_bytes; 2290 karg.max_sense_bytes = karg32.max_sense_bytes;
2204 karg.data_sge_offset = karg32.data_sge_offset; 2291 karg.data_sge_offset = karg32.data_sge_offset;
2205 memcpy(&karg.reply_frame_buf_ptr, &karg32.reply_frame_buf_ptr, 2292 karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr);
2206 sizeof(uint32_t)); 2293 karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr);
2207 memcpy(&karg.data_in_buf_ptr, &karg32.data_in_buf_ptr, 2294 karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr);
2208 sizeof(uint32_t)); 2295 karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr);
2209 memcpy(&karg.data_out_buf_ptr, &karg32.data_out_buf_ptr,
2210 sizeof(uint32_t));
2211 memcpy(&karg.sense_data_ptr, &karg32.sense_data_ptr,
2212 sizeof(uint32_t));
2213 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; 2296 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
2214 return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); 2297 return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state);
2215} 2298}
@@ -2227,12 +2310,12 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
2227{ 2310{
2228 long ret; 2311 long ret;
2229 2312
2230 lock_kernel(); 2313 mutex_lock(&_ctl_mutex);
2231 if (cmd == MPT2COMMAND32) 2314 if (cmd == MPT2COMMAND32)
2232 ret = _ctl_compat_mpt_command(file, cmd, arg); 2315 ret = _ctl_compat_mpt_command(file, cmd, arg);
2233 else 2316 else
2234 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); 2317 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
2235 unlock_kernel(); 2318 mutex_unlock(&_ctl_mutex);
2236 return ret; 2319 return ret;
2237} 2320}
2238#endif 2321#endif
@@ -2337,8 +2420,8 @@ _ctl_version_nvdata_persistent_show(struct device *cdev,
2337 struct Scsi_Host *shost = class_to_shost(cdev); 2420 struct Scsi_Host *shost = class_to_shost(cdev);
2338 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 2421 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2339 2422
2340 return snprintf(buf, PAGE_SIZE, "%02xh\n", 2423 return snprintf(buf, PAGE_SIZE, "%08xh\n",
2341 le16_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word)); 2424 le32_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word));
2342} 2425}
2343static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO, 2426static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
2344 _ctl_version_nvdata_persistent_show, NULL); 2427 _ctl_version_nvdata_persistent_show, NULL);
@@ -2357,8 +2440,8 @@ _ctl_version_nvdata_default_show(struct device *cdev,
2357 struct Scsi_Host *shost = class_to_shost(cdev); 2440 struct Scsi_Host *shost = class_to_shost(cdev);
2358 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 2441 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2359 2442
2360 return snprintf(buf, PAGE_SIZE, "%02xh\n", 2443 return snprintf(buf, PAGE_SIZE, "%08xh\n",
2361 le16_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word)); 2444 le32_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word));
2362} 2445}
2363static DEVICE_ATTR(version_nvdata_default, S_IRUGO, 2446static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
2364 _ctl_version_nvdata_default_show, NULL); 2447 _ctl_version_nvdata_default_show, NULL);
@@ -2578,6 +2661,218 @@ _ctl_fwfault_debug_store(struct device *cdev,
2578static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR, 2661static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
2579 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store); 2662 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
2580 2663
2664
2665/**
2666 * _ctl_ioc_reset_count_show - ioc reset count
2667 * @cdev - pointer to embedded class device
2668 * @buf - the buffer returned
2669 *
2670 * This is firmware queue depth limit
2671 *
2672 * A sysfs 'read-only' shost attribute.
2673 */
2674static ssize_t
2675_ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr,
2676 char *buf)
2677{
2678 struct Scsi_Host *shost = class_to_shost(cdev);
2679 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2680
2681 return snprintf(buf, PAGE_SIZE, "%08d\n", ioc->ioc_reset_count);
2682}
2683static DEVICE_ATTR(ioc_reset_count, S_IRUGO,
2684 _ctl_ioc_reset_count_show, NULL);
2685
2686struct DIAG_BUFFER_START {
2687 u32 Size;
2688 u32 DiagVersion;
2689 u8 BufferType;
2690 u8 Reserved[3];
2691 u32 Reserved1;
2692 u32 Reserved2;
2693 u32 Reserved3;
2694};
2695/**
2696 * _ctl_host_trace_buffer_size_show - host buffer size (trace only)
2697 * @cdev - pointer to embedded class device
2698 * @buf - the buffer returned
2699 *
2700 * A sysfs 'read-only' shost attribute.
2701 */
2702static ssize_t
2703_ctl_host_trace_buffer_size_show(struct device *cdev,
2704 struct device_attribute *attr, char *buf)
2705{
2706 struct Scsi_Host *shost = class_to_shost(cdev);
2707 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2708 u32 size = 0;
2709 struct DIAG_BUFFER_START *request_data;
2710
2711 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {
2712 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2713 "registered\n", ioc->name, __func__);
2714 return 0;
2715 }
2716
2717 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2718 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
2719 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2720 "registered\n", ioc->name, __func__);
2721 return 0;
2722 }
2723
2724 request_data = (struct DIAG_BUFFER_START *)
2725 ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE];
2726 if ((le32_to_cpu(request_data->DiagVersion) == 0x00000000 ||
2727 le32_to_cpu(request_data->DiagVersion) == 0x01000000) &&
2728 le32_to_cpu(request_data->Reserved3) == 0x4742444c)
2729 size = le32_to_cpu(request_data->Size);
2730
2731 ioc->ring_buffer_sz = size;
2732 return snprintf(buf, PAGE_SIZE, "%d\n", size);
2733}
2734static DEVICE_ATTR(host_trace_buffer_size, S_IRUGO,
2735 _ctl_host_trace_buffer_size_show, NULL);
2736
2737/**
2738 * _ctl_host_trace_buffer_show - firmware ring buffer (trace only)
2739 * @cdev - pointer to embedded class device
2740 * @buf - the buffer returned
2741 *
2742 * A sysfs 'read/write' shost attribute.
2743 *
2744 * You will only be able to read 4k bytes of ring buffer at a time.
2745 * In order to read beyond 4k bytes, you will have to write out the
2746 * offset to the same attribute, it will move the pointer.
2747 */
2748static ssize_t
2749_ctl_host_trace_buffer_show(struct device *cdev, struct device_attribute *attr,
2750 char *buf)
2751{
2752 struct Scsi_Host *shost = class_to_shost(cdev);
2753 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2754 void *request_data;
2755 u32 size;
2756
2757 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {
2758 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2759 "registered\n", ioc->name, __func__);
2760 return 0;
2761 }
2762
2763 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2764 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
2765 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2766 "registered\n", ioc->name, __func__);
2767 return 0;
2768 }
2769
2770 if (ioc->ring_buffer_offset > ioc->ring_buffer_sz)
2771 return 0;
2772
2773 size = ioc->ring_buffer_sz - ioc->ring_buffer_offset;
2774 size = (size > PAGE_SIZE) ? PAGE_SIZE : size;
2775 request_data = ioc->diag_buffer[0] + ioc->ring_buffer_offset;
2776 memcpy(buf, request_data, size);
2777 return size;
2778}
2779
2780static ssize_t
2781_ctl_host_trace_buffer_store(struct device *cdev, struct device_attribute *attr,
2782 const char *buf, size_t count)
2783{
2784 struct Scsi_Host *shost = class_to_shost(cdev);
2785 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2786 int val = 0;
2787
2788 if (sscanf(buf, "%d", &val) != 1)
2789 return -EINVAL;
2790
2791 ioc->ring_buffer_offset = val;
2792 return strlen(buf);
2793}
2794static DEVICE_ATTR(host_trace_buffer, S_IRUGO | S_IWUSR,
2795 _ctl_host_trace_buffer_show, _ctl_host_trace_buffer_store);
2796
2797/*****************************************/
2798
2799/**
2800 * _ctl_host_trace_buffer_enable_show - firmware ring buffer (trace only)
2801 * @cdev - pointer to embedded class device
2802 * @buf - the buffer returned
2803 *
2804 * A sysfs 'read/write' shost attribute.
2805 *
2806 * This is a mechnism to post/release host_trace_buffers
2807 */
2808static ssize_t
2809_ctl_host_trace_buffer_enable_show(struct device *cdev,
2810 struct device_attribute *attr, char *buf)
2811{
2812 struct Scsi_Host *shost = class_to_shost(cdev);
2813 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2814
2815 if ((!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) ||
2816 ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2817 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0))
2818 return snprintf(buf, PAGE_SIZE, "off\n");
2819 else if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2820 MPT2_DIAG_BUFFER_IS_RELEASED))
2821 return snprintf(buf, PAGE_SIZE, "release\n");
2822 else
2823 return snprintf(buf, PAGE_SIZE, "post\n");
2824}
2825
2826static ssize_t
2827_ctl_host_trace_buffer_enable_store(struct device *cdev,
2828 struct device_attribute *attr, const char *buf, size_t count)
2829{
2830 struct Scsi_Host *shost = class_to_shost(cdev);
2831 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2832 char str[10] = "";
2833 struct mpt2_diag_register diag_register;
2834 u8 issue_reset = 0;
2835
2836 if (sscanf(buf, "%s", str) != 1)
2837 return -EINVAL;
2838
2839 if (!strcmp(str, "post")) {
2840 /* exit out if host buffers are already posted */
2841 if ((ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) &&
2842 (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2843 MPT2_DIAG_BUFFER_IS_REGISTERED) &&
2844 ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2845 MPT2_DIAG_BUFFER_IS_RELEASED) == 0))
2846 goto out;
2847 memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
2848 printk(MPT2SAS_INFO_FMT "posting host trace buffers\n",
2849 ioc->name);
2850 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
2851 diag_register.requested_buffer_size = (1024 * 1024);
2852 diag_register.unique_id = 0x7075900;
2853 ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0;
2854 _ctl_diag_register_2(ioc, &diag_register);
2855 } else if (!strcmp(str, "release")) {
2856 /* exit out if host buffers are already released */
2857 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE])
2858 goto out;
2859 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2860 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0)
2861 goto out;
2862 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2863 MPT2_DIAG_BUFFER_IS_RELEASED))
2864 goto out;
2865 printk(MPT2SAS_INFO_FMT "releasing host trace buffer\n",
2866 ioc->name);
2867 _ctl_send_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, &issue_reset);
2868 }
2869
2870 out:
2871 return strlen(buf);
2872}
2873static DEVICE_ATTR(host_trace_buffer_enable, S_IRUGO | S_IWUSR,
2874 _ctl_host_trace_buffer_enable_show, _ctl_host_trace_buffer_enable_store);
2875
2581struct device_attribute *mpt2sas_host_attrs[] = { 2876struct device_attribute *mpt2sas_host_attrs[] = {
2582 &dev_attr_version_fw, 2877 &dev_attr_version_fw,
2583 &dev_attr_version_bios, 2878 &dev_attr_version_bios,
@@ -2594,6 +2889,10 @@ struct device_attribute *mpt2sas_host_attrs[] = {
2594 &dev_attr_fwfault_debug, 2889 &dev_attr_fwfault_debug,
2595 &dev_attr_fw_queue_depth, 2890 &dev_attr_fw_queue_depth,
2596 &dev_attr_host_sas_address, 2891 &dev_attr_host_sas_address,
2892 &dev_attr_ioc_reset_count,
2893 &dev_attr_host_trace_buffer_size,
2894 &dev_attr_host_trace_buffer,
2895 &dev_attr_host_trace_buffer_enable,
2597 NULL, 2896 NULL,
2598}; 2897};
2599 2898
@@ -2654,6 +2953,7 @@ static const struct file_operations ctl_fops = {
2654#ifdef CONFIG_COMPAT 2953#ifdef CONFIG_COMPAT
2655 .compat_ioctl = _ctl_ioctl_compat, 2954 .compat_ioctl = _ctl_ioctl_compat,
2656#endif 2955#endif
2956 .llseek = noop_llseek,
2657}; 2957};
2658 2958
2659static struct miscdevice ctl_dev = { 2959static struct miscdevice ctl_dev = {
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 8a5eeb1a5c8..69916e46e04 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -3,7 +3,7 @@
3 * controllers 3 * controllers
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h 5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h
index 5308a25cb30..3dcddfeb6f4 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_debug.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h
@@ -2,7 +2,7 @@
2 * Logging Support for MPT (Message Passing Technology) based controllers 2 * Logging Support for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index efabea1a3ce..eda347c5797 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2,7 +2,7 @@
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers 2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -52,6 +52,9 @@
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/pci.h> 53#include <linux/pci.h>
54#include <linux/interrupt.h> 54#include <linux/interrupt.h>
55#include <linux/aer.h>
56#include <linux/raid_class.h>
57#include <linux/slab.h>
55 58
56#include "mpt2sas_base.h" 59#include "mpt2sas_base.h"
57 60
@@ -67,6 +70,8 @@ static void _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
67 struct _sas_node *sas_expander); 70 struct _sas_node *sas_expander);
68static void _firmware_event_work(struct work_struct *work); 71static void _firmware_event_work(struct work_struct *work);
69 72
73static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
74
70/* global parameters */ 75/* global parameters */
71LIST_HEAD(mpt2sas_ioc_list); 76LIST_HEAD(mpt2sas_ioc_list);
72 77
@@ -81,6 +86,7 @@ static u8 config_cb_idx = -1;
81static int mpt_ids; 86static int mpt_ids;
82 87
83static u8 tm_tr_cb_idx = -1 ; 88static u8 tm_tr_cb_idx = -1 ;
89static u8 tm_tr_volume_cb_idx = -1 ;
84static u8 tm_sas_control_cb_idx = -1; 90static u8 tm_sas_control_cb_idx = -1;
85 91
86/* command line options */ 92/* command line options */
@@ -107,14 +113,16 @@ struct sense_info {
107}; 113};
108 114
109 115
116#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
117
110/** 118/**
111 * struct fw_event_work - firmware event struct 119 * struct fw_event_work - firmware event struct
112 * @list: link list framework 120 * @list: link list framework
113 * @work: work object (ioc->fault_reset_work_q) 121 * @work: work object (ioc->fault_reset_work_q)
122 * @cancel_pending_work: flag set during reset handling
114 * @ioc: per adapter object 123 * @ioc: per adapter object
115 * @VF_ID: virtual function id 124 * @VF_ID: virtual function id
116 * @VP_ID: virtual port id 125 * @VP_ID: virtual port id
117 * @host_reset_handling: handling events during host reset
118 * @ignore: flag meaning this event has been marked to ignore 126 * @ignore: flag meaning this event has been marked to ignore
119 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h 127 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
120 * @event_data: reply event data payload follows 128 * @event_data: reply event data payload follows
@@ -123,16 +131,19 @@ struct sense_info {
123 */ 131 */
124struct fw_event_work { 132struct fw_event_work {
125 struct list_head list; 133 struct list_head list;
126 struct work_struct work; 134 u8 cancel_pending_work;
135 struct delayed_work delayed_work;
127 struct MPT2SAS_ADAPTER *ioc; 136 struct MPT2SAS_ADAPTER *ioc;
128 u8 VF_ID; 137 u8 VF_ID;
129 u8 VP_ID; 138 u8 VP_ID;
130 u8 host_reset_handling;
131 u8 ignore; 139 u8 ignore;
132 u16 event; 140 u16 event;
133 void *event_data; 141 void *event_data;
134}; 142};
135 143
144/* raid transport support */
145static struct raid_template *mpt2sas_raid_template;
146
136/** 147/**
137 * struct _scsi_io_transfer - scsi io transfer 148 * struct _scsi_io_transfer - scsi io transfer
138 * @handle: sas device handle (assigned by firmware) 149 * @handle: sas device handle (assigned by firmware)
@@ -215,9 +226,12 @@ static struct pci_device_id scsih_pci_table[] = {
215 PCI_ANY_ID, PCI_ANY_ID }, 226 PCI_ANY_ID, PCI_ANY_ID },
216 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6, 227 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
217 PCI_ANY_ID, PCI_ANY_ID }, 228 PCI_ANY_ID, PCI_ANY_ID },
218 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7, 229 /* Mustang ~ 2308 */
230 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
231 PCI_ANY_ID, PCI_ANY_ID },
232 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
219 PCI_ANY_ID, PCI_ANY_ID }, 233 PCI_ANY_ID, PCI_ANY_ID },
220 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8, 234 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
221 PCI_ANY_ID, PCI_ANY_ID }, 235 PCI_ANY_ID, PCI_ANY_ID },
222 {0} /* Terminating entry */ 236 {0} /* Terminating entry */
223}; 237};
@@ -424,7 +438,7 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
424 (ioc->bios_pg2.ReqBootDeviceForm & 438 (ioc->bios_pg2.ReqBootDeviceForm &
425 MPI2_BIOSPAGE2_FORM_MASK), 439 MPI2_BIOSPAGE2_FORM_MASK),
426 &ioc->bios_pg2.RequestedBootDevice)) { 440 &ioc->bios_pg2.RequestedBootDevice)) {
427 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT 441 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
428 "%s: req_boot_device(0x%016llx)\n", 442 "%s: req_boot_device(0x%016llx)\n",
429 ioc->name, __func__, 443 ioc->name, __func__,
430 (unsigned long long)sas_address)); 444 (unsigned long long)sas_address));
@@ -439,7 +453,7 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
439 (ioc->bios_pg2.ReqAltBootDeviceForm & 453 (ioc->bios_pg2.ReqAltBootDeviceForm &
440 MPI2_BIOSPAGE2_FORM_MASK), 454 MPI2_BIOSPAGE2_FORM_MASK),
441 &ioc->bios_pg2.RequestedAltBootDevice)) { 455 &ioc->bios_pg2.RequestedAltBootDevice)) {
442 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT 456 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
443 "%s: req_alt_boot_device(0x%016llx)\n", 457 "%s: req_alt_boot_device(0x%016llx)\n",
444 ioc->name, __func__, 458 ioc->name, __func__,
445 (unsigned long long)sas_address)); 459 (unsigned long long)sas_address));
@@ -454,7 +468,7 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
454 (ioc->bios_pg2.CurrentBootDeviceForm & 468 (ioc->bios_pg2.CurrentBootDeviceForm &
455 MPI2_BIOSPAGE2_FORM_MASK), 469 MPI2_BIOSPAGE2_FORM_MASK),
456 &ioc->bios_pg2.CurrentBootDevice)) { 470 &ioc->bios_pg2.CurrentBootDevice)) {
457 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT 471 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
458 "%s: current_boot_device(0x%016llx)\n", 472 "%s: current_boot_device(0x%016llx)\n",
459 ioc->name, __func__, 473 ioc->name, __func__,
460 (unsigned long long)sas_address)); 474 (unsigned long long)sas_address));
@@ -477,27 +491,17 @@ struct _sas_device *
477mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc, 491mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
478 u64 sas_address) 492 u64 sas_address)
479{ 493{
480 struct _sas_device *sas_device, *r; 494 struct _sas_device *sas_device;
481 495
482 r = NULL; 496 list_for_each_entry(sas_device, &ioc->sas_device_list, list)
483 /* check the sas_device_init_list */ 497 if (sas_device->sas_address == sas_address)
484 list_for_each_entry(sas_device, &ioc->sas_device_init_list, 498 return sas_device;
485 list) {
486 if (sas_device->sas_address != sas_address)
487 continue;
488 r = sas_device;
489 goto out;
490 }
491 499
492 /* then check the sas_device_list */ 500 list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
493 list_for_each_entry(sas_device, &ioc->sas_device_list, list) { 501 if (sas_device->sas_address == sas_address)
494 if (sas_device->sas_address != sas_address) 502 return sas_device;
495 continue; 503
496 r = sas_device; 504 return NULL;
497 goto out;
498 }
499 out:
500 return r;
501} 505}
502 506
503/** 507/**
@@ -512,28 +516,17 @@ mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
512static struct _sas_device * 516static struct _sas_device *
513_scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) 517_scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
514{ 518{
515 struct _sas_device *sas_device, *r; 519 struct _sas_device *sas_device;
516 520
517 r = NULL; 521 list_for_each_entry(sas_device, &ioc->sas_device_list, list)
518 if (ioc->wait_for_port_enable_to_complete) { 522 if (sas_device->handle == handle)
519 list_for_each_entry(sas_device, &ioc->sas_device_init_list, 523 return sas_device;
520 list) {
521 if (sas_device->handle != handle)
522 continue;
523 r = sas_device;
524 goto out;
525 }
526 } else {
527 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
528 if (sas_device->handle != handle)
529 continue;
530 r = sas_device;
531 goto out;
532 }
533 }
534 524
535 out: 525 list_for_each_entry(sas_device, &ioc->sas_device_init_list, list)
536 return r; 526 if (sas_device->handle == handle)
527 return sas_device;
528
529 return NULL;
537} 530}
538 531
539/** 532/**
@@ -550,10 +543,15 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
550{ 543{
551 unsigned long flags; 544 unsigned long flags;
552 545
546 if (!sas_device)
547 return;
548
553 spin_lock_irqsave(&ioc->sas_device_lock, flags); 549 spin_lock_irqsave(&ioc->sas_device_lock, flags);
554 list_del(&sas_device->list); 550 if (mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
555 memset(sas_device, 0, sizeof(struct _sas_device)); 551 sas_device->sas_address)) {
556 kfree(sas_device); 552 list_del(&sas_device->list);
553 kfree(sas_device);
554 }
557 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 555 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
558} 556}
559 557
@@ -571,7 +569,7 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
571{ 569{
572 unsigned long flags; 570 unsigned long flags;
573 571
574 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" 572 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle"
575 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 573 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
576 sas_device->handle, (unsigned long long)sas_device->sas_address)); 574 sas_device->handle, (unsigned long long)sas_device->sas_address));
577 575
@@ -598,7 +596,7 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
598{ 596{
599 unsigned long flags; 597 unsigned long flags;
600 598
601 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" 599 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle"
602 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 600 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
603 sas_device->handle, (unsigned long long)sas_device->sas_address)); 601 sas_device->handle, (unsigned long long)sas_device->sas_address));
604 602
@@ -700,7 +698,7 @@ _scsih_raid_device_add(struct MPT2SAS_ADAPTER *ioc,
700{ 698{
701 unsigned long flags; 699 unsigned long flags;
702 700
703 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle" 701 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle"
704 "(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__, 702 "(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
705 raid_device->handle, (unsigned long long)raid_device->wwid)); 703 raid_device->handle, (unsigned long long)raid_device->wwid));
706 704
@@ -933,31 +931,32 @@ _scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
933} 931}
934 932
935/** 933/**
936 * _scsih_get_chain_buffer_dma - obtain block of chains (dma address) 934 * _scsih_get_chain_buffer_tracker - obtain chain tracker
937 * @ioc: per adapter object 935 * @ioc: per adapter object
938 * @smid: system request message index 936 * @smid: smid associated to an IO request
939 * 937 *
940 * Returns phys pointer to chain buffer. 938 * Returns chain tracker(from ioc->free_chain_list)
941 */ 939 */
942static dma_addr_t 940static struct chain_tracker *
943_scsih_get_chain_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) 941_scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
944{ 942{
945 return ioc->chain_dma + ((smid - 1) * (ioc->request_sz * 943 struct chain_tracker *chain_req;
946 ioc->chains_needed_per_io)); 944 unsigned long flags;
947}
948 945
949/** 946 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
950 * _scsih_get_chain_buffer - obtain block of chains assigned to a mf request 947 if (list_empty(&ioc->free_chain_list)) {
951 * @ioc: per adapter object 948 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
952 * @smid: system request message index 949 printk(MPT2SAS_WARN_FMT "chain buffers not available\n",
953 * 950 ioc->name);
954 * Returns virt pointer to chain buffer. 951 return NULL;
955 */ 952 }
956static void * 953 chain_req = list_entry(ioc->free_chain_list.next,
957_scsih_get_chain_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid) 954 struct chain_tracker, tracker_list);
958{ 955 list_del_init(&chain_req->tracker_list);
959 return (void *)(ioc->chain + ((smid - 1) * (ioc->request_sz * 956 list_add_tail(&chain_req->tracker_list,
960 ioc->chains_needed_per_io))); 957 &ioc->scsi_lookup[smid - 1].chain_list);
958 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
959 return chain_req;
961} 960}
962 961
963/** 962/**
@@ -983,11 +982,12 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
983 u32 chain_offset; 982 u32 chain_offset;
984 u32 chain_length; 983 u32 chain_length;
985 u32 chain_flags; 984 u32 chain_flags;
986 u32 sges_left; 985 int sges_left;
987 u32 sges_in_segment; 986 u32 sges_in_segment;
988 u32 sgl_flags; 987 u32 sgl_flags;
989 u32 sgl_flags_last_element; 988 u32 sgl_flags_last_element;
990 u32 sgl_flags_end_buffer; 989 u32 sgl_flags_end_buffer;
990 struct chain_tracker *chain_req;
991 991
992 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 992 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
993 993
@@ -1004,7 +1004,7 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1004 1004
1005 sg_scmd = scsi_sglist(scmd); 1005 sg_scmd = scsi_sglist(scmd);
1006 sges_left = scsi_dma_map(scmd); 1006 sges_left = scsi_dma_map(scmd);
1007 if (!sges_left) { 1007 if (sges_left < 0) {
1008 sdev_printk(KERN_ERR, scmd->device, "pci_map_sg" 1008 sdev_printk(KERN_ERR, scmd->device, "pci_map_sg"
1009 " failed: request for %d bytes!\n", scsi_bufflen(scmd)); 1009 " failed: request for %d bytes!\n", scsi_bufflen(scmd));
1010 return -ENOMEM; 1010 return -ENOMEM;
@@ -1035,8 +1035,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1035 1035
1036 /* initializing the chain flags and pointers */ 1036 /* initializing the chain flags and pointers */
1037 chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT; 1037 chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
1038 chain = _scsih_get_chain_buffer(ioc, smid); 1038 chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
1039 chain_dma = _scsih_get_chain_buffer_dma(ioc, smid); 1039 if (!chain_req)
1040 return -1;
1041 chain = chain_req->chain_buffer;
1042 chain_dma = chain_req->chain_buffer_dma;
1040 do { 1043 do {
1041 sges_in_segment = (sges_left <= 1044 sges_in_segment = (sges_left <=
1042 ioc->max_sges_in_chain_message) ? sges_left : 1045 ioc->max_sges_in_chain_message) ? sges_left :
@@ -1072,8 +1075,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1072 sges_in_segment--; 1075 sges_in_segment--;
1073 } 1076 }
1074 1077
1075 chain_dma += ioc->request_sz; 1078 chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
1076 chain += ioc->request_sz; 1079 if (!chain_req)
1080 return -1;
1081 chain = chain_req->chain_buffer;
1082 chain_dma = chain_req->chain_buffer_dma;
1077 } while (1); 1083 } while (1);
1078 1084
1079 1085
@@ -1096,28 +1102,24 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
1096} 1102}
1097 1103
1098/** 1104/**
1099 * _scsih_change_queue_depth - setting device queue depth 1105 * _scsih_adjust_queue_depth - setting device queue depth
1100 * @sdev: scsi device struct 1106 * @sdev: scsi device struct
1101 * @qdepth: requested queue depth 1107 * @qdepth: requested queue depth
1102 * @reason: calling context
1103 * 1108 *
1104 * Returns queue depth. 1109 *
1110 * Returns nothing
1105 */ 1111 */
1106static int 1112static void
1107_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) 1113_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
1108{ 1114{
1109 struct Scsi_Host *shost = sdev->host; 1115 struct Scsi_Host *shost = sdev->host;
1110 int max_depth; 1116 int max_depth;
1111 int tag_type;
1112 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 1117 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1113 struct MPT2SAS_DEVICE *sas_device_priv_data; 1118 struct MPT2SAS_DEVICE *sas_device_priv_data;
1114 struct MPT2SAS_TARGET *sas_target_priv_data; 1119 struct MPT2SAS_TARGET *sas_target_priv_data;
1115 struct _sas_device *sas_device; 1120 struct _sas_device *sas_device;
1116 unsigned long flags; 1121 unsigned long flags;
1117 1122
1118 if (reason != SCSI_QDEPTH_DEFAULT)
1119 return -EOPNOTSUPP;
1120
1121 max_depth = shost->can_queue; 1123 max_depth = shost->can_queue;
1122 1124
1123 /* limit max device queue for SATA to 32 */ 1125 /* limit max device queue for SATA to 32 */
@@ -1143,8 +1145,27 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
1143 max_depth = 1; 1145 max_depth = 1;
1144 if (qdepth > max_depth) 1146 if (qdepth > max_depth)
1145 qdepth = max_depth; 1147 qdepth = max_depth;
1146 tag_type = (qdepth == 1) ? 0 : MSG_SIMPLE_TAG; 1148 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
1147 scsi_adjust_queue_depth(sdev, tag_type, qdepth); 1149}
1150
1151/**
1152 * _scsih_change_queue_depth - setting device queue depth
1153 * @sdev: scsi device struct
1154 * @qdepth: requested queue depth
1155 * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP
1156 * (see include/scsi/scsi_host.h for definition)
1157 *
1158 * Returns queue depth.
1159 */
1160static int
1161_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
1162{
1163 if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP)
1164 _scsih_adjust_queue_depth(sdev, qdepth);
1165 else if (reason == SCSI_QDEPTH_QFULL)
1166 scsi_track_queue_full(sdev, qdepth);
1167 else
1168 return -EOPNOTSUPP;
1148 1169
1149 if (sdev->inquiry_len > 7) 1170 if (sdev->inquiry_len > 7)
1150 sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " 1171 sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), "
@@ -1231,7 +1252,7 @@ _scsih_target_alloc(struct scsi_target *starget)
1231 sas_device->starget = starget; 1252 sas_device->starget = starget;
1232 sas_device->id = starget->id; 1253 sas_device->id = starget->id;
1233 sas_device->channel = starget->channel; 1254 sas_device->channel = starget->channel;
1234 if (sas_device->hidden_raid_component) 1255 if (test_bit(sas_device->handle, ioc->pd_handles))
1235 sas_target_priv_data->flags |= 1256 sas_target_priv_data->flags |=
1236 MPT_TARGET_FLAGS_RAID_COMPONENT; 1257 MPT_TARGET_FLAGS_RAID_COMPONENT;
1237 } 1258 }
@@ -1305,7 +1326,6 @@ _scsih_slave_alloc(struct scsi_device *sdev)
1305 struct MPT2SAS_DEVICE *sas_device_priv_data; 1326 struct MPT2SAS_DEVICE *sas_device_priv_data;
1306 struct scsi_target *starget; 1327 struct scsi_target *starget;
1307 struct _raid_device *raid_device; 1328 struct _raid_device *raid_device;
1308 struct _sas_device *sas_device;
1309 unsigned long flags; 1329 unsigned long flags;
1310 1330
1311 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); 1331 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
@@ -1332,21 +1352,8 @@ _scsih_slave_alloc(struct scsi_device *sdev)
1332 if (raid_device) 1352 if (raid_device)
1333 raid_device->sdev = sdev; /* raid is single lun */ 1353 raid_device->sdev = sdev; /* raid is single lun */
1334 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1354 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1335 } else {
1336 /* set TLR bit for SSP devices */
1337 if (!(ioc->facts.IOCCapabilities &
1338 MPI2_IOCFACTS_CAPABILITY_TLR))
1339 goto out;
1340 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1341 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1342 sas_device_priv_data->sas_target->sas_address);
1343 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1344 if (sas_device && sas_device->device_info &
1345 MPI2_SAS_DEVICE_INFO_SSP_TARGET)
1346 sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON;
1347 } 1355 }
1348 1356
1349 out:
1350 return 0; 1357 return 0;
1351} 1358}
1352 1359
@@ -1404,7 +1411,7 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1404 } 1411 }
1405 1412
1406 flags = le16_to_cpu(sas_device_pg0.Flags); 1413 flags = le16_to_cpu(sas_device_pg0.Flags);
1407 device_info = le16_to_cpu(sas_device_pg0.DeviceInfo); 1414 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
1408 1415
1409 sdev_printk(KERN_INFO, sdev, 1416 sdev_printk(KERN_INFO, sdev,
1410 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), " 1417 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), "
@@ -1419,6 +1426,140 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1419} 1426}
1420 1427
1421/** 1428/**
1429 * _scsih_is_raid - return boolean indicating device is raid volume
1430 * @dev the device struct object
1431 */
1432static int
1433_scsih_is_raid(struct device *dev)
1434{
1435 struct scsi_device *sdev = to_scsi_device(dev);
1436
1437 return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
1438}
1439
1440/**
1441 * _scsih_get_resync - get raid volume resync percent complete
1442 * @dev the device struct object
1443 */
1444static void
1445_scsih_get_resync(struct device *dev)
1446{
1447 struct scsi_device *sdev = to_scsi_device(dev);
1448 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1449 static struct _raid_device *raid_device;
1450 unsigned long flags;
1451 Mpi2RaidVolPage0_t vol_pg0;
1452 Mpi2ConfigReply_t mpi_reply;
1453 u32 volume_status_flags;
1454 u8 percent_complete = 0;
1455
1456 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1457 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1458 sdev->channel);
1459 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1460
1461 if (!raid_device)
1462 goto out;
1463
1464 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1465 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1466 sizeof(Mpi2RaidVolPage0_t))) {
1467 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1468 ioc->name, __FILE__, __LINE__, __func__);
1469 goto out;
1470 }
1471
1472 volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1473 if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)
1474 percent_complete = raid_device->percent_complete;
1475 out:
1476 raid_set_resync(mpt2sas_raid_template, dev, percent_complete);
1477}
1478
1479/**
1480 * _scsih_get_state - get raid volume level
1481 * @dev the device struct object
1482 */
1483static void
1484_scsih_get_state(struct device *dev)
1485{
1486 struct scsi_device *sdev = to_scsi_device(dev);
1487 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1488 static struct _raid_device *raid_device;
1489 unsigned long flags;
1490 Mpi2RaidVolPage0_t vol_pg0;
1491 Mpi2ConfigReply_t mpi_reply;
1492 u32 volstate;
1493 enum raid_state state = RAID_STATE_UNKNOWN;
1494
1495 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1496 raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id,
1497 sdev->channel);
1498 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1499
1500 if (!raid_device)
1501 goto out;
1502
1503 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
1504 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle,
1505 sizeof(Mpi2RaidVolPage0_t))) {
1506 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1507 ioc->name, __FILE__, __LINE__, __func__);
1508 goto out;
1509 }
1510
1511 volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags);
1512 if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
1513 state = RAID_STATE_RESYNCING;
1514 goto out;
1515 }
1516
1517 switch (vol_pg0.VolumeState) {
1518 case MPI2_RAID_VOL_STATE_OPTIMAL:
1519 case MPI2_RAID_VOL_STATE_ONLINE:
1520 state = RAID_STATE_ACTIVE;
1521 break;
1522 case MPI2_RAID_VOL_STATE_DEGRADED:
1523 state = RAID_STATE_DEGRADED;
1524 break;
1525 case MPI2_RAID_VOL_STATE_FAILED:
1526 case MPI2_RAID_VOL_STATE_MISSING:
1527 state = RAID_STATE_OFFLINE;
1528 break;
1529 }
1530 out:
1531 raid_set_state(mpt2sas_raid_template, dev, state);
1532}
1533
1534/**
1535 * _scsih_set_level - set raid level
1536 * @sdev: scsi device struct
1537 * @raid_device: raid_device object
1538 */
1539static void
1540_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1541{
1542 enum raid_level level = RAID_LEVEL_UNKNOWN;
1543
1544 switch (raid_device->volume_type) {
1545 case MPI2_RAID_VOL_TYPE_RAID0:
1546 level = RAID_LEVEL_0;
1547 break;
1548 case MPI2_RAID_VOL_TYPE_RAID10:
1549 level = RAID_LEVEL_10;
1550 break;
1551 case MPI2_RAID_VOL_TYPE_RAID1E:
1552 level = RAID_LEVEL_1E;
1553 break;
1554 case MPI2_RAID_VOL_TYPE_RAID1:
1555 level = RAID_LEVEL_1;
1556 break;
1557 }
1558
1559 raid_set_level(mpt2sas_raid_template, &sdev->sdev_gendev, level);
1560}
1561
1562/**
1422 * _scsih_get_volume_capabilities - volume capabilities 1563 * _scsih_get_volume_capabilities - volume capabilities
1423 * @ioc: per adapter object 1564 * @ioc: per adapter object
1424 * @sas_device: the raid_device object 1565 * @sas_device: the raid_device object
@@ -1479,6 +1620,32 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1479} 1620}
1480 1621
1481/** 1622/**
1623 * _scsih_enable_tlr - setting TLR flags
1624 * @ioc: per adapter object
1625 * @sdev: scsi device struct
1626 *
1627 * Enabling Transaction Layer Retries for tape devices when
1628 * vpd page 0x90 is present
1629 *
1630 */
1631static void
1632_scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev)
1633{
1634 /* only for TAPE */
1635 if (sdev->type != TYPE_TAPE)
1636 return;
1637
1638 if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR))
1639 return;
1640
1641 sas_enable_tlr(sdev);
1642 sdev_printk(KERN_INFO, sdev, "TLR %s\n",
1643 sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled");
1644 return;
1645
1646}
1647
1648/**
1482 * _scsih_slave_configure - device configure routine. 1649 * _scsih_slave_configure - device configure routine.
1483 * @sdev: scsi device struct 1650 * @sdev: scsi device struct
1484 * 1651 *
@@ -1574,6 +1741,8 @@ _scsih_slave_configure(struct scsi_device *sdev)
1574 (unsigned long long)raid_device->wwid, 1741 (unsigned long long)raid_device->wwid,
1575 raid_device->num_pds, ds); 1742 raid_device->num_pds, ds);
1576 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 1743 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1744 /* raid transport support */
1745 _scsih_set_level(sdev, raid_device);
1577 return 0; 1746 return 0;
1578 } 1747 }
1579 1748
@@ -1606,9 +1775,10 @@ _scsih_slave_configure(struct scsi_device *sdev)
1606 } 1775 }
1607 1776
1608 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " 1777 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
1609 "sas_addr(0x%016llx), device_name(0x%016llx)\n", 1778 "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n",
1610 ds, sas_device->handle, 1779 ds, sas_device->handle,
1611 (unsigned long long)sas_device->sas_address, 1780 (unsigned long long)sas_device->sas_address,
1781 sas_device->phy,
1612 (unsigned long long)sas_device->device_name); 1782 (unsigned long long)sas_device->device_name);
1613 sdev_printk(KERN_INFO, sdev, "%s: " 1783 sdev_printk(KERN_INFO, sdev, "%s: "
1614 "enclosure_logical_id(0x%016llx), slot(%d)\n", ds, 1784 "enclosure_logical_id(0x%016llx), slot(%d)\n", ds,
@@ -1621,8 +1791,10 @@ _scsih_slave_configure(struct scsi_device *sdev)
1621 1791
1622 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 1792 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1623 1793
1624 if (ssp_target) 1794 if (ssp_target) {
1625 sas_read_port_mode_page(sdev); 1795 sas_read_port_mode_page(sdev);
1796 _scsih_enable_tlr(ioc, sdev);
1797 }
1626 return 0; 1798 return 0;
1627} 1799}
1628 1800
@@ -1808,65 +1980,79 @@ mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
1808 } 1980 }
1809} 1981}
1810 1982
1983
1811/** 1984/**
1812 * mpt2sas_scsih_issue_tm - main routine for sending tm requests 1985 * mpt2sas_scsih_issue_tm - main routine for sending tm requests
1813 * @ioc: per adapter struct 1986 * @ioc: per adapter struct
1814 * @device_handle: device handle 1987 * @device_handle: device handle
1988 * @channel: the channel assigned by the OS
1989 * @id: the id assigned by the OS
1815 * @lun: lun number 1990 * @lun: lun number
1816 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) 1991 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
1817 * @smid_task: smid assigned to the task 1992 * @smid_task: smid assigned to the task
1818 * @timeout: timeout in seconds 1993 * @timeout: timeout in seconds
1819 * Context: The calling function needs to acquire the tm_cmds.mutex 1994 * Context: user
1820 * 1995 *
1821 * A generic API for sending task management requests to firmware. 1996 * A generic API for sending task management requests to firmware.
1822 * 1997 *
1823 * The ioc->tm_cmds.status flag should be MPT2_CMD_NOT_USED before calling
1824 * this API.
1825 *
1826 * The callback index is set inside `ioc->tm_cb_idx`. 1998 * The callback index is set inside `ioc->tm_cb_idx`.
1827 * 1999 *
1828 * Return nothing. 2000 * Return SUCCESS or FAILED.
1829 */ 2001 */
1830void 2002int
1831mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, 2003mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel,
1832 u8 type, u16 smid_task, ulong timeout) 2004 uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
2005 struct scsi_cmnd *scmd)
1833{ 2006{
1834 Mpi2SCSITaskManagementRequest_t *mpi_request; 2007 Mpi2SCSITaskManagementRequest_t *mpi_request;
1835 Mpi2SCSITaskManagementReply_t *mpi_reply; 2008 Mpi2SCSITaskManagementReply_t *mpi_reply;
1836 u16 smid = 0; 2009 u16 smid = 0;
1837 u32 ioc_state; 2010 u32 ioc_state;
1838 unsigned long timeleft; 2011 unsigned long timeleft;
2012 struct scsi_cmnd *scmd_lookup;
2013 int rc;
1839 2014
2015 mutex_lock(&ioc->tm_cmds.mutex);
1840 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) { 2016 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1841 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n", 2017 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
1842 __func__, ioc->name); 2018 __func__, ioc->name);
1843 return; 2019 rc = FAILED;
2020 goto err_out;
1844 } 2021 }
1845 2022
1846 if (ioc->shost_recovery) { 2023 if (ioc->shost_recovery || ioc->remove_host ||
2024 ioc->pci_error_recovery) {
1847 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 2025 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1848 __func__, ioc->name); 2026 __func__, ioc->name);
1849 return; 2027 rc = FAILED;
2028 goto err_out;
1850 } 2029 }
1851 2030
1852 ioc_state = mpt2sas_base_get_iocstate(ioc, 0); 2031 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
1853 if (ioc_state & MPI2_DOORBELL_USED) { 2032 if (ioc_state & MPI2_DOORBELL_USED) {
1854 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell " 2033 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "unexpected doorbell "
1855 "active!\n", ioc->name)); 2034 "active!\n", ioc->name));
1856 goto issue_host_reset; 2035 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2036 FORCE_BIG_HAMMER);
2037 rc = SUCCESS;
2038 goto err_out;
1857 } 2039 }
1858 2040
1859 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 2041 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
1860 mpt2sas_base_fault_info(ioc, ioc_state & 2042 mpt2sas_base_fault_info(ioc, ioc_state &
1861 MPI2_DOORBELL_DATA_MASK); 2043 MPI2_DOORBELL_DATA_MASK);
1862 goto issue_host_reset; 2044 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2045 FORCE_BIG_HAMMER);
2046 rc = SUCCESS;
2047 goto err_out;
1863 } 2048 }
1864 2049
1865 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx); 2050 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
1866 if (!smid) { 2051 if (!smid) {
1867 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 2052 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1868 ioc->name, __func__); 2053 ioc->name, __func__);
1869 return; 2054 rc = FAILED;
2055 goto err_out;
1870 } 2056 }
1871 2057
1872 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x)," 2058 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
@@ -1880,21 +2066,24 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1880 mpi_request->DevHandle = cpu_to_le16(handle); 2066 mpi_request->DevHandle = cpu_to_le16(handle);
1881 mpi_request->TaskType = type; 2067 mpi_request->TaskType = type;
1882 mpi_request->TaskMID = cpu_to_le16(smid_task); 2068 mpi_request->TaskMID = cpu_to_le16(smid_task);
1883 mpi_request->VP_ID = 0; /* TODO */
1884 mpi_request->VF_ID = 0;
1885 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); 2069 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
1886 mpt2sas_scsih_set_tm_flag(ioc, handle); 2070 mpt2sas_scsih_set_tm_flag(ioc, handle);
1887 init_completion(&ioc->tm_cmds.done); 2071 init_completion(&ioc->tm_cmds.done);
1888 mpt2sas_base_put_smid_hi_priority(ioc, smid); 2072 mpt2sas_base_put_smid_hi_priority(ioc, smid);
1889 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); 2073 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
1890 mpt2sas_scsih_clear_tm_flag(ioc, handle);
1891 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) { 2074 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
1892 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 2075 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1893 ioc->name, __func__); 2076 ioc->name, __func__);
1894 _debug_dump_mf(mpi_request, 2077 _debug_dump_mf(mpi_request,
1895 sizeof(Mpi2SCSITaskManagementRequest_t)/4); 2078 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
1896 if (!(ioc->tm_cmds.status & MPT2_CMD_RESET)) 2079 if (!(ioc->tm_cmds.status & MPT2_CMD_RESET)) {
1897 goto issue_host_reset; 2080 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2081 FORCE_BIG_HAMMER);
2082 rc = SUCCESS;
2083 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2084 mpt2sas_scsih_clear_tm_flag(ioc, handle);
2085 goto err_out;
2086 }
1898 } 2087 }
1899 2088
1900 if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) { 2089 if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) {
@@ -1904,17 +2093,113 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1904 ioc->name, le16_to_cpu(mpi_reply->IOCStatus), 2093 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
1905 le32_to_cpu(mpi_reply->IOCLogInfo), 2094 le32_to_cpu(mpi_reply->IOCLogInfo),
1906 le32_to_cpu(mpi_reply->TerminationCount))); 2095 le32_to_cpu(mpi_reply->TerminationCount)));
1907 if (ioc->logging_level & MPT_DEBUG_TM) 2096 if (ioc->logging_level & MPT_DEBUG_TM) {
1908 _scsih_response_code(ioc, mpi_reply->ResponseCode); 2097 _scsih_response_code(ioc, mpi_reply->ResponseCode);
2098 if (mpi_reply->IOCStatus)
2099 _debug_dump_mf(mpi_request,
2100 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
2101 }
2102 }
2103
2104 /* sanity check:
2105 * Check to see the commands were terminated.
2106 * This is only needed for eh callbacks, hence the scmd check.
2107 */
2108 rc = FAILED;
2109 if (scmd == NULL)
2110 goto bypass_sanity_checks;
2111 switch (type) {
2112 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2113 scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task);
2114 if (scmd_lookup && (scmd_lookup->serial_number ==
2115 scmd->serial_number))
2116 rc = FAILED;
2117 else
2118 rc = SUCCESS;
2119 break;
2120
2121 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2122 if (_scsih_scsi_lookup_find_by_target(ioc, id, channel))
2123 rc = FAILED;
2124 else
2125 rc = SUCCESS;
2126 break;
2127
2128 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
2129 if (_scsih_scsi_lookup_find_by_lun(ioc, id, lun, channel))
2130 rc = FAILED;
2131 else
2132 rc = SUCCESS;
2133 break;
2134 }
2135
2136 bypass_sanity_checks:
2137
2138 mpt2sas_scsih_clear_tm_flag(ioc, handle);
2139 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2140 mutex_unlock(&ioc->tm_cmds.mutex);
2141
2142 return rc;
2143
2144 err_out:
2145 mutex_unlock(&ioc->tm_cmds.mutex);
2146 return rc;
2147}
2148
2149/**
2150 * _scsih_tm_display_info - displays info about the device
2151 * @ioc: per adapter struct
2152 * @scmd: pointer to scsi command object
2153 *
2154 * Called by task management callback handlers.
2155 */
2156static void
2157_scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
2158{
2159 struct scsi_target *starget = scmd->device->sdev_target;
2160 struct MPT2SAS_TARGET *priv_target = starget->hostdata;
2161 struct _sas_device *sas_device = NULL;
2162 unsigned long flags;
2163
2164 if (!priv_target)
2165 return;
2166
2167 scsi_print_command(scmd);
2168 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
2169 starget_printk(KERN_INFO, starget, "volume handle(0x%04x), "
2170 "volume wwid(0x%016llx)\n",
2171 priv_target->handle,
2172 (unsigned long long)priv_target->sas_address);
2173 } else {
2174 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2175 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
2176 priv_target->sas_address);
2177 if (sas_device) {
2178 if (priv_target->flags &
2179 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2180 starget_printk(KERN_INFO, starget,
2181 "volume handle(0x%04x), "
2182 "volume wwid(0x%016llx)\n",
2183 sas_device->volume_handle,
2184 (unsigned long long)sas_device->volume_wwid);
2185 }
2186 starget_printk(KERN_INFO, starget,
2187 "handle(0x%04x), sas_address(0x%016llx), phy(%d)\n",
2188 sas_device->handle,
2189 (unsigned long long)sas_device->sas_address,
2190 sas_device->phy);
2191 starget_printk(KERN_INFO, starget,
2192 "enclosure_logical_id(0x%016llx), slot(%d)\n",
2193 (unsigned long long)sas_device->enclosure_logical_id,
2194 sas_device->slot);
2195 }
2196 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1909 } 2197 }
1910 return;
1911 issue_host_reset:
1912 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, FORCE_BIG_HAMMER);
1913} 2198}
1914 2199
1915/** 2200/**
1916 * _scsih_abort - eh threads main abort routine 2201 * _scsih_abort - eh threads main abort routine
1917 * @sdev: scsi device struct 2202 * @scmd: pointer to scsi command object
1918 * 2203 *
1919 * Returns SUCCESS if command aborted else FAILED 2204 * Returns SUCCESS if command aborted else FAILED
1920 */ 2205 */
@@ -1926,16 +2211,15 @@ _scsih_abort(struct scsi_cmnd *scmd)
1926 u16 smid; 2211 u16 smid;
1927 u16 handle; 2212 u16 handle;
1928 int r; 2213 int r;
1929 struct scsi_cmnd *scmd_lookup;
1930 2214
1931 printk(MPT2SAS_INFO_FMT "attempting task abort! scmd(%p)\n", 2215 sdev_printk(KERN_INFO, scmd->device, "attempting task abort! "
1932 ioc->name, scmd); 2216 "scmd(%p)\n", scmd);
1933 scsi_print_command(scmd); 2217 _scsih_tm_display_info(ioc, scmd);
1934 2218
1935 sas_device_priv_data = scmd->device->hostdata; 2219 sas_device_priv_data = scmd->device->hostdata;
1936 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { 2220 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
1937 printk(MPT2SAS_INFO_FMT "device been deleted! scmd(%p)\n", 2221 sdev_printk(KERN_INFO, scmd->device, "device been deleted! "
1938 ioc->name, scmd); 2222 "scmd(%p)\n", scmd);
1939 scmd->result = DID_NO_CONNECT << 16; 2223 scmd->result = DID_NO_CONNECT << 16;
1940 scmd->scsi_done(scmd); 2224 scmd->scsi_done(scmd);
1941 r = SUCCESS; 2225 r = SUCCESS;
@@ -1961,29 +2245,20 @@ _scsih_abort(struct scsi_cmnd *scmd)
1961 2245
1962 mpt2sas_halt_firmware(ioc); 2246 mpt2sas_halt_firmware(ioc);
1963 2247
1964 mutex_lock(&ioc->tm_cmds.mutex);
1965 handle = sas_device_priv_data->sas_target->handle; 2248 handle = sas_device_priv_data->sas_target->handle;
1966 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun, 2249 r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
1967 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30); 2250 scmd->device->id, scmd->device->lun,
1968 2251 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, scmd);
1969 /* sanity check - see whether command actually completed */
1970 scmd_lookup = _scsih_scsi_lookup_get(ioc, smid);
1971 if (scmd_lookup && (scmd_lookup->serial_number == scmd->serial_number))
1972 r = FAILED;
1973 else
1974 r = SUCCESS;
1975 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
1976 mutex_unlock(&ioc->tm_cmds.mutex);
1977 2252
1978 out: 2253 out:
1979 printk(MPT2SAS_INFO_FMT "task abort: %s scmd(%p)\n", 2254 sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
1980 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); 2255 ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
1981 return r; 2256 return r;
1982} 2257}
1983 2258
1984/** 2259/**
1985 * _scsih_dev_reset - eh threads main device reset routine 2260 * _scsih_dev_reset - eh threads main device reset routine
1986 * @sdev: scsi device struct 2261 * @scmd: pointer to scsi command object
1987 * 2262 *
1988 * Returns SUCCESS if command aborted else FAILED 2263 * Returns SUCCESS if command aborted else FAILED
1989 */ 2264 */
@@ -1997,14 +2272,16 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
1997 u16 handle; 2272 u16 handle;
1998 int r; 2273 int r;
1999 2274
2000 printk(MPT2SAS_INFO_FMT "attempting device reset! scmd(%p)\n", 2275 struct scsi_target *starget = scmd->device->sdev_target;
2001 ioc->name, scmd); 2276
2002 scsi_print_command(scmd); 2277 starget_printk(KERN_INFO, starget, "attempting device reset! "
2278 "scmd(%p)\n", scmd);
2279 _scsih_tm_display_info(ioc, scmd);
2003 2280
2004 sas_device_priv_data = scmd->device->hostdata; 2281 sas_device_priv_data = scmd->device->hostdata;
2005 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { 2282 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2006 printk(MPT2SAS_INFO_FMT "device been deleted! scmd(%p)\n", 2283 starget_printk(KERN_INFO, starget, "device been deleted! "
2007 ioc->name, scmd); 2284 "scmd(%p)\n", scmd);
2008 scmd->result = DID_NO_CONNECT << 16; 2285 scmd->result = DID_NO_CONNECT << 16;
2009 scmd->scsi_done(scmd); 2286 scmd->scsi_done(scmd);
2010 r = SUCCESS; 2287 r = SUCCESS;
@@ -2030,32 +2307,19 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
2030 goto out; 2307 goto out;
2031 } 2308 }
2032 2309
2033 mutex_lock(&ioc->tm_cmds.mutex); 2310 r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
2034 mpt2sas_scsih_issue_tm(ioc, handle, 0, 2311 scmd->device->id, scmd->device->lun,
2035 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, scmd->device->lun, 2312 MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, scmd);
2036 30);
2037
2038 /*
2039 * sanity check see whether all commands to this device been
2040 * completed
2041 */
2042 if (_scsih_scsi_lookup_find_by_lun(ioc, scmd->device->id,
2043 scmd->device->lun, scmd->device->channel))
2044 r = FAILED;
2045 else
2046 r = SUCCESS;
2047 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2048 mutex_unlock(&ioc->tm_cmds.mutex);
2049 2313
2050 out: 2314 out:
2051 printk(MPT2SAS_INFO_FMT "device reset: %s scmd(%p)\n", 2315 sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
2052 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); 2316 ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2053 return r; 2317 return r;
2054} 2318}
2055 2319
2056/** 2320/**
2057 * _scsih_target_reset - eh threads main target reset routine 2321 * _scsih_target_reset - eh threads main target reset routine
2058 * @sdev: scsi device struct 2322 * @scmd: pointer to scsi command object
2059 * 2323 *
2060 * Returns SUCCESS if command aborted else FAILED 2324 * Returns SUCCESS if command aborted else FAILED
2061 */ 2325 */
@@ -2068,15 +2332,16 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
2068 unsigned long flags; 2332 unsigned long flags;
2069 u16 handle; 2333 u16 handle;
2070 int r; 2334 int r;
2335 struct scsi_target *starget = scmd->device->sdev_target;
2071 2336
2072 printk(MPT2SAS_INFO_FMT "attempting target reset! scmd(%p)\n", 2337 starget_printk(KERN_INFO, starget, "attempting target reset! "
2073 ioc->name, scmd); 2338 "scmd(%p)\n", scmd);
2074 scsi_print_command(scmd); 2339 _scsih_tm_display_info(ioc, scmd);
2075 2340
2076 sas_device_priv_data = scmd->device->hostdata; 2341 sas_device_priv_data = scmd->device->hostdata;
2077 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { 2342 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2078 printk(MPT2SAS_INFO_FMT "target been deleted! scmd(%p)\n", 2343 starget_printk(KERN_INFO, starget, "target been deleted! "
2079 ioc->name, scmd); 2344 "scmd(%p)\n", scmd);
2080 scmd->result = DID_NO_CONNECT << 16; 2345 scmd->result = DID_NO_CONNECT << 16;
2081 scmd->scsi_done(scmd); 2346 scmd->scsi_done(scmd);
2082 r = SUCCESS; 2347 r = SUCCESS;
@@ -2102,31 +2367,19 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
2102 goto out; 2367 goto out;
2103 } 2368 }
2104 2369
2105 mutex_lock(&ioc->tm_cmds.mutex); 2370 r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
2106 mpt2sas_scsih_issue_tm(ioc, handle, 0, 2371 scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
2107 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30); 2372 30, scmd);
2108
2109 /*
2110 * sanity check see whether all commands to this target been
2111 * completed
2112 */
2113 if (_scsih_scsi_lookup_find_by_target(ioc, scmd->device->id,
2114 scmd->device->channel))
2115 r = FAILED;
2116 else
2117 r = SUCCESS;
2118 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
2119 mutex_unlock(&ioc->tm_cmds.mutex);
2120 2373
2121 out: 2374 out:
2122 printk(MPT2SAS_INFO_FMT "target reset: %s scmd(%p)\n", 2375 starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
2123 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); 2376 ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
2124 return r; 2377 return r;
2125} 2378}
2126 2379
2127/** 2380/**
2128 * _scsih_host_reset - eh threads main host reset routine 2381 * _scsih_host_reset - eh threads main host reset routine
2129 * @sdev: scsi device struct 2382 * @scmd: pointer to scsi command object
2130 * 2383 *
2131 * Returns SUCCESS if command aborted else FAILED 2384 * Returns SUCCESS if command aborted else FAILED
2132 */ 2385 */
@@ -2170,8 +2423,9 @@ _scsih_fw_event_add(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
2170 2423
2171 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2424 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2172 list_add_tail(&fw_event->list, &ioc->fw_event_list); 2425 list_add_tail(&fw_event->list, &ioc->fw_event_list);
2173 INIT_WORK(&fw_event->work, _firmware_event_work); 2426 INIT_DELAYED_WORK(&fw_event->delayed_work, _firmware_event_work);
2174 queue_work(ioc->firmware_event_thread, &fw_event->work); 2427 queue_delayed_work(ioc->firmware_event_thread,
2428 &fw_event->delayed_work, 0);
2175 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2429 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2176} 2430}
2177 2431
@@ -2198,61 +2452,53 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2198 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2452 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2199} 2453}
2200 2454
2455
2201/** 2456/**
2202 * _scsih_fw_event_add - requeue an event 2457 * _scsih_queue_rescan - queue a topology rescan from user context
2203 * @ioc: per adapter object 2458 * @ioc: per adapter object
2204 * @fw_event: object describing the event
2205 * Context: This function will acquire ioc->fw_event_lock.
2206 * 2459 *
2207 * Return nothing. 2460 * Return nothing.
2208 */ 2461 */
2209static void 2462static void
2210_scsih_fw_event_requeue(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work 2463_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
2211 *fw_event, unsigned long delay)
2212{ 2464{
2213 unsigned long flags; 2465 struct fw_event_work *fw_event;
2214 if (ioc->firmware_event_thread == NULL)
2215 return;
2216 2466
2217 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2467 if (ioc->wait_for_port_enable_to_complete)
2218 queue_work(ioc->firmware_event_thread, &fw_event->work); 2468 return;
2219 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2469 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2470 if (!fw_event)
2471 return;
2472 fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
2473 fw_event->ioc = ioc;
2474 _scsih_fw_event_add(ioc, fw_event);
2220} 2475}
2221 2476
2222/** 2477/**
2223 * _scsih_fw_event_off - turn flag off preventing event handling 2478 * _scsih_fw_event_cleanup_queue - cleanup event queue
2224 * @ioc: per adapter object 2479 * @ioc: per adapter object
2225 * 2480 *
2226 * Used to prevent handling of firmware events during adapter reset 2481 * Walk the firmware event queue, either killing timers, or waiting
2227 * driver unload. 2482 * for outstanding events to complete
2228 * 2483 *
2229 * Return nothing. 2484 * Return nothing.
2230 */ 2485 */
2231static void 2486static void
2232_scsih_fw_event_off(struct MPT2SAS_ADAPTER *ioc) 2487_scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc)
2233{ 2488{
2234 unsigned long flags; 2489 struct fw_event_work *fw_event, *next;
2235
2236 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2237 ioc->fw_events_off = 1;
2238 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2239
2240}
2241 2490
2242/** 2491 if (list_empty(&ioc->fw_event_list) ||
2243 * _scsih_fw_event_on - turn flag on allowing firmware event handling 2492 !ioc->firmware_event_thread || in_interrupt())
2244 * @ioc: per adapter object 2493 return;
2245 *
2246 * Returns nothing.
2247 */
2248static void
2249_scsih_fw_event_on(struct MPT2SAS_ADAPTER *ioc)
2250{
2251 unsigned long flags;
2252 2494
2253 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2495 list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
2254 ioc->fw_events_off = 0; 2496 if (cancel_delayed_work(&fw_event->delayed_work)) {
2255 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2497 _scsih_fw_event_free(ioc, fw_event);
2498 continue;
2499 }
2500 fw_event->cancel_pending_work = 1;
2501 }
2256} 2502}
2257 2503
2258/** 2504/**
@@ -2353,9 +2599,9 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
2353 &sas_expander->sas_port_list, port_list) { 2599 &sas_expander->sas_port_list, port_list) {
2354 2600
2355 if (mpt2sas_port->remote_identify.device_type == 2601 if (mpt2sas_port->remote_identify.device_type ==
2356 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || 2602 SAS_EDGE_EXPANDER_DEVICE ||
2357 mpt2sas_port->remote_identify.device_type == 2603 mpt2sas_port->remote_identify.device_type ==
2358 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) { 2604 SAS_FANOUT_EXPANDER_DEVICE) {
2359 2605
2360 spin_lock_irqsave(&ioc->sas_node_lock, flags); 2606 spin_lock_irqsave(&ioc->sas_node_lock, flags);
2361 expander_sibling = 2607 expander_sibling =
@@ -2416,26 +2662,36 @@ static void
2416_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) 2662_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2417{ 2663{
2418 Mpi2SCSITaskManagementRequest_t *mpi_request; 2664 Mpi2SCSITaskManagementRequest_t *mpi_request;
2419 struct MPT2SAS_TARGET *sas_target_priv_data;
2420 u16 smid; 2665 u16 smid;
2421 struct _sas_device *sas_device; 2666 struct _sas_device *sas_device;
2667 struct MPT2SAS_TARGET *sas_target_priv_data;
2422 unsigned long flags; 2668 unsigned long flags;
2423 struct _tr_list *delayed_tr; 2669 struct _tr_list *delayed_tr;
2424 2670
2425 if (ioc->shost_recovery) { 2671 if (ioc->shost_recovery || ioc->remove_host ||
2426 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 2672 ioc->pci_error_recovery) {
2427 __func__, ioc->name); 2673 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2674 "progress!\n", __func__, ioc->name));
2428 return; 2675 return;
2429 } 2676 }
2430 2677
2678 /* if PD, then return */
2679 if (test_bit(handle, ioc->pd_handles))
2680 return;
2681
2431 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2682 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2432 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2683 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2684 if (sas_device && sas_device->starget &&
2685 sas_device->starget->hostdata) {
2686 sas_target_priv_data = sas_device->starget->hostdata;
2687 sas_target_priv_data->deleted = 1;
2688 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2689 "setting delete flag: handle(0x%04x), "
2690 "sas_addr(0x%016llx)\n", ioc->name, handle,
2691 (unsigned long long) sas_device->sas_address));
2692 }
2433 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2693 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2434 2694
2435 /* skip is hidden raid component */
2436 if (sas_device && sas_device->hidden_raid_component)
2437 return;
2438
2439 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 2695 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
2440 if (!smid) { 2696 if (!smid) {
2441 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); 2697 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
@@ -2443,36 +2699,16 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2443 return; 2699 return;
2444 INIT_LIST_HEAD(&delayed_tr->list); 2700 INIT_LIST_HEAD(&delayed_tr->list);
2445 delayed_tr->handle = handle; 2701 delayed_tr->handle = handle;
2446 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; 2702 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
2447 list_add_tail(&delayed_tr->list,
2448 &ioc->delayed_tr_list);
2449 if (sas_device && sas_device->starget) {
2450 dewtprintk(ioc, starget_printk(KERN_INFO,
2451 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2452 "(open)\n", handle));
2453 } else {
2454 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2455 "DELAYED:tr:handle(0x%04x), (open)\n",
2456 ioc->name, handle));
2457 }
2458 return;
2459 }
2460
2461 if (sas_device) {
2462 sas_device->state |= MPTSAS_STATE_TR_SEND;
2463 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2464 if (sas_device->starget && sas_device->starget->hostdata) {
2465 sas_target_priv_data = sas_device->starget->hostdata;
2466 sas_target_priv_data->tm_busy = 1;
2467 dewtprintk(ioc, starget_printk(KERN_INFO,
2468 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2469 handle));
2470 }
2471 } else {
2472 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 2703 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2473 "tr:handle(0x%04x), (open)\n", ioc->name, handle)); 2704 "DELAYED:tr:handle(0x%04x), (open)\n",
2705 ioc->name, handle));
2706 return;
2474 } 2707 }
2475 2708
2709 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
2710 "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
2711 ioc->tm_tr_cb_idx));
2476 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 2712 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2477 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); 2713 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2478 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 2714 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
@@ -2502,36 +2738,112 @@ static u8
2502_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, 2738_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2503 u8 msix_index, u32 reply) 2739 u8 msix_index, u32 reply)
2504{ 2740{
2505 unsigned long flags; 2741#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
2506 u16 handle;
2507 struct _sas_device *sas_device;
2508 Mpi2SasIoUnitControlReply_t *mpi_reply = 2742 Mpi2SasIoUnitControlReply_t *mpi_reply =
2509 mpt2sas_base_get_reply_virt_addr(ioc, reply); 2743 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2744#endif
2745 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2746 "sc_complete:handle(0x%04x), (open) "
2747 "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
2748 ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid,
2749 le16_to_cpu(mpi_reply->IOCStatus),
2750 le32_to_cpu(mpi_reply->IOCLogInfo)));
2751 return 1;
2752}
2510 2753
2511 handle = le16_to_cpu(mpi_reply->DevHandle); 2754/**
2755 * _scsih_tm_tr_volume_send - send target reset request for volumes
2756 * @ioc: per adapter object
2757 * @handle: device handle
2758 * Context: interrupt time.
2759 *
2760 * This is designed to send muliple task management request at the same
2761 * time to the fifo. If the fifo is full, we will append the request,
2762 * and process it in a future completion.
2763 */
2764static void
2765_scsih_tm_tr_volume_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2766{
2767 Mpi2SCSITaskManagementRequest_t *mpi_request;
2768 u16 smid;
2769 struct _tr_list *delayed_tr;
2512 2770
2513 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2771 if (ioc->shost_recovery || ioc->remove_host ||
2514 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2772 ioc->pci_error_recovery) {
2515 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2773 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2774 "progress!\n", __func__, ioc->name));
2775 return;
2776 }
2516 2777
2517 if (sas_device) { 2778 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx);
2518 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE; 2779 if (!smid) {
2519 if (sas_device->starget) 2780 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
2520 dewtprintk(ioc, starget_printk(KERN_INFO, 2781 if (!delayed_tr)
2521 sas_device->starget, 2782 return;
2522 "sc_complete:handle(0x%04x), " 2783 INIT_LIST_HEAD(&delayed_tr->list);
2523 "ioc_status(0x%04x), loginfo(0x%08x)\n", 2784 delayed_tr->handle = handle;
2524 handle, le16_to_cpu(mpi_reply->IOCStatus), 2785 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_volume_list);
2525 le32_to_cpu(mpi_reply->IOCLogInfo)));
2526 } else {
2527 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 2786 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2528 "sc_complete:handle(0x%04x), " 2787 "DELAYED:tr:handle(0x%04x), (open)\n",
2529 "ioc_status(0x%04x), loginfo(0x%08x)\n", 2788 ioc->name, handle));
2530 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus), 2789 return;
2531 le32_to_cpu(mpi_reply->IOCLogInfo)));
2532 } 2790 }
2533 2791
2534 return 1; 2792 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
2793 "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
2794 ioc->tm_tr_volume_cb_idx));
2795 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2796 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2797 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2798 mpi_request->DevHandle = cpu_to_le16(handle);
2799 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2800 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2801}
2802
2803/**
2804 * _scsih_tm_volume_tr_complete - target reset completion
2805 * @ioc: per adapter object
2806 * @smid: system request message index
2807 * @msix_index: MSIX table index supplied by the OS
2808 * @reply: reply message frame(lower 32bit addr)
2809 * Context: interrupt time.
2810 *
2811 * Return 1 meaning mf should be freed from _base_interrupt
2812 * 0 means the mf is freed from this function.
2813 */
2814static u8
2815_scsih_tm_volume_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2816 u8 msix_index, u32 reply)
2817{
2818 u16 handle;
2819 Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
2820 Mpi2SCSITaskManagementReply_t *mpi_reply =
2821 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2822
2823 if (ioc->shost_recovery || ioc->remove_host ||
2824 ioc->pci_error_recovery) {
2825 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2826 "progress!\n", __func__, ioc->name));
2827 return 1;
2828 }
2829
2830 mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid);
2831 handle = le16_to_cpu(mpi_request_tm->DevHandle);
2832 if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
2833 dewtprintk(ioc, printk("spurious interrupt: "
2834 "handle(0x%04x:0x%04x), smid(%d)!!!\n", handle,
2835 le16_to_cpu(mpi_reply->DevHandle), smid));
2836 return 0;
2837 }
2838
2839 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2840 "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
2841 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2842 handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
2843 le32_to_cpu(mpi_reply->IOCLogInfo),
2844 le32_to_cpu(mpi_reply->TerminationCount)));
2845
2846 return _scsih_check_for_pending_tm(ioc, smid);
2535} 2847}
2536 2848
2537/** 2849/**
@@ -2554,87 +2866,93 @@ static u8
2554_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 2866_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2555 u32 reply) 2867 u32 reply)
2556{ 2868{
2557 unsigned long flags;
2558 u16 handle; 2869 u16 handle;
2559 struct _sas_device *sas_device; 2870 Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
2560 Mpi2SCSITaskManagementReply_t *mpi_reply = 2871 Mpi2SCSITaskManagementReply_t *mpi_reply =
2561 mpt2sas_base_get_reply_virt_addr(ioc, reply); 2872 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2562 Mpi2SasIoUnitControlRequest_t *mpi_request; 2873 Mpi2SasIoUnitControlRequest_t *mpi_request;
2563 u16 smid_sas_ctrl; 2874 u16 smid_sas_ctrl;
2564 struct MPT2SAS_TARGET *sas_target_priv_data;
2565 struct _tr_list *delayed_tr;
2566 u8 rc;
2567
2568 handle = le16_to_cpu(mpi_reply->DevHandle);
2569 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2570 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2571 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2572 2875
2573 if (sas_device) { 2876 if (ioc->shost_recovery || ioc->remove_host ||
2574 sas_device->state |= MPTSAS_STATE_TR_COMPLETE; 2877 ioc->pci_error_recovery) {
2575 if (sas_device->starget) { 2878 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2576 dewtprintk(ioc, starget_printk(KERN_INFO, 2879 "progress!\n", __func__, ioc->name));
2577 sas_device->starget, "tr_complete:handle(0x%04x), " 2880 return 1;
2578 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2579 "completed(%d)\n", sas_device->handle,
2580 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2581 "open" : "active",
2582 le16_to_cpu(mpi_reply->IOCStatus),
2583 le32_to_cpu(mpi_reply->IOCLogInfo),
2584 le32_to_cpu(mpi_reply->TerminationCount)));
2585 if (sas_device->starget->hostdata) {
2586 sas_target_priv_data =
2587 sas_device->starget->hostdata;
2588 sas_target_priv_data->tm_busy = 0;
2589 }
2590 }
2591 } else {
2592 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2593 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2594 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2595 handle, le16_to_cpu(mpi_reply->IOCStatus),
2596 le32_to_cpu(mpi_reply->IOCLogInfo),
2597 le32_to_cpu(mpi_reply->TerminationCount)));
2598 } 2881 }
2599 2882
2600 if (!list_empty(&ioc->delayed_tr_list)) { 2883 mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid);
2601 delayed_tr = list_entry(ioc->delayed_tr_list.next, 2884 handle = le16_to_cpu(mpi_request_tm->DevHandle);
2602 struct _tr_list, list); 2885 if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
2603 mpt2sas_base_free_smid(ioc, smid); 2886 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "spurious interrupt: "
2604 if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL) 2887 "handle(0x%04x:0x%04x), smid(%d)!!!\n", ioc->name, handle,
2605 _scsih_tm_tr_send(ioc, delayed_tr->handle); 2888 le16_to_cpu(mpi_reply->DevHandle), smid));
2606 list_del(&delayed_tr->list); 2889 return 0;
2607 kfree(delayed_tr);
2608 rc = 0; /* tells base_interrupt not to free mf */
2609 } else
2610 rc = 1;
2611
2612 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2613 return rc;
2614
2615 if (ioc->shost_recovery) {
2616 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2617 __func__, ioc->name);
2618 return rc;
2619 } 2890 }
2620 2891
2892 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2893 "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
2894 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2895 handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
2896 le32_to_cpu(mpi_reply->IOCLogInfo),
2897 le32_to_cpu(mpi_reply->TerminationCount)));
2898
2621 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); 2899 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
2622 if (!smid_sas_ctrl) { 2900 if (!smid_sas_ctrl) {
2623 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 2901 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2624 ioc->name, __func__); 2902 ioc->name, __func__);
2625 return rc; 2903 return 1;
2626 } 2904 }
2627 2905
2628 if (sas_device) 2906 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sc_send:handle(0x%04x), "
2629 sas_device->state |= MPTSAS_STATE_CNTRL_SEND; 2907 "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid_sas_ctrl,
2630 2908 ioc->tm_sas_control_cb_idx));
2631 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); 2909 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2632 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 2910 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2633 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 2911 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2634 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; 2912 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2635 mpi_request->DevHandle = mpi_reply->DevHandle; 2913 mpi_request->DevHandle = mpi_request_tm->DevHandle;
2636 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2914 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2637 return rc; 2915
2916 return _scsih_check_for_pending_tm(ioc, smid);
2917}
2918
2919/**
2920 * _scsih_check_for_pending_tm - check for pending task management
2921 * @ioc: per adapter object
2922 * @smid: system request message index
2923 *
2924 * This will check delayed target reset list, and feed the
2925 * next reqeust.
2926 *
2927 * Return 1 meaning mf should be freed from _base_interrupt
2928 * 0 means the mf is freed from this function.
2929 */
2930static u8
2931_scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid)
2932{
2933 struct _tr_list *delayed_tr;
2934
2935 if (!list_empty(&ioc->delayed_tr_volume_list)) {
2936 delayed_tr = list_entry(ioc->delayed_tr_volume_list.next,
2937 struct _tr_list, list);
2938 mpt2sas_base_free_smid(ioc, smid);
2939 _scsih_tm_tr_volume_send(ioc, delayed_tr->handle);
2940 list_del(&delayed_tr->list);
2941 kfree(delayed_tr);
2942 return 0;
2943 }
2944
2945 if (!list_empty(&ioc->delayed_tr_list)) {
2946 delayed_tr = list_entry(ioc->delayed_tr_list.next,
2947 struct _tr_list, list);
2948 mpt2sas_base_free_smid(ioc, smid);
2949 _scsih_tm_tr_send(ioc, delayed_tr->handle);
2950 list_del(&delayed_tr->list);
2951 kfree(delayed_tr);
2952 return 0;
2953 }
2954
2955 return 1;
2638} 2956}
2639 2957
2640/** 2958/**
@@ -2707,7 +3025,7 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2707 MPI2_EVENT_SAS_TOPO_ES_RESPONDING) { 3025 MPI2_EVENT_SAS_TOPO_ES_RESPONDING) {
2708 if (le16_to_cpu(local_event_data->ExpanderDevHandle) == 3026 if (le16_to_cpu(local_event_data->ExpanderDevHandle) ==
2709 expander_handle) { 3027 expander_handle) {
2710 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT 3028 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2711 "setting ignoring flag\n", ioc->name)); 3029 "setting ignoring flag\n", ioc->name));
2712 fw_event->ignore = 1; 3030 fw_event->ignore = 1;
2713 } 3031 }
@@ -2717,6 +3035,165 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2717} 3035}
2718 3036
2719/** 3037/**
3038 * _scsih_set_volume_delete_flag - setting volume delete flag
3039 * @ioc: per adapter object
3040 * @handle: device handle
3041 *
3042 * This
3043 * Return nothing.
3044 */
3045static void
3046_scsih_set_volume_delete_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3047{
3048 struct _raid_device *raid_device;
3049 struct MPT2SAS_TARGET *sas_target_priv_data;
3050 unsigned long flags;
3051
3052 spin_lock_irqsave(&ioc->raid_device_lock, flags);
3053 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
3054 if (raid_device && raid_device->starget &&
3055 raid_device->starget->hostdata) {
3056 sas_target_priv_data =
3057 raid_device->starget->hostdata;
3058 sas_target_priv_data->deleted = 1;
3059 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
3060 "setting delete flag: handle(0x%04x), "
3061 "wwid(0x%016llx)\n", ioc->name, handle,
3062 (unsigned long long) raid_device->wwid));
3063 }
3064 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
3065}
3066
3067/**
3068 * _scsih_set_volume_handle_for_tr - set handle for target reset to volume
3069 * @handle: input handle
3070 * @a: handle for volume a
3071 * @b: handle for volume b
3072 *
3073 * IR firmware only supports two raid volumes. The purpose of this
3074 * routine is to set the volume handle in either a or b. When the given
3075 * input handle is non-zero, or when a and b have not been set before.
3076 */
3077static void
3078_scsih_set_volume_handle_for_tr(u16 handle, u16 *a, u16 *b)
3079{
3080 if (!handle || handle == *a || handle == *b)
3081 return;
3082 if (!*a)
3083 *a = handle;
3084 else if (!*b)
3085 *b = handle;
3086}
3087
3088/**
3089 * _scsih_check_ir_config_unhide_events - check for UNHIDE events
3090 * @ioc: per adapter object
3091 * @event_data: the event data payload
3092 * Context: interrupt time.
3093 *
3094 * This routine will send target reset to volume, followed by target
3095 * resets to the PDs. This is called when a PD has been removed, or
3096 * volume has been deleted or removed. When the target reset is sent
3097 * to volume, the PD target resets need to be queued to start upon
3098 * completion of the volume target reset.
3099 *
3100 * Return nothing.
3101 */
3102static void
3103_scsih_check_ir_config_unhide_events(struct MPT2SAS_ADAPTER *ioc,
3104 Mpi2EventDataIrConfigChangeList_t *event_data)
3105{
3106 Mpi2EventIrConfigElement_t *element;
3107 int i;
3108 u16 handle, volume_handle, a, b;
3109 struct _tr_list *delayed_tr;
3110
3111 a = 0;
3112 b = 0;
3113
3114 /* Volume Resets for Deleted or Removed */
3115 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3116 for (i = 0; i < event_data->NumElements; i++, element++) {
3117 if (element->ReasonCode ==
3118 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED ||
3119 element->ReasonCode ==
3120 MPI2_EVENT_IR_CHANGE_RC_REMOVED) {
3121 volume_handle = le16_to_cpu(element->VolDevHandle);
3122 _scsih_set_volume_delete_flag(ioc, volume_handle);
3123 _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
3124 }
3125 }
3126
3127 /* Volume Resets for UNHIDE events */
3128 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3129 for (i = 0; i < event_data->NumElements; i++, element++) {
3130 if (le32_to_cpu(event_data->Flags) &
3131 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
3132 continue;
3133 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_UNHIDE) {
3134 volume_handle = le16_to_cpu(element->VolDevHandle);
3135 _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
3136 }
3137 }
3138
3139 if (a)
3140 _scsih_tm_tr_volume_send(ioc, a);
3141 if (b)
3142 _scsih_tm_tr_volume_send(ioc, b);
3143
3144 /* PD target resets */
3145 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3146 for (i = 0; i < event_data->NumElements; i++, element++) {
3147 if (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_UNHIDE)
3148 continue;
3149 handle = le16_to_cpu(element->PhysDiskDevHandle);
3150 volume_handle = le16_to_cpu(element->VolDevHandle);
3151 clear_bit(handle, ioc->pd_handles);
3152 if (!volume_handle)
3153 _scsih_tm_tr_send(ioc, handle);
3154 else if (volume_handle == a || volume_handle == b) {
3155 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
3156 BUG_ON(!delayed_tr);
3157 INIT_LIST_HEAD(&delayed_tr->list);
3158 delayed_tr->handle = handle;
3159 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
3160 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
3161 "DELAYED:tr:handle(0x%04x), (open)\n", ioc->name,
3162 handle));
3163 } else
3164 _scsih_tm_tr_send(ioc, handle);
3165 }
3166}
3167
3168
3169/**
3170 * _scsih_check_volume_delete_events - set delete flag for volumes
3171 * @ioc: per adapter object
3172 * @event_data: the event data payload
3173 * Context: interrupt time.
3174 *
3175 * This will handle the case when the cable connected to entire volume is
3176 * pulled. We will take care of setting the deleted flag so normal IO will
3177 * not be sent.
3178 *
3179 * Return nothing.
3180 */
3181static void
3182_scsih_check_volume_delete_events(struct MPT2SAS_ADAPTER *ioc,
3183 Mpi2EventDataIrVolume_t *event_data)
3184{
3185 u32 state;
3186
3187 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
3188 return;
3189 state = le32_to_cpu(event_data->NewValue);
3190 if (state == MPI2_RAID_VOL_STATE_MISSING || state ==
3191 MPI2_RAID_VOL_STATE_FAILED)
3192 _scsih_set_volume_delete_flag(ioc,
3193 le16_to_cpu(event_data->VolDevHandle));
3194}
3195
3196/**
2720 * _scsih_flush_running_cmds - completing outstanding commands. 3197 * _scsih_flush_running_cmds - completing outstanding commands.
2721 * @ioc: per adapter object 3198 * @ioc: per adapter object
2722 * 3199 *
@@ -2739,7 +3216,10 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
2739 count++; 3216 count++;
2740 mpt2sas_base_free_smid(ioc, smid); 3217 mpt2sas_base_free_smid(ioc, smid);
2741 scsi_dma_unmap(scmd); 3218 scsi_dma_unmap(scmd);
2742 scmd->result = DID_RESET << 16; 3219 if (ioc->pci_error_recovery)
3220 scmd->result = DID_NO_CONNECT << 16;
3221 else
3222 scmd->result = DID_RESET << 16;
2743 scmd->scsi_done(scmd); 3223 scmd->scsi_done(scmd);
2744 } 3224 }
2745 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "completing %d cmds\n", 3225 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "completing %d cmds\n",
@@ -2762,9 +3242,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2762 unsigned char prot_op = scsi_get_prot_op(scmd); 3242 unsigned char prot_op = scsi_get_prot_op(scmd);
2763 unsigned char prot_type = scsi_get_prot_type(scmd); 3243 unsigned char prot_type = scsi_get_prot_type(scmd);
2764 3244
2765 if (prot_type == SCSI_PROT_DIF_TYPE0 || 3245 if (prot_type == SCSI_PROT_DIF_TYPE0 || prot_op == SCSI_PROT_NORMAL)
2766 prot_type == SCSI_PROT_DIF_TYPE2 ||
2767 prot_op == SCSI_PROT_NORMAL)
2768 return; 3246 return;
2769 3247
2770 if (prot_op == SCSI_PROT_READ_STRIP) 3248 if (prot_op == SCSI_PROT_READ_STRIP)
@@ -2786,7 +3264,13 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
2786 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; 3264 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2787 mpi_request->CDB.EEDP32.PrimaryReferenceTag = 3265 mpi_request->CDB.EEDP32.PrimaryReferenceTag =
2788 cpu_to_be32(scsi_get_lba(scmd)); 3266 cpu_to_be32(scsi_get_lba(scmd));
3267 break;
2789 3268
3269 case SCSI_PROT_DIF_TYPE2:
3270
3271 eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
3272 MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
3273 MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
2790 break; 3274 break;
2791 3275
2792 case SCSI_PROT_DIF_TYPE3: 3276 case SCSI_PROT_DIF_TYPE3:
@@ -2855,7 +3339,7 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
2855 * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full 3339 * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
2856 */ 3340 */
2857static int 3341static int
2858_scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) 3342_scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2859{ 3343{
2860 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); 3344 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2861 struct MPT2SAS_DEVICE *sas_device_priv_data; 3345 struct MPT2SAS_DEVICE *sas_device_priv_data;
@@ -2866,25 +3350,38 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2866 3350
2867 scmd->scsi_done = done; 3351 scmd->scsi_done = done;
2868 sas_device_priv_data = scmd->device->hostdata; 3352 sas_device_priv_data = scmd->device->hostdata;
2869 if (!sas_device_priv_data) { 3353 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
3354 scmd->result = DID_NO_CONNECT << 16;
3355 scmd->scsi_done(scmd);
3356 return 0;
3357 }
3358
3359 if (ioc->pci_error_recovery) {
2870 scmd->result = DID_NO_CONNECT << 16; 3360 scmd->result = DID_NO_CONNECT << 16;
2871 scmd->scsi_done(scmd); 3361 scmd->scsi_done(scmd);
2872 return 0; 3362 return 0;
2873 } 3363 }
2874 3364
2875 sas_target_priv_data = sas_device_priv_data->sas_target; 3365 sas_target_priv_data = sas_device_priv_data->sas_target;
2876 if (!sas_target_priv_data || sas_target_priv_data->handle == 3366 /* invalid device handle */
2877 MPT2SAS_INVALID_DEVICE_HANDLE || sas_target_priv_data->deleted) { 3367 if (sas_target_priv_data->handle == MPT2SAS_INVALID_DEVICE_HANDLE) {
2878 scmd->result = DID_NO_CONNECT << 16; 3368 scmd->result = DID_NO_CONNECT << 16;
2879 scmd->scsi_done(scmd); 3369 scmd->scsi_done(scmd);
2880 return 0; 3370 return 0;
2881 } 3371 }
2882 3372
2883 /* see if we are busy with task managment stuff */ 3373 /* host recovery or link resets sent via IOCTLs */
2884 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy) 3374 if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2885 return SCSI_MLQUEUE_DEVICE_BUSY;
2886 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2887 return SCSI_MLQUEUE_HOST_BUSY; 3375 return SCSI_MLQUEUE_HOST_BUSY;
3376 /* device busy with task management */
3377 else if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
3378 return SCSI_MLQUEUE_DEVICE_BUSY;
3379 /* device has been deleted */
3380 else if (sas_target_priv_data->deleted) {
3381 scmd->result = DID_NO_CONNECT << 16;
3382 scmd->scsi_done(scmd);
3383 return 0;
3384 }
2888 3385
2889 if (scmd->sc_data_direction == DMA_FROM_DEVICE) 3386 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
2890 mpi_control = MPI2_SCSIIO_CONTROL_READ; 3387 mpi_control = MPI2_SCSIIO_CONTROL_READ;
@@ -2908,8 +3405,9 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2908 3405
2909 } else 3406 } else
2910 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 3407 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
2911 3408 /* Make sure Device is not raid volume */
2912 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) 3409 if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
3410 sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
2913 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; 3411 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
2914 3412
2915 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); 3413 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -2921,6 +3419,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2921 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 3419 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2922 memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t)); 3420 memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
2923 _scsih_setup_eedp(scmd, mpi_request); 3421 _scsih_setup_eedp(scmd, mpi_request);
3422 if (scmd->cmd_len == 32)
3423 mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT;
2924 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; 3424 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
2925 if (sas_device_priv_data->sas_target->flags & 3425 if (sas_device_priv_data->sas_target->flags &
2926 MPT_TARGET_FLAGS_RAID_COMPONENT) 3426 MPT_TARGET_FLAGS_RAID_COMPONENT)
@@ -2954,14 +3454,19 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2954 } 3454 }
2955 } 3455 }
2956 3456
2957 mpt2sas_base_put_smid_scsi_io(ioc, smid, 3457 if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST))
2958 sas_device_priv_data->sas_target->handle); 3458 mpt2sas_base_put_smid_scsi_io(ioc, smid,
3459 sas_device_priv_data->sas_target->handle);
3460 else
3461 mpt2sas_base_put_smid_default(ioc, smid);
2959 return 0; 3462 return 0;
2960 3463
2961 out: 3464 out:
2962 return SCSI_MLQUEUE_HOST_BUSY; 3465 return SCSI_MLQUEUE_HOST_BUSY;
2963} 3466}
2964 3467
3468static DEF_SCSI_QCMD(_scsih_qcmd)
3469
2965/** 3470/**
2966 * _scsih_normalize_sense - normalize descriptor and fixed format sense data 3471 * _scsih_normalize_sense - normalize descriptor and fixed format sense data
2967 * @sense_buffer: sense data returned by target 3472 * @sense_buffer: sense data returned by target
@@ -3012,6 +3517,13 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3012 char *desc_scsi_status = NULL; 3517 char *desc_scsi_status = NULL;
3013 char *desc_scsi_state = ioc->tmp_string; 3518 char *desc_scsi_state = ioc->tmp_string;
3014 u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); 3519 u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
3520 struct _sas_device *sas_device = NULL;
3521 unsigned long flags;
3522 struct scsi_target *starget = scmd->device->sdev_target;
3523 struct MPT2SAS_TARGET *priv_target = starget->hostdata;
3524
3525 if (!priv_target)
3526 return;
3015 3527
3016 if (log_info == 0x31170000) 3528 if (log_info == 0x31170000)
3017 return; 3529 return;
@@ -3127,10 +3639,29 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3127 strcat(desc_scsi_state, "autosense valid "); 3639 strcat(desc_scsi_state, "autosense valid ");
3128 3640
3129 scsi_print_command(scmd); 3641 scsi_print_command(scmd);
3130 printk(MPT2SAS_WARN_FMT "\tdev handle(0x%04x), " 3642
3131 "ioc_status(%s)(0x%04x), smid(%d)\n", ioc->name, 3643 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
3132 le16_to_cpu(mpi_reply->DevHandle), desc_ioc_state, 3644 printk(MPT2SAS_WARN_FMT "\tvolume wwid(0x%016llx)\n", ioc->name,
3133 ioc_status, smid); 3645 (unsigned long long)priv_target->sas_address);
3646 } else {
3647 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3648 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
3649 priv_target->sas_address);
3650 if (sas_device) {
3651 printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), "
3652 "phy(%d)\n", ioc->name, sas_device->sas_address,
3653 sas_device->phy);
3654 printk(MPT2SAS_WARN_FMT
3655 "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
3656 ioc->name, sas_device->enclosure_logical_id,
3657 sas_device->slot);
3658 }
3659 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3660 }
3661
3662 printk(MPT2SAS_WARN_FMT "\thandle(0x%04x), ioc_status(%s)(0x%04x), "
3663 "smid(%d)\n", ioc->name, le16_to_cpu(mpi_reply->DevHandle),
3664 desc_ioc_state, ioc_status, smid);
3134 printk(MPT2SAS_WARN_FMT "\trequest_len(%d), underflow(%d), " 3665 printk(MPT2SAS_WARN_FMT "\trequest_len(%d), underflow(%d), "
3135 "resid(%d)\n", ioc->name, scsi_bufflen(scmd), scmd->underflow, 3666 "resid(%d)\n", ioc->name, scsi_bufflen(scmd), scmd->underflow,
3136 scsi_get_resid(scmd)); 3667 scsi_get_resid(scmd));
@@ -3145,8 +3676,8 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3145 struct sense_info data; 3676 struct sense_info data;
3146 _scsih_normalize_sense(scmd->sense_buffer, &data); 3677 _scsih_normalize_sense(scmd->sense_buffer, &data);
3147 printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: " 3678 printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: "
3148 "[0x%02x,0x%02x,0x%02x]\n", ioc->name, data.skey, 3679 "[0x%02x,0x%02x,0x%02x], count(%d)\n", ioc->name, data.skey,
3149 data.asc, data.ascq); 3680 data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
3150 } 3681 }
3151 3682
3152 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 3683 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
@@ -3200,7 +3731,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3200 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 3731 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
3201 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; 3732 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
3202 mpi_request.SlotStatus = 3733 mpi_request.SlotStatus =
3203 MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 3734 cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
3204 mpi_request.DevHandle = cpu_to_le16(handle); 3735 mpi_request.DevHandle = cpu_to_le16(handle);
3205 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; 3736 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
3206 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, 3737 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
@@ -3298,10 +3829,12 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3298 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; 3829 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
3299 if (!sas_device_priv_data->tlr_snoop_check) { 3830 if (!sas_device_priv_data->tlr_snoop_check) {
3300 sas_device_priv_data->tlr_snoop_check++; 3831 sas_device_priv_data->tlr_snoop_check++;
3301 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && 3832 if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
3302 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) 3833 sas_is_tlr_enabled(scmd->device) &&
3303 sas_device_priv_data->flags &= 3834 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
3304 ~MPT_DEVICE_TLR_ON; 3835 sas_disable_tlr(scmd->device);
3836 sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
3837 }
3305 } 3838 }
3306 3839
3307 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); 3840 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -3454,6 +3987,7 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
3454 Mpi2ConfigReply_t mpi_reply; 3987 Mpi2ConfigReply_t mpi_reply;
3455 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; 3988 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3456 u16 attached_handle; 3989 u16 attached_handle;
3990 u8 link_rate;
3457 3991
3458 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT 3992 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
3459 "updating handles for sas_host(0x%016llx)\n", 3993 "updating handles for sas_host(0x%016llx)\n",
@@ -3475,15 +4009,17 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
3475 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 4009 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3476 goto out; 4010 goto out;
3477 for (i = 0; i < ioc->sas_hba.num_phys ; i++) { 4011 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
4012 link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4;
3478 if (i == 0) 4013 if (i == 0)
3479 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> 4014 ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
3480 PhyData[0].ControllerDevHandle); 4015 PhyData[0].ControllerDevHandle);
3481 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; 4016 ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
3482 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. 4017 attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
3483 AttachedDevHandle); 4018 AttachedDevHandle);
4019 if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
4020 link_rate = MPI2_SAS_NEG_LINK_RATE_1_5;
3484 mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, 4021 mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
3485 attached_handle, i, sas_iounit_pg0->PhyData[i]. 4022 attached_handle, i, link_rate);
3486 NegotiatedLinkRate >> 4);
3487 } 4023 }
3488 out: 4024 out:
3489 kfree(sas_iounit_pg0); 4025 kfree(sas_iounit_pg0);
@@ -3663,7 +4199,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3663 if (!handle) 4199 if (!handle)
3664 return -1; 4200 return -1;
3665 4201
3666 if (ioc->shost_recovery) 4202 if (ioc->shost_recovery || ioc->pci_error_recovery)
3667 return -1; 4203 return -1;
3668 4204
3669 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, 4205 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
@@ -3827,14 +4363,14 @@ _scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3827} 4363}
3828 4364
3829/** 4365/**
3830 * _scsih_expander_remove - removing expander object 4366 * mpt2sas_expander_remove - removing expander object
3831 * @ioc: per adapter object 4367 * @ioc: per adapter object
3832 * @sas_address: expander sas_address 4368 * @sas_address: expander sas_address
3833 * 4369 *
3834 * Return nothing. 4370 * Return nothing.
3835 */ 4371 */
3836static void 4372void
3837_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) 4373mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
3838{ 4374{
3839 struct _sas_node *sas_expander; 4375 struct _sas_node *sas_expander;
3840 unsigned long flags; 4376 unsigned long flags;
@@ -3845,11 +4381,144 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
3845 spin_lock_irqsave(&ioc->sas_node_lock, flags); 4381 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3846 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, 4382 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3847 sas_address); 4383 sas_address);
4384 if (!sas_expander) {
4385 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4386 return;
4387 }
4388 list_del(&sas_expander->list);
3848 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 4389 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3849 _scsih_expander_node_remove(ioc, sas_expander); 4390 _scsih_expander_node_remove(ioc, sas_expander);
3850} 4391}
3851 4392
3852/** 4393/**
4394 * _scsih_check_access_status - check access flags
4395 * @ioc: per adapter object
4396 * @sas_address: sas address
4397 * @handle: sas device handle
4398 * @access_flags: errors returned during discovery of the device
4399 *
4400 * Return 0 for success, else failure
4401 */
4402static u8
4403_scsih_check_access_status(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4404 u16 handle, u8 access_status)
4405{
4406 u8 rc = 1;
4407 char *desc = NULL;
4408
4409 switch (access_status) {
4410 case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS:
4411 case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION:
4412 rc = 0;
4413 break;
4414 case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED:
4415 desc = "sata capability failed";
4416 break;
4417 case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT:
4418 desc = "sata affiliation conflict";
4419 break;
4420 case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE:
4421 desc = "route not addressable";
4422 break;
4423 case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE:
4424 desc = "smp error not addressable";
4425 break;
4426 case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED:
4427 desc = "device blocked";
4428 break;
4429 case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED:
4430 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN:
4431 case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT:
4432 case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG:
4433 case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION:
4434 case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER:
4435 case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN:
4436 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN:
4437 case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN:
4438 case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION:
4439 case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE:
4440 case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX:
4441 desc = "sata initialization failed";
4442 break;
4443 default:
4444 desc = "unknown";
4445 break;
4446 }
4447
4448 if (!rc)
4449 return 0;
4450
4451 printk(MPT2SAS_ERR_FMT "discovery errors(%s): sas_address(0x%016llx), "
4452 "handle(0x%04x)\n", ioc->name, desc,
4453 (unsigned long long)sas_address, handle);
4454 return rc;
4455}
4456
4457static void
4458_scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4459{
4460 Mpi2ConfigReply_t mpi_reply;
4461 Mpi2SasDevicePage0_t sas_device_pg0;
4462 struct _sas_device *sas_device;
4463 u32 ioc_status;
4464 unsigned long flags;
4465 u64 sas_address;
4466 struct scsi_target *starget;
4467 struct MPT2SAS_TARGET *sas_target_priv_data;
4468 u32 device_info;
4469
4470 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
4471 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)))
4472 return;
4473
4474 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
4475 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
4476 return;
4477
4478 /* check if this is end device */
4479 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
4480 if (!(_scsih_is_end_device(device_info)))
4481 return;
4482
4483 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4484 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4485 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4486 sas_address);
4487
4488 if (!sas_device) {
4489 printk(MPT2SAS_ERR_FMT "device is not present "
4490 "handle(0x%04x), no sas_device!!!\n", ioc->name, handle);
4491 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4492 return;
4493 }
4494
4495 if (unlikely(sas_device->handle != handle)) {
4496 starget = sas_device->starget;
4497 sas_target_priv_data = starget->hostdata;
4498 starget_printk(KERN_INFO, starget, "handle changed from(0x%04x)"
4499 " to (0x%04x)!!!\n", sas_device->handle, handle);
4500 sas_target_priv_data->handle = handle;
4501 sas_device->handle = handle;
4502 }
4503 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4504
4505 /* check if device is present */
4506 if (!(le16_to_cpu(sas_device_pg0.Flags) &
4507 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
4508 printk(MPT2SAS_ERR_FMT "device is not present "
4509 "handle(0x%04x), flags!!!\n", ioc->name, handle);
4510 return;
4511 }
4512
4513 /* check if there were any issues with discovery */
4514 if (_scsih_check_access_status(ioc, sas_address, handle,
4515 sas_device_pg0.AccessStatus))
4516 return;
4517 _scsih_ublock_io_device(ioc, handle);
4518
4519}
4520
4521/**
3853 * _scsih_add_device - creating sas device object 4522 * _scsih_add_device - creating sas device object
3854 * @ioc: per adapter object 4523 * @ioc: per adapter object
3855 * @handle: sas device handle 4524 * @handle: sas device handle
@@ -3887,6 +4556,8 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3887 return -1; 4556 return -1;
3888 } 4557 }
3889 4558
4559 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4560
3890 /* check if device is present */ 4561 /* check if device is present */
3891 if (!(le16_to_cpu(sas_device_pg0.Flags) & 4562 if (!(le16_to_cpu(sas_device_pg0.Flags) &
3892 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { 4563 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
@@ -3897,15 +4568,10 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3897 return -1; 4568 return -1;
3898 } 4569 }
3899 4570
3900 /* check if there were any issus with discovery */ 4571 /* check if there were any issues with discovery */
3901 if (sas_device_pg0.AccessStatus == 4572 if (_scsih_check_access_status(ioc, sas_address, handle,
3902 MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED) { 4573 sas_device_pg0.AccessStatus))
3903 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3904 ioc->name, __FILE__, __LINE__, __func__);
3905 printk(MPT2SAS_ERR_FMT "AccessStatus = 0x%02x\n",
3906 ioc->name, sas_device_pg0.AccessStatus);
3907 return -1; 4574 return -1;
3908 }
3909 4575
3910 /* check if this is end device */ 4576 /* check if this is end device */
3911 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 4577 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
@@ -3915,17 +4581,14 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3915 return -1; 4581 return -1;
3916 } 4582 }
3917 4583
3918 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
3919 4584
3920 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4585 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3921 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 4586 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
3922 sas_address); 4587 sas_address);
3923 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4588 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3924 4589
3925 if (sas_device) { 4590 if (sas_device)
3926 _scsih_ublock_io_device(ioc, handle);
3927 return 0; 4591 return 0;
3928 }
3929 4592
3930 sas_device = kzalloc(sizeof(struct _sas_device), 4593 sas_device = kzalloc(sizeof(struct _sas_device),
3931 GFP_KERNEL); 4594 GFP_KERNEL);
@@ -3947,7 +4610,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3947 le16_to_cpu(sas_device_pg0.Slot); 4610 le16_to_cpu(sas_device_pg0.Slot);
3948 sas_device->device_info = device_info; 4611 sas_device->device_info = device_info;
3949 sas_device->sas_address = sas_address; 4612 sas_device->sas_address = sas_address;
3950 sas_device->hidden_raid_component = is_pd; 4613 sas_device->phy = sas_device_pg0.PhyNum;
3951 4614
3952 /* get enclosure_logical_id */ 4615 /* get enclosure_logical_id */
3953 if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0( 4616 if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
@@ -3970,100 +4633,73 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3970/** 4633/**
3971 * _scsih_remove_device - removing sas device object 4634 * _scsih_remove_device - removing sas device object
3972 * @ioc: per adapter object 4635 * @ioc: per adapter object
3973 * @sas_device: the sas_device object 4636 * @sas_device_delete: the sas_device object
3974 * 4637 *
3975 * Return nothing. 4638 * Return nothing.
3976 */ 4639 */
3977static void 4640static void
3978_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device 4641_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
3979 *sas_device) 4642 struct _sas_device *sas_device)
3980{ 4643{
4644 struct _sas_device sas_device_backup;
3981 struct MPT2SAS_TARGET *sas_target_priv_data; 4645 struct MPT2SAS_TARGET *sas_target_priv_data;
3982 Mpi2SasIoUnitControlReply_t mpi_reply;
3983 Mpi2SasIoUnitControlRequest_t mpi_request;
3984 u16 device_handle, handle;
3985 4646
3986 if (!sas_device) 4647 if (!sas_device)
3987 return; 4648 return;
3988 4649
3989 handle = sas_device->handle; 4650 memcpy(&sas_device_backup, sas_device, sizeof(struct _sas_device));
3990 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x)," 4651 _scsih_sas_device_remove(ioc, sas_device);
3991 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
3992 (unsigned long long) sas_device->sas_address));
3993
3994 if (sas_device->starget && sas_device->starget->hostdata) {
3995 sas_target_priv_data = sas_device->starget->hostdata;
3996 sas_target_priv_data->deleted = 1;
3997 }
3998
3999 if (ioc->remove_host || ioc->shost_recovery || !handle)
4000 goto out;
4001 4652
4002 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { 4653 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: "
4003 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " 4654 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
4004 "target_reset handle(0x%04x)\n", ioc->name, 4655 sas_device_backup.handle, (unsigned long long)
4005 handle)); 4656 sas_device_backup.sas_address));
4006 goto skip_tr;
4007 }
4008
4009 /* Target Reset to flush out all the outstanding IO */
4010 device_handle = (sas_device->hidden_raid_component) ?
4011 sas_device->volume_handle : handle;
4012 if (device_handle) {
4013 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: "
4014 "handle(0x%04x)\n", ioc->name, device_handle));
4015 mutex_lock(&ioc->tm_cmds.mutex);
4016 mpt2sas_scsih_issue_tm(ioc, device_handle, 0,
4017 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10);
4018 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4019 mutex_unlock(&ioc->tm_cmds.mutex);
4020 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
4021 "done: handle(0x%04x)\n", ioc->name, device_handle));
4022 if (ioc->shost_recovery)
4023 goto out;
4024 }
4025 skip_tr:
4026 4657
4027 if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) { 4658 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) {
4028 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " 4659 sas_target_priv_data = sas_device_backup.starget->hostdata;
4029 "sas_cntrl handle(0x%04x)\n", ioc->name, handle)); 4660 sas_target_priv_data->deleted = 1;
4030 goto out;
4031 } 4661 }
4032 4662
4033 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ 4663 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
4034 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
4035 "(0x%04x)\n", ioc->name, handle));
4036 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
4037 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
4038 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
4039 mpi_request.DevHandle = handle;
4040 mpi_request.VF_ID = 0; /* TODO */
4041 mpi_request.VP_ID = 0;
4042 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
4043 &mpi_request)) != 0) {
4044 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4045 ioc->name, __FILE__, __LINE__, __func__);
4046 }
4047 4664
4048 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status" 4665 mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address,
4049 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 4666 sas_device_backup.sas_address_parent);
4050 le16_to_cpu(mpi_reply.IOCStatus),
4051 le32_to_cpu(mpi_reply.IOCLogInfo)));
4052 4667
4053 out: 4668 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
4669 "(0x%016llx)\n", ioc->name, sas_device_backup.handle,
4670 (unsigned long long) sas_device_backup.sas_address);
4054 4671
4055 _scsih_ublock_io_device(ioc, handle); 4672 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: "
4673 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
4674 sas_device_backup.handle, (unsigned long long)
4675 sas_device_backup.sas_address));
4676}
4056 4677
4057 mpt2sas_transport_port_remove(ioc, sas_device->sas_address, 4678/**
4058 sas_device->sas_address_parent); 4679 * mpt2sas_device_remove - removing device object
4680 * @ioc: per adapter object
4681 * @sas_address: expander sas_address
4682 *
4683 * Return nothing.
4684 */
4685void
4686mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
4687{
4688 struct _sas_device *sas_device;
4689 unsigned long flags;
4059 4690
4060 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 4691 if (ioc->shost_recovery)
4061 "(0x%016llx)\n", ioc->name, handle, 4692 return;
4062 (unsigned long long) sas_device->sas_address);
4063 _scsih_sas_device_remove(ioc, sas_device);
4064 4693
4065 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle" 4694 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4066 "(0x%04x)\n", ioc->name, __func__, handle)); 4695 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
4696 sas_address);
4697 if (!sas_device) {
4698 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4699 return;
4700 }
4701 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4702 _scsih_remove_device(ioc, sas_device);
4067} 4703}
4068 4704
4069#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4705#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4102,9 +4738,9 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4102 status_str = "unknown status"; 4738 status_str = "unknown status";
4103 break; 4739 break;
4104 } 4740 }
4105 printk(MPT2SAS_DEBUG_FMT "sas topology change: (%s)\n", 4741 printk(MPT2SAS_INFO_FMT "sas topology change: (%s)\n",
4106 ioc->name, status_str); 4742 ioc->name, status_str);
4107 printk(KERN_DEBUG "\thandle(0x%04x), enclosure_handle(0x%04x) " 4743 printk(KERN_INFO "\thandle(0x%04x), enclosure_handle(0x%04x) "
4108 "start_phy(%02d), count(%d)\n", 4744 "start_phy(%02d), count(%d)\n",
4109 le16_to_cpu(event_data->ExpanderDevHandle), 4745 le16_to_cpu(event_data->ExpanderDevHandle),
4110 le16_to_cpu(event_data->EnclosureHandle), 4746 le16_to_cpu(event_data->EnclosureHandle),
@@ -4138,7 +4774,7 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4138 } 4774 }
4139 link_rate = event_data->PHY[i].LinkRate >> 4; 4775 link_rate = event_data->PHY[i].LinkRate >> 4;
4140 prev_link_rate = event_data->PHY[i].LinkRate & 0xF; 4776 prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
4141 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:" 4777 printk(KERN_INFO "\tphy(%02d), attached_handle(0x%04x): %s:"
4142 " link rate: new(0x%02x), old(0x%02x)\n", phy_number, 4778 " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
4143 handle, status_str, link_rate, prev_link_rate); 4779 handle, status_str, link_rate, prev_link_rate);
4144 4780
@@ -4160,7 +4796,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4160 int i; 4796 int i;
4161 u16 parent_handle, handle; 4797 u16 parent_handle, handle;
4162 u16 reason_code; 4798 u16 reason_code;
4163 u8 phy_number; 4799 u8 phy_number, max_phys;
4164 struct _sas_node *sas_expander; 4800 struct _sas_node *sas_expander;
4165 struct _sas_device *sas_device; 4801 struct _sas_device *sas_device;
4166 u64 sas_address; 4802 u64 sas_address;
@@ -4173,7 +4809,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4173 _scsih_sas_topology_change_event_debug(ioc, event_data); 4809 _scsih_sas_topology_change_event_debug(ioc, event_data);
4174#endif 4810#endif
4175 4811
4176 if (ioc->shost_recovery) 4812 if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery)
4177 return; 4813 return;
4178 4814
4179 if (!ioc->sas_hba.num_phys) 4815 if (!ioc->sas_hba.num_phys)
@@ -4182,7 +4818,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4182 _scsih_sas_host_refresh(ioc); 4818 _scsih_sas_host_refresh(ioc);
4183 4819
4184 if (fw_event->ignore) { 4820 if (fw_event->ignore) {
4185 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander " 4821 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "ignoring expander "
4186 "event\n", ioc->name)); 4822 "event\n", ioc->name));
4187 return; 4823 return;
4188 } 4824 }
@@ -4198,23 +4834,28 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4198 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, 4834 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
4199 parent_handle); 4835 parent_handle);
4200 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 4836 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4201 if (sas_expander) 4837 if (sas_expander) {
4202 sas_address = sas_expander->sas_address; 4838 sas_address = sas_expander->sas_address;
4203 else if (parent_handle < ioc->sas_hba.num_phys) 4839 max_phys = sas_expander->num_phys;
4840 } else if (parent_handle < ioc->sas_hba.num_phys) {
4204 sas_address = ioc->sas_hba.sas_address; 4841 sas_address = ioc->sas_hba.sas_address;
4205 else 4842 max_phys = ioc->sas_hba.num_phys;
4843 } else
4206 return; 4844 return;
4207 4845
4208 /* handle siblings events */ 4846 /* handle siblings events */
4209 for (i = 0; i < event_data->NumEntries; i++) { 4847 for (i = 0; i < event_data->NumEntries; i++) {
4210 if (fw_event->ignore) { 4848 if (fw_event->ignore) {
4211 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring " 4849 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "ignoring "
4212 "expander event\n", ioc->name)); 4850 "expander event\n", ioc->name));
4213 return; 4851 return;
4214 } 4852 }
4215 if (ioc->shost_recovery) 4853 if (ioc->shost_recovery || ioc->remove_host ||
4854 ioc->pci_error_recovery)
4216 return; 4855 return;
4217 phy_number = event_data->StartPhyNum + i; 4856 phy_number = event_data->StartPhyNum + i;
4857 if (phy_number >= max_phys)
4858 continue;
4218 reason_code = event_data->PHY[i].PhyStatus & 4859 reason_code = event_data->PHY[i].PhyStatus &
4219 MPI2_EVENT_SAS_TOPO_RC_MASK; 4860 MPI2_EVENT_SAS_TOPO_RC_MASK;
4220 if ((event_data->PHY[i].PhyStatus & 4861 if ((event_data->PHY[i].PhyStatus &
@@ -4235,8 +4876,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4235 mpt2sas_transport_update_links(ioc, sas_address, 4876 mpt2sas_transport_update_links(ioc, sas_address,
4236 handle, phy_number, link_rate); 4877 handle, phy_number, link_rate);
4237 4878
4238 if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5) 4879 if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
4239 _scsih_ublock_io_device(ioc, handle); 4880 break;
4881
4882 _scsih_check_device(ioc, handle);
4240 break; 4883 break;
4241 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 4884 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
4242 4885
@@ -4264,7 +4907,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
4264 /* handle expander removal */ 4907 /* handle expander removal */
4265 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && 4908 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
4266 sas_expander) 4909 sas_expander)
4267 _scsih_expander_remove(ioc, sas_address); 4910 mpt2sas_expander_remove(ioc, sas_address);
4268 4911
4269} 4912}
4270 4913
@@ -4326,12 +4969,12 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4326 reason_str = "unknown reason"; 4969 reason_str = "unknown reason";
4327 break; 4970 break;
4328 } 4971 }
4329 printk(MPT2SAS_DEBUG_FMT "device status change: (%s)\n" 4972 printk(MPT2SAS_INFO_FMT "device status change: (%s)\n"
4330 "\thandle(0x%04x), sas address(0x%016llx)", ioc->name, 4973 "\thandle(0x%04x), sas address(0x%016llx)", ioc->name,
4331 reason_str, le16_to_cpu(event_data->DevHandle), 4974 reason_str, le16_to_cpu(event_data->DevHandle),
4332 (unsigned long long)le64_to_cpu(event_data->SASAddress)); 4975 (unsigned long long)le64_to_cpu(event_data->SASAddress));
4333 if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA) 4976 if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA)
4334 printk(MPT2SAS_DEBUG_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name, 4977 printk(MPT2SAS_INFO_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name,
4335 event_data->ASC, event_data->ASCQ); 4978 event_data->ASC, event_data->ASCQ);
4336 printk(KERN_INFO "\n"); 4979 printk(KERN_INFO "\n");
4337} 4980}
@@ -4362,10 +5005,10 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4362 event_data); 5005 event_data);
4363#endif 5006#endif
4364 5007
4365 if (!(event_data->ReasonCode == 5008 if (event_data->ReasonCode !=
4366 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && 5009 MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
4367 event_data->ReasonCode == 5010 event_data->ReasonCode !=
4368 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)) 5011 MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET)
4369 return; 5012 return;
4370 5013
4371 spin_lock_irqsave(&ioc->sas_device_lock, flags); 5014 spin_lock_irqsave(&ioc->sas_device_lock, flags);
@@ -4415,7 +5058,7 @@ _scsih_sas_enclosure_dev_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4415 break; 5058 break;
4416 } 5059 }
4417 5060
4418 printk(MPT2SAS_DEBUG_FMT "enclosure status change: (%s)\n" 5061 printk(MPT2SAS_INFO_FMT "enclosure status change: (%s)\n"
4419 "\thandle(0x%04x), enclosure logical id(0x%016llx)" 5062 "\thandle(0x%04x), enclosure logical id(0x%016llx)"
4420 " number slots(%d)\n", ioc->name, reason_str, 5063 " number slots(%d)\n", ioc->name, reason_str,
4421 le16_to_cpu(event_data->EnclosureHandle), 5064 le16_to_cpu(event_data->EnclosureHandle),
@@ -4466,13 +5109,12 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4466 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; 5109 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4467#endif 5110#endif
4468 u16 ioc_status; 5111 u16 ioc_status;
4469 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " 5112 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: "
4470 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, 5113 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4471 event_data->PortWidth)); 5114 event_data->PortWidth));
4472 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 5115 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
4473 __func__)); 5116 __func__));
4474 5117
4475 mutex_lock(&ioc->tm_cmds.mutex);
4476 termination_count = 0; 5118 termination_count = 0;
4477 query_count = 0; 5119 query_count = 0;
4478 mpi_reply = ioc->tm_cmds.reply; 5120 mpi_reply = ioc->tm_cmds.reply;
@@ -4496,8 +5138,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4496 lun = sas_device_priv_data->lun; 5138 lun = sas_device_priv_data->lun;
4497 query_count++; 5139 query_count++;
4498 5140
4499 mpt2sas_scsih_issue_tm(ioc, handle, lun, 5141 mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
4500 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); 5142 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL);
4501 ioc->tm_cmds.status = MPT2_CMD_NOT_USED; 5143 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4502 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) 5144 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
4503 & MPI2_IOCSTATUS_MASK; 5145 & MPI2_IOCSTATUS_MASK;
@@ -4508,15 +5150,13 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4508 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) 5150 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4509 continue; 5151 continue;
4510 5152
4511 mpt2sas_scsih_issue_tm(ioc, handle, lun, 5153 mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
4512 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30); 5154 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL);
4513 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
4514 termination_count += le32_to_cpu(mpi_reply->TerminationCount); 5155 termination_count += le32_to_cpu(mpi_reply->TerminationCount);
4515 } 5156 }
4516 ioc->broadcast_aen_busy = 0; 5157 ioc->broadcast_aen_busy = 0;
4517 mutex_unlock(&ioc->tm_cmds.mutex);
4518 5158
4519 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT 5159 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
4520 "%s - exit, query_count = %d termination_count = %d\n", 5160 "%s - exit, query_count = %d termination_count = %d\n",
4521 ioc->name, __func__, query_count, termination_count)); 5161 ioc->name, __func__, query_count, termination_count));
4522} 5162}
@@ -4537,7 +5177,7 @@ _scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
4537 5177
4538#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5178#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4539 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { 5179 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
4540 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name, 5180 printk(MPT2SAS_INFO_FMT "discovery event: (%s)", ioc->name,
4541 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? 5181 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
4542 "start" : "stop"); 5182 "start" : "stop");
4543 if (event_data->DiscoveryStatus) 5183 if (event_data->DiscoveryStatus)
@@ -4648,17 +5288,15 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
4648/** 5288/**
4649 * _scsih_sas_volume_delete - delete volume 5289 * _scsih_sas_volume_delete - delete volume
4650 * @ioc: per adapter object 5290 * @ioc: per adapter object
4651 * @element: IR config element data 5291 * @handle: volume device handle
4652 * Context: user. 5292 * Context: user.
4653 * 5293 *
4654 * Return nothing. 5294 * Return nothing.
4655 */ 5295 */
4656static void 5296static void
4657_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, 5297_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4658 Mpi2EventIrConfigElement_t *element)
4659{ 5298{
4660 struct _raid_device *raid_device; 5299 struct _raid_device *raid_device;
4661 u16 handle = le16_to_cpu(element->VolDevHandle);
4662 unsigned long flags; 5300 unsigned long flags;
4663 struct MPT2SAS_TARGET *sas_target_priv_data; 5301 struct MPT2SAS_TARGET *sas_target_priv_data;
4664 5302
@@ -4672,6 +5310,9 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc,
4672 sas_target_priv_data->deleted = 1; 5310 sas_target_priv_data->deleted = 1;
4673 scsi_remove_target(&raid_device->starget->dev); 5311 scsi_remove_target(&raid_device->starget->dev);
4674 } 5312 }
5313 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
5314 "(0x%016llx)\n", ioc->name, raid_device->handle,
5315 (unsigned long long) raid_device->wwid);
4675 _scsih_raid_device_remove(ioc, raid_device); 5316 _scsih_raid_device_remove(ioc, raid_device);
4676} 5317}
4677 5318
@@ -4700,7 +5341,7 @@ _scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc,
4700 /* exposing raid component */ 5341 /* exposing raid component */
4701 sas_device->volume_handle = 0; 5342 sas_device->volume_handle = 0;
4702 sas_device->volume_wwid = 0; 5343 sas_device->volume_wwid = 0;
4703 sas_device->hidden_raid_component = 0; 5344 clear_bit(handle, ioc->pd_handles);
4704 _scsih_reprobe_target(sas_device->starget, 0); 5345 _scsih_reprobe_target(sas_device->starget, 0);
4705} 5346}
4706 5347
@@ -4731,7 +5372,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
4731 &sas_device->volume_handle); 5372 &sas_device->volume_handle);
4732 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle, 5373 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle,
4733 &sas_device->volume_wwid); 5374 &sas_device->volume_wwid);
4734 sas_device->hidden_raid_component = 1; 5375 set_bit(handle, ioc->pd_handles);
4735 _scsih_reprobe_target(sas_device->starget, 1); 5376 _scsih_reprobe_target(sas_device->starget, 1);
4736} 5377}
4737 5378
@@ -4780,13 +5421,13 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4780 u64 sas_address; 5421 u64 sas_address;
4781 u16 parent_handle; 5422 u16 parent_handle;
4782 5423
5424 set_bit(handle, ioc->pd_handles);
5425
4783 spin_lock_irqsave(&ioc->sas_device_lock, flags); 5426 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4784 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 5427 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4785 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 5428 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4786 if (sas_device) { 5429 if (sas_device)
4787 sas_device->hidden_raid_component = 1;
4788 return; 5430 return;
4789 }
4790 5431
4791 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 5432 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
4792 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 5433 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
@@ -4831,7 +5472,7 @@ _scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4831 5472
4832 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; 5473 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
4833 5474
4834 printk(MPT2SAS_DEBUG_FMT "raid config change: (%s), elements(%d)\n", 5475 printk(MPT2SAS_INFO_FMT "raid config change: (%s), elements(%d)\n",
4835 ioc->name, (le32_to_cpu(event_data->Flags) & 5476 ioc->name, (le32_to_cpu(event_data->Flags) &
4836 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 5477 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ?
4837 "foreign" : "native", event_data->NumElements); 5478 "foreign" : "native", event_data->NumElements);
@@ -4884,7 +5525,7 @@ _scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4884 element_str = "unknown element"; 5525 element_str = "unknown element";
4885 break; 5526 break;
4886 } 5527 }
4887 printk(KERN_DEBUG "\t(%s:%s), vol handle(0x%04x), " 5528 printk(KERN_INFO "\t(%s:%s), vol handle(0x%04x), "
4888 "pd handle(0x%04x), pd num(0x%02x)\n", element_str, 5529 "pd handle(0x%04x), pd num(0x%02x)\n", element_str,
4889 reason_str, le16_to_cpu(element->VolDevHandle), 5530 reason_str, le16_to_cpu(element->VolDevHandle),
4890 le16_to_cpu(element->PhysDiskDevHandle), 5531 le16_to_cpu(element->PhysDiskDevHandle),
@@ -4930,7 +5571,8 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
4930 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 5571 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
4931 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 5572 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
4932 if (!foreign_config) 5573 if (!foreign_config)
4933 _scsih_sas_volume_delete(ioc, element); 5574 _scsih_sas_volume_delete(ioc,
5575 le16_to_cpu(element->VolDevHandle));
4934 break; 5576 break;
4935 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 5577 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
4936 _scsih_sas_pd_hide(ioc, element); 5578 _scsih_sas_pd_hide(ioc, element);
@@ -4966,7 +5608,6 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
4966 u16 handle; 5608 u16 handle;
4967 u32 state; 5609 u32 state;
4968 int rc; 5610 int rc;
4969 struct MPT2SAS_TARGET *sas_target_priv_data;
4970 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; 5611 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
4971 5612
4972 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 5613 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
@@ -4974,30 +5615,24 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
4974 5615
4975 handle = le16_to_cpu(event_data->VolDevHandle); 5616 handle = le16_to_cpu(event_data->VolDevHandle);
4976 state = le32_to_cpu(event_data->NewValue); 5617 state = le32_to_cpu(event_data->NewValue);
4977 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle(0x%04x), " 5618 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
4978 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, 5619 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
4979 le32_to_cpu(event_data->PreviousValue), state)); 5620 le32_to_cpu(event_data->PreviousValue), state));
4980 5621
4981 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4982 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
4983 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4984
4985 switch (state) { 5622 switch (state) {
4986 case MPI2_RAID_VOL_STATE_MISSING: 5623 case MPI2_RAID_VOL_STATE_MISSING:
4987 case MPI2_RAID_VOL_STATE_FAILED: 5624 case MPI2_RAID_VOL_STATE_FAILED:
4988 if (!raid_device) 5625 _scsih_sas_volume_delete(ioc, handle);
4989 break;
4990 if (raid_device->starget) {
4991 sas_target_priv_data = raid_device->starget->hostdata;
4992 sas_target_priv_data->deleted = 1;
4993 scsi_remove_target(&raid_device->starget->dev);
4994 }
4995 _scsih_raid_device_remove(ioc, raid_device);
4996 break; 5626 break;
4997 5627
4998 case MPI2_RAID_VOL_STATE_ONLINE: 5628 case MPI2_RAID_VOL_STATE_ONLINE:
4999 case MPI2_RAID_VOL_STATE_DEGRADED: 5629 case MPI2_RAID_VOL_STATE_DEGRADED:
5000 case MPI2_RAID_VOL_STATE_OPTIMAL: 5630 case MPI2_RAID_VOL_STATE_OPTIMAL:
5631
5632 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5633 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5634 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5635
5001 if (raid_device) 5636 if (raid_device)
5002 break; 5637 break;
5003 5638
@@ -5062,23 +5697,25 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5062 handle = le16_to_cpu(event_data->PhysDiskDevHandle); 5697 handle = le16_to_cpu(event_data->PhysDiskDevHandle);
5063 state = le32_to_cpu(event_data->NewValue); 5698 state = le32_to_cpu(event_data->NewValue);
5064 5699
5065 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle(0x%04x), " 5700 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
5066 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, 5701 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
5067 le32_to_cpu(event_data->PreviousValue), state)); 5702 le32_to_cpu(event_data->PreviousValue), state));
5068 5703
5069 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5070 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5071 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5072
5073 switch (state) { 5704 switch (state) {
5074 case MPI2_RAID_PD_STATE_ONLINE: 5705 case MPI2_RAID_PD_STATE_ONLINE:
5075 case MPI2_RAID_PD_STATE_DEGRADED: 5706 case MPI2_RAID_PD_STATE_DEGRADED:
5076 case MPI2_RAID_PD_STATE_REBUILDING: 5707 case MPI2_RAID_PD_STATE_REBUILDING:
5077 case MPI2_RAID_PD_STATE_OPTIMAL: 5708 case MPI2_RAID_PD_STATE_OPTIMAL:
5078 if (sas_device) { 5709 case MPI2_RAID_PD_STATE_HOT_SPARE:
5079 sas_device->hidden_raid_component = 1; 5710
5711 set_bit(handle, ioc->pd_handles);
5712
5713 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5714 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5715 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5716
5717 if (sas_device)
5080 return; 5718 return;
5081 }
5082 5719
5083 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, 5720 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
5084 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, 5721 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
@@ -5108,7 +5745,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5108 case MPI2_RAID_PD_STATE_OFFLINE: 5745 case MPI2_RAID_PD_STATE_OFFLINE:
5109 case MPI2_RAID_PD_STATE_NOT_CONFIGURED: 5746 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
5110 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: 5747 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
5111 case MPI2_RAID_PD_STATE_HOT_SPARE:
5112 default: 5748 default:
5113 break; 5749 break;
5114 } 5750 }
@@ -5170,94 +5806,52 @@ static void
5170_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, 5806_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
5171 struct fw_event_work *fw_event) 5807 struct fw_event_work *fw_event)
5172{ 5808{
5809 Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
5810 static struct _raid_device *raid_device;
5811 unsigned long flags;
5812 u16 handle;
5813
5173#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5814#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5174 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 5815 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
5175 _scsih_sas_ir_operation_status_event_debug(ioc, 5816 _scsih_sas_ir_operation_status_event_debug(ioc,
5176 fw_event->event_data); 5817 event_data);
5177#endif 5818#endif
5819
5820 /* code added for raid transport support */
5821 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) {
5822
5823 handle = le16_to_cpu(event_data->VolDevHandle);
5824
5825 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5826 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5827 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5828
5829 if (!raid_device)
5830 return;
5831
5832 if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC)
5833 raid_device->percent_complete =
5834 event_data->PercentComplete;
5835 }
5178} 5836}
5179 5837
5180/** 5838/**
5181 * _scsih_task_set_full - handle task set full 5839 * _scsih_prep_device_scan - initialize parameters prior to device scan
5182 * @ioc: per adapter object 5840 * @ioc: per adapter object
5183 * @fw_event: The fw_event_work object
5184 * Context: user.
5185 * 5841 *
5186 * Throttle back qdepth. 5842 * Set the deleted flag prior to device scan. If the device is found during
5843 * the scan, then we clear the deleted flag.
5187 */ 5844 */
5188static void 5845static void
5189_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work 5846_scsih_prep_device_scan(struct MPT2SAS_ADAPTER *ioc)
5190 *fw_event)
5191{ 5847{
5192 unsigned long flags; 5848 struct MPT2SAS_DEVICE *sas_device_priv_data;
5193 struct _sas_device *sas_device;
5194 static struct _raid_device *raid_device;
5195 struct scsi_device *sdev; 5849 struct scsi_device *sdev;
5196 int depth;
5197 u16 current_depth;
5198 u16 handle;
5199 int id, channel;
5200 u64 sas_address;
5201 Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data;
5202
5203 current_depth = le16_to_cpu(event_data->CurrentDepth);
5204 handle = le16_to_cpu(event_data->DevHandle);
5205 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5206 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5207 if (!sas_device) {
5208 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5209 return;
5210 }
5211 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5212 id = sas_device->id;
5213 channel = sas_device->channel;
5214 sas_address = sas_device->sas_address;
5215
5216 /* if hidden raid component, then change to volume characteristics */
5217 if (sas_device->hidden_raid_component && sas_device->volume_handle) {
5218 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5219 raid_device = _scsih_raid_device_find_by_handle(
5220 ioc, sas_device->volume_handle);
5221 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5222 if (raid_device) {
5223 id = raid_device->id;
5224 channel = raid_device->channel;
5225 handle = raid_device->handle;
5226 sas_address = raid_device->wwid;
5227 }
5228 }
5229
5230 if (ioc->logging_level & MPT_DEBUG_TASK_SET_FULL)
5231 starget_printk(KERN_DEBUG, sas_device->starget, "task set "
5232 "full: handle(0x%04x), sas_addr(0x%016llx), depth(%d)\n",
5233 handle, (unsigned long long)sas_address, current_depth);
5234 5850
5235 shost_for_each_device(sdev, ioc->shost) { 5851 shost_for_each_device(sdev, ioc->shost) {
5236 if (sdev->id == id && sdev->channel == channel) { 5852 sas_device_priv_data = sdev->hostdata;
5237 if (current_depth > sdev->queue_depth) { 5853 if (sas_device_priv_data && sas_device_priv_data->sas_target)
5238 if (ioc->logging_level & 5854 sas_device_priv_data->sas_target->deleted = 1;
5239 MPT_DEBUG_TASK_SET_FULL)
5240 sdev_printk(KERN_INFO, sdev, "strange "
5241 "observation, the queue depth is"
5242 " (%d) meanwhile fw queue depth "
5243 "is (%d)\n", sdev->queue_depth,
5244 current_depth);
5245 continue;
5246 }
5247 depth = scsi_track_queue_full(sdev,
5248 current_depth - 1);
5249 if (depth > 0)
5250 sdev_printk(KERN_INFO, sdev, "Queue depth "
5251 "reduced to (%d)\n", depth);
5252 else if (depth < 0)
5253 sdev_printk(KERN_INFO, sdev, "Tagged Command "
5254 "Queueing is being disabled\n");
5255 else if (depth == 0)
5256 if (ioc->logging_level &
5257 MPT_DEBUG_TASK_SET_FULL)
5258 sdev_printk(KERN_INFO, sdev,
5259 "Queue depth not changed yet\n");
5260 }
5261 } 5855 }
5262} 5856}
5263 5857
@@ -5287,10 +5881,13 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5287 if (sas_device->sas_address == sas_address && 5881 if (sas_device->sas_address == sas_address &&
5288 sas_device->slot == slot && sas_device->starget) { 5882 sas_device->slot == slot && sas_device->starget) {
5289 sas_device->responding = 1; 5883 sas_device->responding = 1;
5290 sas_device->state = 0;
5291 starget = sas_device->starget; 5884 starget = sas_device->starget;
5292 sas_target_priv_data = starget->hostdata; 5885 if (starget && starget->hostdata) {
5293 sas_target_priv_data->tm_busy = 0; 5886 sas_target_priv_data = starget->hostdata;
5887 sas_target_priv_data->tm_busy = 0;
5888 sas_target_priv_data->deleted = 0;
5889 } else
5890 sas_target_priv_data = NULL;
5294 starget_printk(KERN_INFO, sas_device->starget, 5891 starget_printk(KERN_INFO, sas_device->starget,
5295 "handle(0x%04x), sas_addr(0x%016llx), enclosure " 5892 "handle(0x%04x), sas_addr(0x%016llx), enclosure "
5296 "logical id(0x%016llx), slot(%d)\n", handle, 5893 "logical id(0x%016llx), slot(%d)\n", handle,
@@ -5303,7 +5900,8 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5303 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 5900 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
5304 sas_device->handle); 5901 sas_device->handle);
5305 sas_device->handle = handle; 5902 sas_device->handle = handle;
5306 sas_target_priv_data->handle = handle; 5903 if (sas_target_priv_data)
5904 sas_target_priv_data->handle = handle;
5307 goto out; 5905 goto out;
5308 } 5906 }
5309 } 5907 }
@@ -5378,6 +5976,12 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
5378 spin_lock_irqsave(&ioc->raid_device_lock, flags); 5976 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5379 list_for_each_entry(raid_device, &ioc->raid_device_list, list) { 5977 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
5380 if (raid_device->wwid == wwid && raid_device->starget) { 5978 if (raid_device->wwid == wwid && raid_device->starget) {
5979 starget = raid_device->starget;
5980 if (starget && starget->hostdata) {
5981 sas_target_priv_data = starget->hostdata;
5982 sas_target_priv_data->deleted = 0;
5983 } else
5984 sas_target_priv_data = NULL;
5381 raid_device->responding = 1; 5985 raid_device->responding = 1;
5382 starget_printk(KERN_INFO, raid_device->starget, 5986 starget_printk(KERN_INFO, raid_device->starget,
5383 "handle(0x%04x), wwid(0x%016llx)\n", handle, 5987 "handle(0x%04x), wwid(0x%016llx)\n", handle,
@@ -5387,9 +5991,8 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
5387 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 5991 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
5388 raid_device->handle); 5992 raid_device->handle);
5389 raid_device->handle = handle; 5993 raid_device->handle = handle;
5390 starget = raid_device->starget; 5994 if (sas_target_priv_data)
5391 sas_target_priv_data = starget->hostdata; 5995 sas_target_priv_data->handle = handle;
5392 sas_target_priv_data->handle = handle;
5393 goto out; 5996 goto out;
5394 } 5997 }
5395 } 5998 }
@@ -5410,9 +6013,12 @@ static void
5410_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc) 6013_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
5411{ 6014{
5412 Mpi2RaidVolPage1_t volume_pg1; 6015 Mpi2RaidVolPage1_t volume_pg1;
6016 Mpi2RaidVolPage0_t volume_pg0;
6017 Mpi2RaidPhysDiskPage0_t pd_pg0;
5413 Mpi2ConfigReply_t mpi_reply; 6018 Mpi2ConfigReply_t mpi_reply;
5414 u16 ioc_status; 6019 u16 ioc_status;
5415 u16 handle; 6020 u16 handle;
6021 u8 phys_disk_num;
5416 6022
5417 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6023 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
5418 6024
@@ -5427,8 +6033,32 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
5427 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 6033 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
5428 break; 6034 break;
5429 handle = le16_to_cpu(volume_pg1.DevHandle); 6035 handle = le16_to_cpu(volume_pg1.DevHandle);
5430 _scsih_mark_responding_raid_device(ioc, 6036
5431 le64_to_cpu(volume_pg1.WWID), handle); 6037 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
6038 &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
6039 sizeof(Mpi2RaidVolPage0_t)))
6040 continue;
6041
6042 if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
6043 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
6044 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED)
6045 _scsih_mark_responding_raid_device(ioc,
6046 le64_to_cpu(volume_pg1.WWID), handle);
6047 }
6048
6049 /* refresh the pd_handles */
6050 phys_disk_num = 0xFF;
6051 memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
6052 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
6053 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
6054 phys_disk_num))) {
6055 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6056 MPI2_IOCSTATUS_MASK;
6057 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
6058 break;
6059 phys_disk_num = pd_pg0.PhysDiskNum;
6060 handle = le16_to_cpu(pd_pg0.DevHandle);
6061 set_bit(handle, ioc->pd_handles);
5432 } 6062 }
5433} 6063}
5434 6064
@@ -5514,13 +6144,13 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
5514} 6144}
5515 6145
5516/** 6146/**
5517 * _scsih_remove_unresponding_devices - removing unresponding devices 6147 * _scsih_remove_unresponding_sas_devices - removing unresponding devices
5518 * @ioc: per adapter object 6148 * @ioc: per adapter object
5519 * 6149 *
5520 * Return nothing. 6150 * Return nothing.
5521 */ 6151 */
5522static void 6152static void
5523_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc) 6153_scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
5524{ 6154{
5525 struct _sas_device *sas_device, *sas_device_next; 6155 struct _sas_device *sas_device, *sas_device_next;
5526 struct _sas_node *sas_expander; 6156 struct _sas_node *sas_expander;
@@ -5542,8 +6172,6 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5542 (unsigned long long) 6172 (unsigned long long)
5543 sas_device->enclosure_logical_id, 6173 sas_device->enclosure_logical_id,
5544 sas_device->slot); 6174 sas_device->slot);
5545 /* invalidate the device handle */
5546 sas_device->handle = 0;
5547 _scsih_remove_device(ioc, sas_device); 6175 _scsih_remove_device(ioc, sas_device);
5548 } 6176 }
5549 6177
@@ -5570,7 +6198,7 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
5570 sas_expander->responding = 0; 6198 sas_expander->responding = 0;
5571 continue; 6199 continue;
5572 } 6200 }
5573 _scsih_expander_remove(ioc, sas_expander->sas_address); 6201 mpt2sas_expander_remove(ioc, sas_expander->sas_address);
5574 goto retry_expander_search; 6202 goto retry_expander_search;
5575 } 6203 }
5576} 6204}
@@ -5592,34 +6220,35 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
5592{ 6220{
5593 switch (reset_phase) { 6221 switch (reset_phase) {
5594 case MPT2_IOC_PRE_RESET: 6222 case MPT2_IOC_PRE_RESET:
5595 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 6223 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
5596 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); 6224 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
5597 _scsih_fw_event_off(ioc);
5598 break; 6225 break;
5599 case MPT2_IOC_AFTER_RESET: 6226 case MPT2_IOC_AFTER_RESET:
5600 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 6227 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
5601 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); 6228 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
6229 if (ioc->scsih_cmds.status & MPT2_CMD_PENDING) {
6230 ioc->scsih_cmds.status |= MPT2_CMD_RESET;
6231 mpt2sas_base_free_smid(ioc, ioc->scsih_cmds.smid);
6232 complete(&ioc->scsih_cmds.done);
6233 }
5602 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) { 6234 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
5603 ioc->tm_cmds.status |= MPT2_CMD_RESET; 6235 ioc->tm_cmds.status |= MPT2_CMD_RESET;
5604 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid); 6236 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
5605 complete(&ioc->tm_cmds.done); 6237 complete(&ioc->tm_cmds.done);
5606 } 6238 }
5607 _scsih_fw_event_on(ioc); 6239 _scsih_fw_event_cleanup_queue(ioc);
5608 _scsih_flush_running_cmds(ioc); 6240 _scsih_flush_running_cmds(ioc);
6241 _scsih_queue_rescan(ioc);
5609 break; 6242 break;
5610 case MPT2_IOC_DONE_RESET: 6243 case MPT2_IOC_DONE_RESET:
5611 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 6244 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
5612 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 6245 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
5613 _scsih_sas_host_refresh(ioc); 6246 _scsih_sas_host_refresh(ioc);
6247 _scsih_prep_device_scan(ioc);
5614 _scsih_search_responding_sas_devices(ioc); 6248 _scsih_search_responding_sas_devices(ioc);
5615 _scsih_search_responding_raid_devices(ioc); 6249 _scsih_search_responding_raid_devices(ioc);
5616 _scsih_search_responding_expanders(ioc); 6250 _scsih_search_responding_expanders(ioc);
5617 break; 6251 break;
5618 case MPT2_IOC_RUNNING:
5619 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
5620 "MPT2_IOC_RUNNING\n", ioc->name, __func__));
5621 _scsih_remove_unresponding_devices(ioc);
5622 break;
5623 } 6252 }
5624} 6253}
5625 6254
@@ -5635,21 +6264,29 @@ static void
5635_firmware_event_work(struct work_struct *work) 6264_firmware_event_work(struct work_struct *work)
5636{ 6265{
5637 struct fw_event_work *fw_event = container_of(work, 6266 struct fw_event_work *fw_event = container_of(work,
5638 struct fw_event_work, work); 6267 struct fw_event_work, delayed_work.work);
5639 unsigned long flags; 6268 unsigned long flags;
5640 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; 6269 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
5641 6270
5642 /* the queue is being flushed so ignore this event */ 6271 /* the queue is being flushed so ignore this event */
5643 spin_lock_irqsave(&ioc->fw_event_lock, flags); 6272 if (ioc->remove_host || fw_event->cancel_pending_work ||
5644 if (ioc->fw_events_off || ioc->remove_host) { 6273 ioc->pci_error_recovery) {
5645 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5646 _scsih_fw_event_free(ioc, fw_event); 6274 _scsih_fw_event_free(ioc, fw_event);
5647 return; 6275 return;
5648 } 6276 }
5649 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5650 6277
5651 if (ioc->shost_recovery) { 6278 if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
5652 _scsih_fw_event_requeue(ioc, fw_event, 1000); 6279 _scsih_fw_event_free(ioc, fw_event);
6280 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
6281 if (ioc->shost_recovery) {
6282 init_completion(&ioc->shost_recovery_done);
6283 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6284 flags);
6285 wait_for_completion(&ioc->shost_recovery_done);
6286 } else
6287 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6288 flags);
6289 _scsih_remove_unresponding_sas_devices(ioc);
5653 return; 6290 return;
5654 } 6291 }
5655 6292
@@ -5685,9 +6322,6 @@ _firmware_event_work(struct work_struct *work)
5685 case MPI2_EVENT_IR_OPERATION_STATUS: 6322 case MPI2_EVENT_IR_OPERATION_STATUS:
5686 _scsih_sas_ir_operation_status_event(ioc, fw_event); 6323 _scsih_sas_ir_operation_status_event(ioc, fw_event);
5687 break; 6324 break;
5688 case MPI2_EVENT_TASK_SET_FULL:
5689 _scsih_task_set_full(ioc, fw_event);
5690 break;
5691 } 6325 }
5692 _scsih_fw_event_free(ioc, fw_event); 6326 _scsih_fw_event_free(ioc, fw_event);
5693} 6327}
@@ -5711,16 +6345,12 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5711{ 6345{
5712 struct fw_event_work *fw_event; 6346 struct fw_event_work *fw_event;
5713 Mpi2EventNotificationReply_t *mpi_reply; 6347 Mpi2EventNotificationReply_t *mpi_reply;
5714 unsigned long flags;
5715 u16 event; 6348 u16 event;
6349 u16 sz;
5716 6350
5717 /* events turned off due to host reset or driver unloading */ 6351 /* events turned off due to host reset or driver unloading */
5718 spin_lock_irqsave(&ioc->fw_event_lock, flags); 6352 if (ioc->remove_host || ioc->pci_error_recovery)
5719 if (ioc->fw_events_off || ioc->remove_host) {
5720 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5721 return 1; 6353 return 1;
5722 }
5723 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5724 6354
5725 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 6355 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
5726 event = le16_to_cpu(mpi_reply->Event); 6356 event = le16_to_cpu(mpi_reply->Event);
@@ -5746,15 +6376,21 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5746 (Mpi2EventDataSasTopologyChangeList_t *) 6376 (Mpi2EventDataSasTopologyChangeList_t *)
5747 mpi_reply->EventData); 6377 mpi_reply->EventData);
5748 break; 6378 break;
5749 6379 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6380 _scsih_check_ir_config_unhide_events(ioc,
6381 (Mpi2EventDataIrConfigChangeList_t *)
6382 mpi_reply->EventData);
6383 break;
6384 case MPI2_EVENT_IR_VOLUME:
6385 _scsih_check_volume_delete_events(ioc,
6386 (Mpi2EventDataIrVolume_t *)
6387 mpi_reply->EventData);
6388 break;
5750 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 6389 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
5751 case MPI2_EVENT_IR_OPERATION_STATUS: 6390 case MPI2_EVENT_IR_OPERATION_STATUS:
5752 case MPI2_EVENT_SAS_DISCOVERY: 6391 case MPI2_EVENT_SAS_DISCOVERY:
5753 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 6392 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5754 case MPI2_EVENT_IR_VOLUME:
5755 case MPI2_EVENT_IR_PHYSICAL_DISK: 6393 case MPI2_EVENT_IR_PHYSICAL_DISK:
5756 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
5757 case MPI2_EVENT_TASK_SET_FULL:
5758 break; 6394 break;
5759 6395
5760 default: /* ignore the rest */ 6396 default: /* ignore the rest */
@@ -5767,8 +6403,8 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5767 ioc->name, __FILE__, __LINE__, __func__); 6403 ioc->name, __FILE__, __LINE__, __func__);
5768 return 1; 6404 return 1;
5769 } 6405 }
5770 fw_event->event_data = 6406 sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
5771 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); 6407 fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
5772 if (!fw_event->event_data) { 6408 if (!fw_event->event_data) {
5773 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 6409 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5774 ioc->name, __FILE__, __LINE__, __func__); 6410 ioc->name, __FILE__, __LINE__, __func__);
@@ -5777,7 +6413,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5777 } 6413 }
5778 6414
5779 memcpy(fw_event->event_data, mpi_reply->EventData, 6415 memcpy(fw_event->event_data, mpi_reply->EventData,
5780 mpi_reply->EventDataLength*4); 6416 sz);
5781 fw_event->ioc = ioc; 6417 fw_event->ioc = ioc;
5782 fw_event->VF_ID = mpi_reply->VF_ID; 6418 fw_event->VF_ID = mpi_reply->VF_ID;
5783 fw_event->VP_ID = mpi_reply->VP_ID; 6419 fw_event->VP_ID = mpi_reply->VP_ID;
@@ -5829,56 +6465,23 @@ static void
5829_scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, 6465_scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5830 struct _sas_node *sas_expander) 6466 struct _sas_node *sas_expander)
5831{ 6467{
5832 struct _sas_port *mpt2sas_port; 6468 struct _sas_port *mpt2sas_port, *next;
5833 struct _sas_device *sas_device;
5834 struct _sas_node *expander_sibling;
5835 unsigned long flags;
5836
5837 if (!sas_expander)
5838 return;
5839 6469
5840 /* remove sibling ports attached to this expander */ 6470 /* remove sibling ports attached to this expander */
5841 retry_device_search: 6471 list_for_each_entry_safe(mpt2sas_port, next,
5842 list_for_each_entry(mpt2sas_port,
5843 &sas_expander->sas_port_list, port_list) { 6472 &sas_expander->sas_port_list, port_list) {
6473 if (ioc->shost_recovery)
6474 return;
5844 if (mpt2sas_port->remote_identify.device_type == 6475 if (mpt2sas_port->remote_identify.device_type ==
5845 SAS_END_DEVICE) { 6476 SAS_END_DEVICE)
5846 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6477 mpt2sas_device_remove(ioc,
5847 sas_device = 6478 mpt2sas_port->remote_identify.sas_address);
5848 mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 6479 else if (mpt2sas_port->remote_identify.device_type ==
5849 mpt2sas_port->remote_identify.sas_address); 6480 SAS_EDGE_EXPANDER_DEVICE ||
5850 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5851 if (!sas_device)
5852 continue;
5853 _scsih_remove_device(ioc, sas_device);
5854 if (ioc->shost_recovery)
5855 return;
5856 goto retry_device_search;
5857 }
5858 }
5859
5860 retry_expander_search:
5861 list_for_each_entry(mpt2sas_port,
5862 &sas_expander->sas_port_list, port_list) {
5863
5864 if (mpt2sas_port->remote_identify.device_type ==
5865 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
5866 mpt2sas_port->remote_identify.device_type == 6481 mpt2sas_port->remote_identify.device_type ==
5867 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) { 6482 SAS_FANOUT_EXPANDER_DEVICE)
5868 6483 mpt2sas_expander_remove(ioc,
5869 spin_lock_irqsave(&ioc->sas_node_lock, flags); 6484 mpt2sas_port->remote_identify.sas_address);
5870 expander_sibling =
5871 mpt2sas_scsih_expander_find_by_sas_address(
5872 ioc, mpt2sas_port->remote_identify.sas_address);
5873 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5874 if (!expander_sibling)
5875 continue;
5876 _scsih_expander_remove(ioc,
5877 expander_sibling->sas_address);
5878 if (ioc->shost_recovery)
5879 return;
5880 goto retry_expander_search;
5881 }
5882 } 6485 }
5883 6486
5884 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, 6487 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
@@ -5889,7 +6492,6 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5889 sas_expander->handle, (unsigned long long) 6492 sas_expander->handle, (unsigned long long)
5890 sas_expander->sas_address); 6493 sas_expander->sas_address);
5891 6494
5892 list_del(&sas_expander->list);
5893 kfree(sas_expander->phy); 6495 kfree(sas_expander->phy);
5894 kfree(sas_expander); 6496 kfree(sas_expander);
5895} 6497}
@@ -5978,6 +6580,18 @@ _scsih_shutdown(struct pci_dev *pdev)
5978{ 6580{
5979 struct Scsi_Host *shost = pci_get_drvdata(pdev); 6581 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5980 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 6582 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
6583 struct workqueue_struct *wq;
6584 unsigned long flags;
6585
6586 ioc->remove_host = 1;
6587 _scsih_fw_event_cleanup_queue(ioc);
6588
6589 spin_lock_irqsave(&ioc->fw_event_lock, flags);
6590 wq = ioc->firmware_event_thread;
6591 ioc->firmware_event_thread = NULL;
6592 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
6593 if (wq)
6594 destroy_workqueue(wq);
5981 6595
5982 _scsih_ir_shutdown(ioc); 6596 _scsih_ir_shutdown(ioc);
5983 mpt2sas_base_detach(ioc); 6597 mpt2sas_base_detach(ioc);
@@ -5995,14 +6609,14 @@ _scsih_remove(struct pci_dev *pdev)
5995{ 6609{
5996 struct Scsi_Host *shost = pci_get_drvdata(pdev); 6610 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5997 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 6611 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5998 struct _sas_port *mpt2sas_port; 6612 struct _sas_port *mpt2sas_port, *next_port;
5999 struct _sas_device *sas_device; 6613 struct _raid_device *raid_device, *next;
6000 struct _sas_node *expander_sibling; 6614 struct MPT2SAS_TARGET *sas_target_priv_data;
6001 struct workqueue_struct *wq; 6615 struct workqueue_struct *wq;
6002 unsigned long flags; 6616 unsigned long flags;
6003 6617
6004 ioc->remove_host = 1; 6618 ioc->remove_host = 1;
6005 _scsih_fw_event_off(ioc); 6619 _scsih_fw_event_cleanup_queue(ioc);
6006 6620
6007 spin_lock_irqsave(&ioc->fw_event_lock, flags); 6621 spin_lock_irqsave(&ioc->fw_event_lock, flags);
6008 wq = ioc->firmware_event_thread; 6622 wq = ioc->firmware_event_thread;
@@ -6011,29 +6625,34 @@ _scsih_remove(struct pci_dev *pdev)
6011 if (wq) 6625 if (wq)
6012 destroy_workqueue(wq); 6626 destroy_workqueue(wq);
6013 6627
6628 /* release all the volumes */
6629 list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
6630 list) {
6631 if (raid_device->starget) {
6632 sas_target_priv_data =
6633 raid_device->starget->hostdata;
6634 sas_target_priv_data->deleted = 1;
6635 scsi_remove_target(&raid_device->starget->dev);
6636 }
6637 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
6638 "(0x%016llx)\n", ioc->name, raid_device->handle,
6639 (unsigned long long) raid_device->wwid);
6640 _scsih_raid_device_remove(ioc, raid_device);
6641 }
6642
6014 /* free ports attached to the sas_host */ 6643 /* free ports attached to the sas_host */
6015 retry_again: 6644 list_for_each_entry_safe(mpt2sas_port, next_port,
6016 list_for_each_entry(mpt2sas_port,
6017 &ioc->sas_hba.sas_port_list, port_list) { 6645 &ioc->sas_hba.sas_port_list, port_list) {
6018 if (mpt2sas_port->remote_identify.device_type == 6646 if (mpt2sas_port->remote_identify.device_type ==
6019 SAS_END_DEVICE) { 6647 SAS_END_DEVICE)
6020 sas_device = 6648 mpt2sas_device_remove(ioc,
6021 mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 6649 mpt2sas_port->remote_identify.sas_address);
6022 mpt2sas_port->remote_identify.sas_address); 6650 else if (mpt2sas_port->remote_identify.device_type ==
6023 if (sas_device) { 6651 SAS_EDGE_EXPANDER_DEVICE ||
6024 _scsih_remove_device(ioc, sas_device); 6652 mpt2sas_port->remote_identify.device_type ==
6025 goto retry_again; 6653 SAS_FANOUT_EXPANDER_DEVICE)
6026 } 6654 mpt2sas_expander_remove(ioc,
6027 } else {
6028 expander_sibling =
6029 mpt2sas_scsih_expander_find_by_sas_address(ioc,
6030 mpt2sas_port->remote_identify.sas_address); 6655 mpt2sas_port->remote_identify.sas_address);
6031 if (expander_sibling) {
6032 _scsih_expander_remove(ioc,
6033 expander_sibling->sas_address);
6034 goto retry_again;
6035 }
6036 }
6037 } 6656 }
6038 6657
6039 /* free phys attached to the sas_host */ 6658 /* free phys attached to the sas_host */
@@ -6231,9 +6850,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6231 ioc->scsih_cb_idx = scsih_cb_idx; 6850 ioc->scsih_cb_idx = scsih_cb_idx;
6232 ioc->config_cb_idx = config_cb_idx; 6851 ioc->config_cb_idx = config_cb_idx;
6233 ioc->tm_tr_cb_idx = tm_tr_cb_idx; 6852 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
6853 ioc->tm_tr_volume_cb_idx = tm_tr_volume_cb_idx;
6234 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; 6854 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
6235 ioc->logging_level = logging_level; 6855 ioc->logging_level = logging_level;
6236 /* misc semaphores and spin locks */ 6856 /* misc semaphores and spin locks */
6857 mutex_init(&ioc->reset_in_progress_mutex);
6237 spin_lock_init(&ioc->ioc_reset_in_progress_lock); 6858 spin_lock_init(&ioc->ioc_reset_in_progress_lock);
6238 spin_lock_init(&ioc->scsi_lookup_lock); 6859 spin_lock_init(&ioc->scsi_lookup_lock);
6239 spin_lock_init(&ioc->sas_device_lock); 6860 spin_lock_init(&ioc->sas_device_lock);
@@ -6248,9 +6869,10 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6248 INIT_LIST_HEAD(&ioc->raid_device_list); 6869 INIT_LIST_HEAD(&ioc->raid_device_list);
6249 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); 6870 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
6250 INIT_LIST_HEAD(&ioc->delayed_tr_list); 6871 INIT_LIST_HEAD(&ioc->delayed_tr_list);
6872 INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
6251 6873
6252 /* init shost parameters */ 6874 /* init shost parameters */
6253 shost->max_cmd_len = 16; 6875 shost->max_cmd_len = 32;
6254 shost->max_lun = max_lun; 6876 shost->max_lun = max_lun;
6255 shost->transportt = mpt2sas_transport_template; 6877 shost->transportt = mpt2sas_transport_template;
6256 shost->unique_id = ioc->id; 6878 shost->unique_id = ioc->id;
@@ -6263,7 +6885,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6263 } 6885 }
6264 6886
6265 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION 6887 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
6266 | SHOST_DIF_TYPE3_PROTECTION); 6888 | SHOST_DIF_TYPE2_PROTECTION | SHOST_DIF_TYPE3_PROTECTION);
6267 scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC); 6889 scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
6268 6890
6269 /* event thread */ 6891 /* event thread */
@@ -6360,6 +6982,129 @@ _scsih_resume(struct pci_dev *pdev)
6360} 6982}
6361#endif /* CONFIG_PM */ 6983#endif /* CONFIG_PM */
6362 6984
6985/**
6986 * _scsih_pci_error_detected - Called when a PCI error is detected.
6987 * @pdev: PCI device struct
6988 * @state: PCI channel state
6989 *
6990 * Description: Called when a PCI error is detected.
6991 *
6992 * Return value:
6993 * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
6994 */
6995static pci_ers_result_t
6996_scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
6997{
6998 struct Scsi_Host *shost = pci_get_drvdata(pdev);
6999 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7000
7001 printk(MPT2SAS_INFO_FMT "PCI error: detected callback, state(%d)!!\n",
7002 ioc->name, state);
7003
7004 switch (state) {
7005 case pci_channel_io_normal:
7006 return PCI_ERS_RESULT_CAN_RECOVER;
7007 case pci_channel_io_frozen:
7008 /* Fatal error, prepare for slot reset */
7009 ioc->pci_error_recovery = 1;
7010 scsi_block_requests(ioc->shost);
7011 mpt2sas_base_stop_watchdog(ioc);
7012 mpt2sas_base_free_resources(ioc);
7013 return PCI_ERS_RESULT_NEED_RESET;
7014 case pci_channel_io_perm_failure:
7015 /* Permanent error, prepare for device removal */
7016 ioc->pci_error_recovery = 1;
7017 mpt2sas_base_stop_watchdog(ioc);
7018 _scsih_flush_running_cmds(ioc);
7019 return PCI_ERS_RESULT_DISCONNECT;
7020 }
7021 return PCI_ERS_RESULT_NEED_RESET;
7022}
7023
7024/**
7025 * _scsih_pci_slot_reset - Called when PCI slot has been reset.
7026 * @pdev: PCI device struct
7027 *
7028 * Description: This routine is called by the pci error recovery
7029 * code after the PCI slot has been reset, just before we
7030 * should resume normal operations.
7031 */
7032static pci_ers_result_t
7033_scsih_pci_slot_reset(struct pci_dev *pdev)
7034{
7035 struct Scsi_Host *shost = pci_get_drvdata(pdev);
7036 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7037 int rc;
7038
7039 printk(MPT2SAS_INFO_FMT "PCI error: slot reset callback!!\n",
7040 ioc->name);
7041
7042 ioc->pci_error_recovery = 0;
7043 ioc->pdev = pdev;
7044 pci_restore_state(pdev);
7045 rc = mpt2sas_base_map_resources(ioc);
7046 if (rc)
7047 return PCI_ERS_RESULT_DISCONNECT;
7048
7049
7050 rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
7051 FORCE_BIG_HAMMER);
7052
7053 printk(MPT2SAS_WARN_FMT "hard reset: %s\n", ioc->name,
7054 (rc == 0) ? "success" : "failed");
7055
7056 if (!rc)
7057 return PCI_ERS_RESULT_RECOVERED;
7058 else
7059 return PCI_ERS_RESULT_DISCONNECT;
7060}
7061
7062/**
7063 * _scsih_pci_resume() - resume normal ops after PCI reset
7064 * @pdev: pointer to PCI device
7065 *
7066 * Called when the error recovery driver tells us that its
7067 * OK to resume normal operation. Use completion to allow
7068 * halted scsi ops to resume.
7069 */
7070static void
7071_scsih_pci_resume(struct pci_dev *pdev)
7072{
7073 struct Scsi_Host *shost = pci_get_drvdata(pdev);
7074 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7075
7076 printk(MPT2SAS_INFO_FMT "PCI error: resume callback!!\n", ioc->name);
7077
7078 pci_cleanup_aer_uncorrect_error_status(pdev);
7079 mpt2sas_base_start_watchdog(ioc);
7080 scsi_unblock_requests(ioc->shost);
7081}
7082
7083/**
7084 * _scsih_pci_mmio_enabled - Enable MMIO and dump debug registers
7085 * @pdev: pointer to PCI device
7086 */
7087static pci_ers_result_t
7088_scsih_pci_mmio_enabled(struct pci_dev *pdev)
7089{
7090 struct Scsi_Host *shost = pci_get_drvdata(pdev);
7091 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7092
7093 printk(MPT2SAS_INFO_FMT "PCI error: mmio enabled callback!!\n",
7094 ioc->name);
7095
7096 /* TODO - dump whatever for debugging purposes */
7097
7098 /* Request a slot reset. */
7099 return PCI_ERS_RESULT_NEED_RESET;
7100}
7101
7102static struct pci_error_handlers _scsih_err_handler = {
7103 .error_detected = _scsih_pci_error_detected,
7104 .mmio_enabled = _scsih_pci_mmio_enabled,
7105 .slot_reset = _scsih_pci_slot_reset,
7106 .resume = _scsih_pci_resume,
7107};
6363 7108
6364static struct pci_driver scsih_driver = { 7109static struct pci_driver scsih_driver = {
6365 .name = MPT2SAS_DRIVER_NAME, 7110 .name = MPT2SAS_DRIVER_NAME,
@@ -6367,12 +7112,20 @@ static struct pci_driver scsih_driver = {
6367 .probe = _scsih_probe, 7112 .probe = _scsih_probe,
6368 .remove = __devexit_p(_scsih_remove), 7113 .remove = __devexit_p(_scsih_remove),
6369 .shutdown = _scsih_shutdown, 7114 .shutdown = _scsih_shutdown,
7115 .err_handler = &_scsih_err_handler,
6370#ifdef CONFIG_PM 7116#ifdef CONFIG_PM
6371 .suspend = _scsih_suspend, 7117 .suspend = _scsih_suspend,
6372 .resume = _scsih_resume, 7118 .resume = _scsih_resume,
6373#endif 7119#endif
6374}; 7120};
6375 7121
7122/* raid transport support */
7123static struct raid_function_template mpt2sas_raid_functions = {
7124 .cookie = &scsih_driver_template,
7125 .is_raid = _scsih_is_raid,
7126 .get_resync = _scsih_get_resync,
7127 .get_state = _scsih_get_state,
7128};
6376 7129
6377/** 7130/**
6378 * _scsih_init - main entry point for this driver. 7131 * _scsih_init - main entry point for this driver.
@@ -6392,13 +7145,19 @@ _scsih_init(void)
6392 sas_attach_transport(&mpt2sas_transport_functions); 7145 sas_attach_transport(&mpt2sas_transport_functions);
6393 if (!mpt2sas_transport_template) 7146 if (!mpt2sas_transport_template)
6394 return -ENODEV; 7147 return -ENODEV;
7148 /* raid transport support */
7149 mpt2sas_raid_template = raid_class_attach(&mpt2sas_raid_functions);
7150 if (!mpt2sas_raid_template) {
7151 sas_release_transport(mpt2sas_transport_template);
7152 return -ENODEV;
7153 }
6395 7154
6396 mpt2sas_base_initialize_callback_handler(); 7155 mpt2sas_base_initialize_callback_handler();
6397 7156
6398 /* queuecommand callback hander */ 7157 /* queuecommand callback hander */
6399 scsi_io_cb_idx = mpt2sas_base_register_callback_handler(_scsih_io_done); 7158 scsi_io_cb_idx = mpt2sas_base_register_callback_handler(_scsih_io_done);
6400 7159
6401 /* task managment callback handler */ 7160 /* task management callback handler */
6402 tm_cb_idx = mpt2sas_base_register_callback_handler(_scsih_tm_done); 7161 tm_cb_idx = mpt2sas_base_register_callback_handler(_scsih_tm_done);
6403 7162
6404 /* base internal commands callback handler */ 7163 /* base internal commands callback handler */
@@ -6420,14 +7179,21 @@ _scsih_init(void)
6420 7179
6421 tm_tr_cb_idx = mpt2sas_base_register_callback_handler( 7180 tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
6422 _scsih_tm_tr_complete); 7181 _scsih_tm_tr_complete);
7182
7183 tm_tr_volume_cb_idx = mpt2sas_base_register_callback_handler(
7184 _scsih_tm_volume_tr_complete);
7185
6423 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler( 7186 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
6424 _scsih_sas_control_complete); 7187 _scsih_sas_control_complete);
6425 7188
6426 mpt2sas_ctl_init(); 7189 mpt2sas_ctl_init();
6427 7190
6428 error = pci_register_driver(&scsih_driver); 7191 error = pci_register_driver(&scsih_driver);
6429 if (error) 7192 if (error) {
7193 /* raid transport support */
7194 raid_class_release(mpt2sas_raid_template);
6430 sas_release_transport(mpt2sas_transport_template); 7195 sas_release_transport(mpt2sas_transport_template);
7196 }
6431 7197
6432 return error; 7198 return error;
6433} 7199}
@@ -6445,7 +7211,8 @@ _scsih_exit(void)
6445 7211
6446 pci_unregister_driver(&scsih_driver); 7212 pci_unregister_driver(&scsih_driver);
6447 7213
6448 sas_release_transport(mpt2sas_transport_template); 7214 mpt2sas_ctl_exit();
7215
6449 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 7216 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
6450 mpt2sas_base_release_callback_handler(tm_cb_idx); 7217 mpt2sas_base_release_callback_handler(tm_cb_idx);
6451 mpt2sas_base_release_callback_handler(base_cb_idx); 7218 mpt2sas_base_release_callback_handler(base_cb_idx);
@@ -6455,9 +7222,13 @@ _scsih_exit(void)
6455 mpt2sas_base_release_callback_handler(ctl_cb_idx); 7222 mpt2sas_base_release_callback_handler(ctl_cb_idx);
6456 7223
6457 mpt2sas_base_release_callback_handler(tm_tr_cb_idx); 7224 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
7225 mpt2sas_base_release_callback_handler(tm_tr_volume_cb_idx);
6458 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); 7226 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6459 7227
6460 mpt2sas_ctl_exit(); 7228 /* raid transport support */
7229 raid_class_release(mpt2sas_raid_template);
7230 sas_release_transport(mpt2sas_transport_template);
7231
6461} 7232}
6462 7233
6463module_init(_scsih_init); 7234module_init(_scsih_init);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 3a82872bad4..cb1cdecbe0f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -2,7 +2,7 @@
2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers 2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
5 * Copyright (C) 2007-2009 LSI Corporation 5 * Copyright (C) 2007-2010 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -49,6 +49,7 @@
49#include <linux/workqueue.h> 49#include <linux/workqueue.h>
50#include <linux/delay.h> 50#include <linux/delay.h>
51#include <linux/pci.h> 51#include <linux/pci.h>
52#include <linux/slab.h>
52 53
53#include <scsi/scsi.h> 54#include <scsi/scsi.h>
54#include <scsi/scsi_cmnd.h> 55#include <scsi/scsi_cmnd.h>
@@ -139,7 +140,7 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
139 u32 device_info; 140 u32 device_info;
140 u32 ioc_status; 141 u32 ioc_status;
141 142
142 if (ioc->shost_recovery) { 143 if (ioc->shost_recovery || ioc->pci_error_recovery) {
143 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 144 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
144 __func__, ioc->name); 145 __func__, ioc->name);
145 return -EFAULT; 146 return -EFAULT;
@@ -301,7 +302,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
301 u64 *sas_address_le; 302 u64 *sas_address_le;
302 u16 wait_state_count; 303 u16 wait_state_count;
303 304
304 if (ioc->shost_recovery) { 305 if (ioc->shost_recovery || ioc->pci_error_recovery) {
305 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 306 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
306 __func__, ioc->name); 307 __func__, ioc->name);
307 return -EFAULT; 308 return -EFAULT;
@@ -396,7 +397,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
396 sizeof(struct rep_manu_reply), data_out_dma + 397 sizeof(struct rep_manu_reply), data_out_dma +
397 sizeof(struct rep_manu_request)); 398 sizeof(struct rep_manu_request));
398 399
399 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - " 400 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
400 "send to sas_addr(0x%016llx)\n", ioc->name, 401 "send to sas_addr(0x%016llx)\n", ioc->name,
401 (unsigned long long)sas_address)); 402 (unsigned long long)sas_address));
402 mpt2sas_base_put_smid_default(ioc, smid); 403 mpt2sas_base_put_smid_default(ioc, smid);
@@ -414,7 +415,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
414 goto issue_host_reset; 415 goto issue_host_reset;
415 } 416 }
416 417
417 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - " 418 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
418 "complete\n", ioc->name)); 419 "complete\n", ioc->name));
419 420
420 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 421 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
@@ -422,7 +423,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
422 423
423 mpi_reply = ioc->transport_cmds.reply; 424 mpi_reply = ioc->transport_cmds.reply;
424 425
425 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT 426 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
426 "report_manufacture - reply data transfer size(%d)\n", 427 "report_manufacture - reply data transfer size(%d)\n",
427 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 428 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
428 429
@@ -448,7 +449,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
448 manufacture_reply->component_revision_id; 449 manufacture_reply->component_revision_id;
449 } 450 }
450 } else 451 } else
451 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT 452 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
452 "report_manufacture - no reply\n", ioc->name)); 453 "report_manufacture - no reply\n", ioc->name));
453 454
454 issue_host_reset: 455 issue_host_reset:
@@ -465,6 +466,174 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
465} 466}
466 467
467/** 468/**
469 * _transport_delete_port - helper function to removing a port
470 * @ioc: per adapter object
471 * @mpt2sas_port: mpt2sas per port object
472 *
473 * Returns nothing.
474 */
475static void
476_transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
477 struct _sas_port *mpt2sas_port)
478{
479 u64 sas_address = mpt2sas_port->remote_identify.sas_address;
480 enum sas_device_type device_type =
481 mpt2sas_port->remote_identify.device_type;
482
483 dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
484 "remove: sas_addr(0x%016llx)\n",
485 (unsigned long long) sas_address);
486
487 ioc->logging_level |= MPT_DEBUG_TRANSPORT;
488 if (device_type == SAS_END_DEVICE)
489 mpt2sas_device_remove(ioc, sas_address);
490 else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
491 device_type == SAS_FANOUT_EXPANDER_DEVICE)
492 mpt2sas_expander_remove(ioc, sas_address);
493 ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
494}
495
496/**
497 * _transport_delete_phy - helper function to removing single phy from port
498 * @ioc: per adapter object
499 * @mpt2sas_port: mpt2sas per port object
500 * @mpt2sas_phy: mpt2sas per phy object
501 *
502 * Returns nothing.
503 */
504static void
505_transport_delete_phy(struct MPT2SAS_ADAPTER *ioc,
506 struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy)
507{
508 u64 sas_address = mpt2sas_port->remote_identify.sas_address;
509
510 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
511 "remove: sas_addr(0x%016llx), phy(%d)\n",
512 (unsigned long long) sas_address, mpt2sas_phy->phy_id);
513
514 list_del(&mpt2sas_phy->port_siblings);
515 mpt2sas_port->num_phys--;
516 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
517 mpt2sas_phy->phy_belongs_to_port = 0;
518}
519
520/**
521 * _transport_add_phy - helper function to adding single phy to port
522 * @ioc: per adapter object
523 * @mpt2sas_port: mpt2sas per port object
524 * @mpt2sas_phy: mpt2sas per phy object
525 *
526 * Returns nothing.
527 */
528static void
529_transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port,
530 struct _sas_phy *mpt2sas_phy)
531{
532 u64 sas_address = mpt2sas_port->remote_identify.sas_address;
533
534 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
535 "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
536 sas_address, mpt2sas_phy->phy_id);
537
538 list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list);
539 mpt2sas_port->num_phys++;
540 sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy);
541 mpt2sas_phy->phy_belongs_to_port = 1;
542}
543
544/**
545 * _transport_add_phy_to_an_existing_port - adding new phy to existing port
546 * @ioc: per adapter object
547 * @sas_node: sas node object (either expander or sas host)
548 * @mpt2sas_phy: mpt2sas per phy object
549 * @sas_address: sas address of device/expander were phy needs to be added to
550 *
551 * Returns nothing.
552 */
553static void
554_transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
555struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address)
556{
557 struct _sas_port *mpt2sas_port;
558 struct _sas_phy *phy_srch;
559
560 if (mpt2sas_phy->phy_belongs_to_port == 1)
561 return;
562
563 list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list,
564 port_list) {
565 if (mpt2sas_port->remote_identify.sas_address !=
566 sas_address)
567 continue;
568 list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
569 port_siblings) {
570 if (phy_srch == mpt2sas_phy)
571 return;
572 }
573 _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy);
574 return;
575 }
576
577}
578
579/**
580 * _transport_del_phy_from_an_existing_port - delete phy from existing port
581 * @ioc: per adapter object
582 * @sas_node: sas node object (either expander or sas host)
583 * @mpt2sas_phy: mpt2sas per phy object
584 *
585 * Returns nothing.
586 */
587static void
588_transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
589 struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy)
590{
591 struct _sas_port *mpt2sas_port, *next;
592 struct _sas_phy *phy_srch;
593
594 if (mpt2sas_phy->phy_belongs_to_port == 0)
595 return;
596
597 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
598 port_list) {
599 list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
600 port_siblings) {
601 if (phy_srch != mpt2sas_phy)
602 continue;
603 if (mpt2sas_port->num_phys == 1)
604 _transport_delete_port(ioc, mpt2sas_port);
605 else
606 _transport_delete_phy(ioc, mpt2sas_port,
607 mpt2sas_phy);
608 return;
609 }
610 }
611}
612
613/**
614 * _transport_sanity_check - sanity check when adding a new port
615 * @ioc: per adapter object
616 * @sas_node: sas node object (either expander or sas host)
617 * @sas_address: sas address of device being added
618 *
619 * See the explanation above from _transport_delete_duplicate_port
620 */
621static void
622_transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
623 u64 sas_address)
624{
625 int i;
626
627 for (i = 0; i < sas_node->num_phys; i++) {
628 if (sas_node->phy[i].remote_identify.sas_address != sas_address)
629 continue;
630 if (sas_node->phy[i].phy_belongs_to_port == 1)
631 _transport_del_phy_from_an_existing_port(ioc, sas_node,
632 &sas_node->phy[i]);
633 }
634}
635
636/**
468 * mpt2sas_transport_port_add - insert port to the list 637 * mpt2sas_transport_port_add - insert port to the list
469 * @ioc: per adapter object 638 * @ioc: per adapter object
470 * @handle: handle of attached device 639 * @handle: handle of attached device
@@ -521,6 +690,9 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
521 goto out_fail; 690 goto out_fail;
522 } 691 }
523 692
693 _transport_sanity_check(ioc, sas_node,
694 mpt2sas_port->remote_identify.sas_address);
695
524 for (i = 0; i < sas_node->num_phys; i++) { 696 for (i = 0; i < sas_node->num_phys; i++) {
525 if (sas_node->phy[i].remote_identify.sas_address != 697 if (sas_node->phy[i].remote_identify.sas_address !=
526 mpt2sas_port->remote_identify.sas_address) 698 mpt2sas_port->remote_identify.sas_address)
@@ -552,6 +724,7 @@ mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
552 mpt2sas_port->remote_identify.sas_address, 724 mpt2sas_port->remote_identify.sas_address,
553 mpt2sas_phy->phy_id); 725 mpt2sas_phy->phy_id);
554 sas_port_add_phy(port, mpt2sas_phy->phy); 726 sas_port_add_phy(port, mpt2sas_phy->phy);
727 mpt2sas_phy->phy_belongs_to_port = 1;
555 } 728 }
556 729
557 mpt2sas_port->port = port; 730 mpt2sas_port->port = port;
@@ -650,6 +823,7 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
650 (unsigned long long) 823 (unsigned long long)
651 mpt2sas_port->remote_identify.sas_address, 824 mpt2sas_port->remote_identify.sas_address,
652 mpt2sas_phy->phy_id); 825 mpt2sas_phy->phy_id);
826 mpt2sas_phy->phy_belongs_to_port = 0;
653 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); 827 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
654 list_del(&mpt2sas_phy->port_siblings); 828 list_del(&mpt2sas_phy->port_siblings);
655 } 829 }
@@ -809,7 +983,7 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
809 struct _sas_node *sas_node; 983 struct _sas_node *sas_node;
810 struct _sas_phy *mpt2sas_phy; 984 struct _sas_phy *mpt2sas_phy;
811 985
812 if (ioc->shost_recovery) 986 if (ioc->shost_recovery || ioc->pci_error_recovery)
813 return; 987 return;
814 988
815 spin_lock_irqsave(&ioc->sas_node_lock, flags); 989 spin_lock_irqsave(&ioc->sas_node_lock, flags);
@@ -820,10 +994,12 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
820 994
821 mpt2sas_phy = &sas_node->phy[phy_number]; 995 mpt2sas_phy = &sas_node->phy[phy_number];
822 mpt2sas_phy->attached_handle = handle; 996 mpt2sas_phy->attached_handle = handle;
823 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) 997 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
824 _transport_set_identify(ioc, handle, 998 _transport_set_identify(ioc, handle,
825 &mpt2sas_phy->remote_identify); 999 &mpt2sas_phy->remote_identify);
826 else 1000 _transport_add_phy_to_an_existing_port(ioc, sas_node,
1001 mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address);
1002 } else
827 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct 1003 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
828 sas_identify)); 1004 sas_identify));
829 1005
@@ -855,11 +1031,230 @@ rphy_to_ioc(struct sas_rphy *rphy)
855 return shost_priv(shost); 1031 return shost_priv(shost);
856} 1032}
857 1033
1034
1035/* report phy error log structure */
1036struct phy_error_log_request{
1037 u8 smp_frame_type; /* 0x40 */
1038 u8 function; /* 0x11 */
1039 u8 allocated_response_length;
1040 u8 request_length; /* 02 */
1041 u8 reserved_1[5];
1042 u8 phy_identifier;
1043 u8 reserved_2[2];
1044};
1045
1046/* report phy error log reply structure */
1047struct phy_error_log_reply{
1048 u8 smp_frame_type; /* 0x41 */
1049 u8 function; /* 0x11 */
1050 u8 function_result;
1051 u8 response_length;
1052 u16 expander_change_count;
1053 u8 reserved_1[3];
1054 u8 phy_identifier;
1055 u8 reserved_2[2];
1056 u32 invalid_dword;
1057 u32 running_disparity_error;
1058 u32 loss_of_dword_sync;
1059 u32 phy_reset_problem;
1060};
1061
858/** 1062/**
859 * _transport_get_linkerrors - 1063 * _transport_get_expander_phy_error_log - return expander counters
1064 * @ioc: per adapter object
1065 * @phy: The sas phy object
1066 *
1067 * Returns 0 for success, non-zero for failure.
1068 *
1069 */
1070static int
1071_transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc,
1072 struct sas_phy *phy)
1073{
1074 Mpi2SmpPassthroughRequest_t *mpi_request;
1075 Mpi2SmpPassthroughReply_t *mpi_reply;
1076 struct phy_error_log_request *phy_error_log_request;
1077 struct phy_error_log_reply *phy_error_log_reply;
1078 int rc;
1079 u16 smid;
1080 u32 ioc_state;
1081 unsigned long timeleft;
1082 void *psge;
1083 u32 sgl_flags;
1084 u8 issue_reset = 0;
1085 void *data_out = NULL;
1086 dma_addr_t data_out_dma;
1087 u32 sz;
1088 u64 *sas_address_le;
1089 u16 wait_state_count;
1090
1091 if (ioc->shost_recovery || ioc->pci_error_recovery) {
1092 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1093 __func__, ioc->name);
1094 return -EFAULT;
1095 }
1096
1097 mutex_lock(&ioc->transport_cmds.mutex);
1098
1099 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1100 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
1101 ioc->name, __func__);
1102 rc = -EAGAIN;
1103 goto out;
1104 }
1105 ioc->transport_cmds.status = MPT2_CMD_PENDING;
1106
1107 wait_state_count = 0;
1108 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1109 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1110 if (wait_state_count++ == 10) {
1111 printk(MPT2SAS_ERR_FMT
1112 "%s: failed due to ioc not operational\n",
1113 ioc->name, __func__);
1114 rc = -EFAULT;
1115 goto out;
1116 }
1117 ssleep(1);
1118 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1119 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1120 "operational state(count=%d)\n", ioc->name,
1121 __func__, wait_state_count);
1122 }
1123 if (wait_state_count)
1124 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1125 ioc->name, __func__);
1126
1127 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1128 if (!smid) {
1129 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1130 ioc->name, __func__);
1131 rc = -EAGAIN;
1132 goto out;
1133 }
1134
1135 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1136 ioc->transport_cmds.smid = smid;
1137
1138 sz = sizeof(struct phy_error_log_request) +
1139 sizeof(struct phy_error_log_reply);
1140 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1141 if (!data_out) {
1142 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
1143 __LINE__, __func__);
1144 rc = -ENOMEM;
1145 mpt2sas_base_free_smid(ioc, smid);
1146 goto out;
1147 }
1148
1149 rc = -EINVAL;
1150 memset(data_out, 0, sz);
1151 phy_error_log_request = data_out;
1152 phy_error_log_request->smp_frame_type = 0x40;
1153 phy_error_log_request->function = 0x11;
1154 phy_error_log_request->request_length = 2;
1155 phy_error_log_request->allocated_response_length = 0;
1156 phy_error_log_request->phy_identifier = phy->number;
1157
1158 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1159 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1160 mpi_request->PhysicalPort = 0xFF;
1161 mpi_request->VF_ID = 0; /* TODO */
1162 mpi_request->VP_ID = 0;
1163 sas_address_le = (u64 *)&mpi_request->SASAddress;
1164 *sas_address_le = cpu_to_le64(phy->identify.sas_address);
1165 mpi_request->RequestDataLength =
1166 cpu_to_le16(sizeof(struct phy_error_log_request));
1167 psge = &mpi_request->SGL;
1168
1169 /* WRITE sgel first */
1170 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1171 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1172 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1173 ioc->base_add_sg_single(psge, sgl_flags |
1174 sizeof(struct phy_error_log_request), data_out_dma);
1175
1176 /* incr sgel */
1177 psge += ioc->sge_size;
1178
1179 /* READ sgel last */
1180 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1181 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1182 MPI2_SGE_FLAGS_END_OF_LIST);
1183 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1184 ioc->base_add_sg_single(psge, sgl_flags |
1185 sizeof(struct phy_error_log_reply), data_out_dma +
1186 sizeof(struct phy_error_log_request));
1187
1188 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
1189 "send to sas_addr(0x%016llx), phy(%d)\n", ioc->name,
1190 (unsigned long long)phy->identify.sas_address, phy->number));
1191 mpt2sas_base_put_smid_default(ioc, smid);
1192 init_completion(&ioc->transport_cmds.done);
1193 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1194 10*HZ);
1195
1196 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1197 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1198 ioc->name, __func__);
1199 _debug_dump_mf(mpi_request,
1200 sizeof(Mpi2SmpPassthroughRequest_t)/4);
1201 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1202 issue_reset = 1;
1203 goto issue_host_reset;
1204 }
1205
1206 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
1207 "complete\n", ioc->name));
1208
1209 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1210
1211 mpi_reply = ioc->transport_cmds.reply;
1212
1213 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1214 "phy_error_log - reply data transfer size(%d)\n",
1215 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1216
1217 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1218 sizeof(struct phy_error_log_reply))
1219 goto out;
1220
1221 phy_error_log_reply = data_out +
1222 sizeof(struct phy_error_log_request);
1223
1224 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1225 "phy_error_log - function_result(%d)\n",
1226 ioc->name, phy_error_log_reply->function_result));
1227
1228 phy->invalid_dword_count =
1229 be32_to_cpu(phy_error_log_reply->invalid_dword);
1230 phy->running_disparity_error_count =
1231 be32_to_cpu(phy_error_log_reply->running_disparity_error);
1232 phy->loss_of_dword_sync_count =
1233 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
1234 phy->phy_reset_problem_count =
1235 be32_to_cpu(phy_error_log_reply->phy_reset_problem);
1236 rc = 0;
1237 } else
1238 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1239 "phy_error_log - no reply\n", ioc->name));
1240
1241 issue_host_reset:
1242 if (issue_reset)
1243 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1244 FORCE_BIG_HAMMER);
1245 out:
1246 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1247 if (data_out)
1248 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1249
1250 mutex_unlock(&ioc->transport_cmds.mutex);
1251 return rc;
1252}
1253
1254/**
1255 * _transport_get_linkerrors - return phy counters for both hba and expanders
860 * @phy: The sas phy object 1256 * @phy: The sas phy object
861 * 1257 *
862 * Only support sas_host direct attached phys.
863 * Returns 0 for success, non-zero for failure. 1258 * Returns 0 for success, non-zero for failure.
864 * 1259 *
865 */ 1260 */
@@ -867,23 +1262,24 @@ static int
867_transport_get_linkerrors(struct sas_phy *phy) 1262_transport_get_linkerrors(struct sas_phy *phy)
868{ 1263{
869 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1264 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
870 struct _sas_phy *mpt2sas_phy; 1265 unsigned long flags;
871 Mpi2ConfigReply_t mpi_reply; 1266 Mpi2ConfigReply_t mpi_reply;
872 Mpi2SasPhyPage1_t phy_pg1; 1267 Mpi2SasPhyPage1_t phy_pg1;
873 int i;
874 1268
875 for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys && 1269 spin_lock_irqsave(&ioc->sas_node_lock, flags);
876 !mpt2sas_phy; i++) { 1270 if (_transport_sas_node_find_by_sas_address(ioc,
877 if (ioc->sas_hba.phy[i].phy != phy) 1271 phy->identify.sas_address) == NULL) {
878 continue; 1272 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
879 mpt2sas_phy = &ioc->sas_hba.phy[i]; 1273 return -EINVAL;
880 } 1274 }
1275 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
881 1276
882 if (!mpt2sas_phy) /* this phy not on sas_host */ 1277 if (phy->identify.sas_address != ioc->sas_hba.sas_address)
883 return -EINVAL; 1278 return _transport_get_expander_phy_error_log(ioc, phy);
884 1279
1280 /* get hba phy error logs */
885 if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1, 1281 if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
886 mpt2sas_phy->phy_id))) { 1282 phy->number))) {
887 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1283 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
888 ioc->name, __FILE__, __LINE__, __func__); 1284 ioc->name, __FILE__, __LINE__, __func__);
889 return -ENXIO; 1285 return -ENXIO;
@@ -892,8 +1288,7 @@ _transport_get_linkerrors(struct sas_phy *phy)
892 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) 1288 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
893 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status" 1289 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
894 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 1290 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
895 mpt2sas_phy->phy_id, 1291 phy->number, le16_to_cpu(mpi_reply.IOCStatus),
896 le16_to_cpu(mpi_reply.IOCStatus),
897 le32_to_cpu(mpi_reply.IOCLogInfo)); 1292 le32_to_cpu(mpi_reply.IOCLogInfo));
898 1293
899 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount); 1294 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
@@ -917,18 +1312,18 @@ static int
917_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) 1312_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
918{ 1313{
919 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1314 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
920 struct _sas_node *sas_expander; 1315 struct _sas_device *sas_device;
921 unsigned long flags; 1316 unsigned long flags;
922 1317
923 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1318 spin_lock_irqsave(&ioc->sas_device_lock, flags);
924 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, 1319 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
925 rphy->identify.sas_address); 1320 rphy->identify.sas_address);
926 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1321 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
927 1322
928 if (!sas_expander) 1323 if (!sas_device)
929 return -ENXIO; 1324 return -ENXIO;
930 1325
931 *identifier = sas_expander->enclosure_logical_id; 1326 *identifier = sas_device->enclosure_logical_id;
932 return 0; 1327 return 0;
933} 1328}
934 1329
@@ -956,38 +1351,260 @@ _transport_get_bay_identifier(struct sas_rphy *rphy)
956 return sas_device->slot; 1351 return sas_device->slot;
957} 1352}
958 1353
1354/* phy control request structure */
1355struct phy_control_request{
1356 u8 smp_frame_type; /* 0x40 */
1357 u8 function; /* 0x91 */
1358 u8 allocated_response_length;
1359 u8 request_length; /* 0x09 */
1360 u16 expander_change_count;
1361 u8 reserved_1[3];
1362 u8 phy_identifier;
1363 u8 phy_operation;
1364 u8 reserved_2[13];
1365 u64 attached_device_name;
1366 u8 programmed_min_physical_link_rate;
1367 u8 programmed_max_physical_link_rate;
1368 u8 reserved_3[6];
1369};
1370
1371/* phy control reply structure */
1372struct phy_control_reply{
1373 u8 smp_frame_type; /* 0x41 */
1374 u8 function; /* 0x11 */
1375 u8 function_result;
1376 u8 response_length;
1377};
1378
1379#define SMP_PHY_CONTROL_LINK_RESET (0x01)
1380#define SMP_PHY_CONTROL_HARD_RESET (0x02)
1381#define SMP_PHY_CONTROL_DISABLE (0x03)
1382
1383/**
1384 * _transport_expander_phy_control - expander phy control
1385 * @ioc: per adapter object
1386 * @phy: The sas phy object
1387 *
1388 * Returns 0 for success, non-zero for failure.
1389 *
1390 */
1391static int
1392_transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc,
1393 struct sas_phy *phy, u8 phy_operation)
1394{
1395 Mpi2SmpPassthroughRequest_t *mpi_request;
1396 Mpi2SmpPassthroughReply_t *mpi_reply;
1397 struct phy_control_request *phy_control_request;
1398 struct phy_control_reply *phy_control_reply;
1399 int rc;
1400 u16 smid;
1401 u32 ioc_state;
1402 unsigned long timeleft;
1403 void *psge;
1404 u32 sgl_flags;
1405 u8 issue_reset = 0;
1406 void *data_out = NULL;
1407 dma_addr_t data_out_dma;
1408 u32 sz;
1409 u64 *sas_address_le;
1410 u16 wait_state_count;
1411
1412 if (ioc->shost_recovery) {
1413 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1414 __func__, ioc->name);
1415 return -EFAULT;
1416 }
1417
1418 mutex_lock(&ioc->transport_cmds.mutex);
1419
1420 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1421 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
1422 ioc->name, __func__);
1423 rc = -EAGAIN;
1424 goto out;
1425 }
1426 ioc->transport_cmds.status = MPT2_CMD_PENDING;
1427
1428 wait_state_count = 0;
1429 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1430 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1431 if (wait_state_count++ == 10) {
1432 printk(MPT2SAS_ERR_FMT
1433 "%s: failed due to ioc not operational\n",
1434 ioc->name, __func__);
1435 rc = -EFAULT;
1436 goto out;
1437 }
1438 ssleep(1);
1439 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1440 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1441 "operational state(count=%d)\n", ioc->name,
1442 __func__, wait_state_count);
1443 }
1444 if (wait_state_count)
1445 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1446 ioc->name, __func__);
1447
1448 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1449 if (!smid) {
1450 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1451 ioc->name, __func__);
1452 rc = -EAGAIN;
1453 goto out;
1454 }
1455
1456 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1457 ioc->transport_cmds.smid = smid;
1458
1459 sz = sizeof(struct phy_control_request) +
1460 sizeof(struct phy_control_reply);
1461 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1462 if (!data_out) {
1463 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
1464 __LINE__, __func__);
1465 rc = -ENOMEM;
1466 mpt2sas_base_free_smid(ioc, smid);
1467 goto out;
1468 }
1469
1470 rc = -EINVAL;
1471 memset(data_out, 0, sz);
1472 phy_control_request = data_out;
1473 phy_control_request->smp_frame_type = 0x40;
1474 phy_control_request->function = 0x91;
1475 phy_control_request->request_length = 9;
1476 phy_control_request->allocated_response_length = 0;
1477 phy_control_request->phy_identifier = phy->number;
1478 phy_control_request->phy_operation = phy_operation;
1479 phy_control_request->programmed_min_physical_link_rate =
1480 phy->minimum_linkrate << 4;
1481 phy_control_request->programmed_max_physical_link_rate =
1482 phy->maximum_linkrate << 4;
1483
1484 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1485 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1486 mpi_request->PhysicalPort = 0xFF;
1487 mpi_request->VF_ID = 0; /* TODO */
1488 mpi_request->VP_ID = 0;
1489 sas_address_le = (u64 *)&mpi_request->SASAddress;
1490 *sas_address_le = cpu_to_le64(phy->identify.sas_address);
1491 mpi_request->RequestDataLength =
1492 cpu_to_le16(sizeof(struct phy_error_log_request));
1493 psge = &mpi_request->SGL;
1494
1495 /* WRITE sgel first */
1496 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1497 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1498 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1499 ioc->base_add_sg_single(psge, sgl_flags |
1500 sizeof(struct phy_control_request), data_out_dma);
1501
1502 /* incr sgel */
1503 psge += ioc->sge_size;
1504
1505 /* READ sgel last */
1506 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1507 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1508 MPI2_SGE_FLAGS_END_OF_LIST);
1509 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1510 ioc->base_add_sg_single(psge, sgl_flags |
1511 sizeof(struct phy_control_reply), data_out_dma +
1512 sizeof(struct phy_control_request));
1513
1514 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1515 "send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ioc->name,
1516 (unsigned long long)phy->identify.sas_address, phy->number,
1517 phy_operation));
1518 mpt2sas_base_put_smid_default(ioc, smid);
1519 init_completion(&ioc->transport_cmds.done);
1520 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1521 10*HZ);
1522
1523 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1524 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1525 ioc->name, __func__);
1526 _debug_dump_mf(mpi_request,
1527 sizeof(Mpi2SmpPassthroughRequest_t)/4);
1528 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1529 issue_reset = 1;
1530 goto issue_host_reset;
1531 }
1532
1533 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1534 "complete\n", ioc->name));
1535
1536 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1537
1538 mpi_reply = ioc->transport_cmds.reply;
1539
1540 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1541 "phy_control - reply data transfer size(%d)\n",
1542 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1543
1544 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1545 sizeof(struct phy_control_reply))
1546 goto out;
1547
1548 phy_control_reply = data_out +
1549 sizeof(struct phy_control_request);
1550
1551 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1552 "phy_control - function_result(%d)\n",
1553 ioc->name, phy_control_reply->function_result));
1554
1555 rc = 0;
1556 } else
1557 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1558 "phy_control - no reply\n", ioc->name));
1559
1560 issue_host_reset:
1561 if (issue_reset)
1562 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1563 FORCE_BIG_HAMMER);
1564 out:
1565 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1566 if (data_out)
1567 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1568
1569 mutex_unlock(&ioc->transport_cmds.mutex);
1570 return rc;
1571}
1572
959/** 1573/**
960 * _transport_phy_reset - 1574 * _transport_phy_reset -
961 * @phy: The sas phy object 1575 * @phy: The sas phy object
962 * @hard_reset: 1576 * @hard_reset:
963 * 1577 *
964 * Only support sas_host direct attached phys.
965 * Returns 0 for success, non-zero for failure. 1578 * Returns 0 for success, non-zero for failure.
966 */ 1579 */
967static int 1580static int
968_transport_phy_reset(struct sas_phy *phy, int hard_reset) 1581_transport_phy_reset(struct sas_phy *phy, int hard_reset)
969{ 1582{
970 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1583 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
971 struct _sas_phy *mpt2sas_phy;
972 Mpi2SasIoUnitControlReply_t mpi_reply; 1584 Mpi2SasIoUnitControlReply_t mpi_reply;
973 Mpi2SasIoUnitControlRequest_t mpi_request; 1585 Mpi2SasIoUnitControlRequest_t mpi_request;
974 int i; 1586 unsigned long flags;
975 1587
976 for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys && 1588 spin_lock_irqsave(&ioc->sas_node_lock, flags);
977 !mpt2sas_phy; i++) { 1589 if (_transport_sas_node_find_by_sas_address(ioc,
978 if (ioc->sas_hba.phy[i].phy != phy) 1590 phy->identify.sas_address) == NULL) {
979 continue; 1591 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
980 mpt2sas_phy = &ioc->sas_hba.phy[i]; 1592 return -EINVAL;
981 } 1593 }
1594 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
982 1595
983 if (!mpt2sas_phy) /* this phy not on sas_host */ 1596 /* handle expander phys */
984 return -EINVAL; 1597 if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1598 return _transport_expander_phy_control(ioc, phy,
1599 (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
1600 SMP_PHY_CONTROL_LINK_RESET);
985 1601
1602 /* handle hba phys */
986 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t)); 1603 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
987 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 1604 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
988 mpi_request.Operation = hard_reset ? 1605 mpi_request.Operation = hard_reset ?
989 MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET; 1606 MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
990 mpi_request.PhyNum = mpt2sas_phy->phy_id; 1607 mpi_request.PhyNum = phy->number;
991 1608
992 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) { 1609 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
993 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1610 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -998,14 +1615,208 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset)
998 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) 1615 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
999 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status" 1616 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
1000 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 1617 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
1001 mpt2sas_phy->phy_id, 1618 phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1002 le16_to_cpu(mpi_reply.IOCStatus),
1003 le32_to_cpu(mpi_reply.IOCLogInfo)); 1619 le32_to_cpu(mpi_reply.IOCLogInfo));
1004 1620
1005 return 0; 1621 return 0;
1006} 1622}
1007 1623
1008/** 1624/**
1625 * _transport_phy_enable - enable/disable phys
1626 * @phy: The sas phy object
1627 * @enable: enable phy when true
1628 *
1629 * Only support sas_host direct attached phys.
1630 * Returns 0 for success, non-zero for failure.
1631 */
1632static int
1633_transport_phy_enable(struct sas_phy *phy, int enable)
1634{
1635 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1636 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1637 Mpi2ConfigReply_t mpi_reply;
1638 u16 ioc_status;
1639 u16 sz;
1640 int rc = 0;
1641 unsigned long flags;
1642
1643 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1644 if (_transport_sas_node_find_by_sas_address(ioc,
1645 phy->identify.sas_address) == NULL) {
1646 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1647 return -EINVAL;
1648 }
1649 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1650
1651 /* handle expander phys */
1652 if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1653 return _transport_expander_phy_control(ioc, phy,
1654 (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
1655 SMP_PHY_CONTROL_DISABLE);
1656
1657 /* handle hba phys */
1658
1659 /* sas_iounit page 1 */
1660 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1661 sizeof(Mpi2SasIOUnit1PhyData_t));
1662 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1663 if (!sas_iounit_pg1) {
1664 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1665 ioc->name, __FILE__, __LINE__, __func__);
1666 rc = -ENOMEM;
1667 goto out;
1668 }
1669 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1670 sas_iounit_pg1, sz))) {
1671 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1672 ioc->name, __FILE__, __LINE__, __func__);
1673 rc = -ENXIO;
1674 goto out;
1675 }
1676 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1677 MPI2_IOCSTATUS_MASK;
1678 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1679 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1680 ioc->name, __FILE__, __LINE__, __func__);
1681 rc = -EIO;
1682 goto out;
1683 }
1684
1685 if (enable)
1686 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1687 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1688 else
1689 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1690 |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1691
1692 mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
1693
1694 /* link reset */
1695 if (enable)
1696 _transport_phy_reset(phy, 0);
1697
1698 out:
1699 kfree(sas_iounit_pg1);
1700 return rc;
1701}
1702
1703/**
1704 * _transport_phy_speed - set phy min/max link rates
1705 * @phy: The sas phy object
1706 * @rates: rates defined in sas_phy_linkrates
1707 *
1708 * Only support sas_host direct attached phys.
1709 * Returns 0 for success, non-zero for failure.
1710 */
1711static int
1712_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
1713{
1714 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1715 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1716 Mpi2SasPhyPage0_t phy_pg0;
1717 Mpi2ConfigReply_t mpi_reply;
1718 u16 ioc_status;
1719 u16 sz;
1720 int i;
1721 int rc = 0;
1722 unsigned long flags;
1723
1724 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1725 if (_transport_sas_node_find_by_sas_address(ioc,
1726 phy->identify.sas_address) == NULL) {
1727 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1728 return -EINVAL;
1729 }
1730 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1731
1732 if (!rates->minimum_linkrate)
1733 rates->minimum_linkrate = phy->minimum_linkrate;
1734 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
1735 rates->minimum_linkrate = phy->minimum_linkrate_hw;
1736
1737 if (!rates->maximum_linkrate)
1738 rates->maximum_linkrate = phy->maximum_linkrate;
1739 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
1740 rates->maximum_linkrate = phy->maximum_linkrate_hw;
1741
1742 /* handle expander phys */
1743 if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
1744 phy->minimum_linkrate = rates->minimum_linkrate;
1745 phy->maximum_linkrate = rates->maximum_linkrate;
1746 return _transport_expander_phy_control(ioc, phy,
1747 SMP_PHY_CONTROL_LINK_RESET);
1748 }
1749
1750 /* handle hba phys */
1751
1752 /* sas_iounit page 1 */
1753 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1754 sizeof(Mpi2SasIOUnit1PhyData_t));
1755 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1756 if (!sas_iounit_pg1) {
1757 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1758 ioc->name, __FILE__, __LINE__, __func__);
1759 rc = -ENOMEM;
1760 goto out;
1761 }
1762 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1763 sas_iounit_pg1, sz))) {
1764 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1765 ioc->name, __FILE__, __LINE__, __func__);
1766 rc = -ENXIO;
1767 goto out;
1768 }
1769 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1770 MPI2_IOCSTATUS_MASK;
1771 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1772 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1773 ioc->name, __FILE__, __LINE__, __func__);
1774 rc = -EIO;
1775 goto out;
1776 }
1777
1778 for (i = 0; i < ioc->sas_hba.num_phys; i++) {
1779 if (phy->number != i) {
1780 sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1781 (ioc->sas_hba.phy[i].phy->minimum_linkrate +
1782 (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
1783 } else {
1784 sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1785 (rates->minimum_linkrate +
1786 (rates->maximum_linkrate << 4));
1787 }
1788 }
1789
1790 if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1791 sz)) {
1792 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1793 ioc->name, __FILE__, __LINE__, __func__);
1794 rc = -ENXIO;
1795 goto out;
1796 }
1797
1798 /* link reset */
1799 _transport_phy_reset(phy, 0);
1800
1801 /* read phy page 0, then update the rates in the sas transport phy */
1802 if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
1803 phy->number)) {
1804 phy->minimum_linkrate = _transport_convert_phy_link_rate(
1805 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
1806 phy->maximum_linkrate = _transport_convert_phy_link_rate(
1807 phy_pg0.ProgrammedLinkRate >> 4);
1808 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
1809 phy_pg0.NegotiatedLinkRate &
1810 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
1811 }
1812
1813 out:
1814 kfree(sas_iounit_pg1);
1815 return rc;
1816}
1817
1818
1819/**
1009 * _transport_smp_handler - transport portal for smp passthru 1820 * _transport_smp_handler - transport portal for smp passthru
1010 * @shost: shost object 1821 * @shost: shost object
1011 * @rphy: sas transport rphy object 1822 * @rphy: sas transport rphy object
@@ -1141,7 +1952,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1141 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4), 1952 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4),
1142 dma_addr_in); 1953 dma_addr_in);
1143 1954
1144 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - " 1955 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
1145 "sending smp request\n", ioc->name, __func__)); 1956 "sending smp request\n", ioc->name, __func__));
1146 1957
1147 mpt2sas_base_put_smid_default(ioc, smid); 1958 mpt2sas_base_put_smid_default(ioc, smid);
@@ -1159,14 +1970,14 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1159 goto issue_host_reset; 1970 goto issue_host_reset;
1160 } 1971 }
1161 1972
1162 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - " 1973 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
1163 "complete\n", ioc->name, __func__)); 1974 "complete\n", ioc->name, __func__));
1164 1975
1165 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1976 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1166 1977
1167 mpi_reply = ioc->transport_cmds.reply; 1978 mpi_reply = ioc->transport_cmds.reply;
1168 1979
1169 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT 1980 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1170 "%s - reply data transfer size(%d)\n", 1981 "%s - reply data transfer size(%d)\n",
1171 ioc->name, __func__, 1982 ioc->name, __func__,
1172 le16_to_cpu(mpi_reply->ResponseDataLength))); 1983 le16_to_cpu(mpi_reply->ResponseDataLength)));
@@ -1174,9 +1985,10 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1174 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); 1985 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
1175 req->sense_len = sizeof(*mpi_reply); 1986 req->sense_len = sizeof(*mpi_reply);
1176 req->resid_len = 0; 1987 req->resid_len = 0;
1177 rsp->resid_len -= mpi_reply->ResponseDataLength; 1988 rsp->resid_len -=
1989 le16_to_cpu(mpi_reply->ResponseDataLength);
1178 } else { 1990 } else {
1179 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT 1991 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1180 "%s - no reply\n", ioc->name, __func__)); 1992 "%s - no reply\n", ioc->name, __func__));
1181 rc = -ENXIO; 1993 rc = -ENXIO;
1182 } 1994 }
@@ -1207,6 +2019,8 @@ struct sas_function_template mpt2sas_transport_functions = {
1207 .get_enclosure_identifier = _transport_get_enclosure_identifier, 2019 .get_enclosure_identifier = _transport_get_enclosure_identifier,
1208 .get_bay_identifier = _transport_get_bay_identifier, 2020 .get_bay_identifier = _transport_get_bay_identifier,
1209 .phy_reset = _transport_phy_reset, 2021 .phy_reset = _transport_phy_reset,
2022 .phy_enable = _transport_phy_enable,
2023 .set_phy_speed = _transport_phy_speed,
1210 .smp_handler = _transport_smp_handler, 2024 .smp_handler = _transport_smp_handler,
1211}; 2025};
1212 2026