diff options
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2.h | 10 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 24 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_history.txt | 381 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_init.h | 11 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 8 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 6 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_sas.h | 14 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 55 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 433 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 126 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 44 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 1151 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 185 |
15 files changed, 1569 insertions, 882 deletions
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h index 4b1c2f0350f9..a3e60385787f 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2.h +++ b/drivers/scsi/mpt2sas/mpi/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.15 | 11 | * mpi2.h Version: 02.00.17 |
12 | * | 12 | * |
13 | * Version History | 13 | * Version History |
14 | * --------------- | 14 | * --------------- |
@@ -61,6 +61,9 @@ | |||
61 | * Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL. | 61 | * Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL. |
62 | * Added defines for product-specific range of message | 62 | * Added defines for product-specific range of message |
63 | * function codes, 0xF0 to 0xFF. | 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. | ||
66 | * 08-11-10 02.00.17 Bumped MPI2_HEADER_VERSION_UNIT. | ||
64 | * -------------------------------------------------------------------------- | 67 | * -------------------------------------------------------------------------- |
65 | */ | 68 | */ |
66 | 69 | ||
@@ -86,7 +89,7 @@ | |||
86 | #define MPI2_VERSION_02_00 (0x0200) | 89 | #define MPI2_VERSION_02_00 (0x0200) |
87 | 90 | ||
88 | /* versioning for this MPI header set */ | 91 | /* versioning for this MPI header set */ |
89 | #define MPI2_HEADER_VERSION_UNIT (0x0F) | 92 | #define MPI2_HEADER_VERSION_UNIT (0x11) |
90 | #define MPI2_HEADER_VERSION_DEV (0x00) | 93 | #define MPI2_HEADER_VERSION_DEV (0x00) |
91 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) | 94 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) |
92 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) | 95 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) |
@@ -929,6 +932,9 @@ typedef struct _MPI2_MPI_SGE_UNION | |||
929 | #define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00) | 932 | #define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00) |
930 | #define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04) | 933 | #define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04) |
931 | 934 | ||
935 | #define MPI2_SGE_FLAGS_DEST (MPI2_SGE_FLAGS_IOC_TO_HOST) | ||
936 | #define MPI2_SGE_FLAGS_SOURCE (MPI2_SGE_FLAGS_HOST_TO_IOC) | ||
937 | |||
932 | /* Address Size */ | 938 | /* Address Size */ |
933 | 939 | ||
934 | #define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00) | 940 | #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 e3728d736d85..f5b9c766e28f 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | |||
@@ -6,7 +6,7 @@ | |||
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.14 | 9 | * mpi2_cnfg.h Version: 02.00.16 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -121,6 +121,12 @@ | |||
121 | * Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines. | 121 | * Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines. |
122 | * Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines. | 122 | * Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines. |
123 | * Added MPI2_CONFIG_PAGE_SASIOUNIT_8 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. | ||
128 | * 08-11-10 02.00.16 Removed IO Unit Page 1 device path (multi-pathing) | ||
129 | * defines. | ||
124 | * -------------------------------------------------------------------------- | 130 | * -------------------------------------------------------------------------- |
125 | */ | 131 | */ |
126 | 132 | ||
@@ -333,7 +339,7 @@ typedef struct _MPI2_CONFIG_REQUEST | |||
333 | #define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06) | 339 | #define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06) |
334 | #define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07) | 340 | #define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07) |
335 | 341 | ||
336 | /* values for SGLFlags field are in the SGL section of mpi2.h */ | 342 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ |
337 | 343 | ||
338 | 344 | ||
339 | /* Config Reply Message */ | 345 | /* Config Reply Message */ |
@@ -379,6 +385,8 @@ typedef struct _MPI2_CONFIG_REPLY | |||
379 | #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) | 385 | #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) |
380 | #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) | 386 | #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) |
381 | 387 | ||
388 | #define MPI2_MFGPAGE_DEVID_SSS6200 (0x007E) | ||
389 | |||
382 | #define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) | 390 | #define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) |
383 | #define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) | 391 | #define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) |
384 | #define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) | 392 | #define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) |
@@ -390,6 +398,8 @@ typedef struct _MPI2_CONFIG_REPLY | |||
390 | #define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E) | 398 | #define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E) |
391 | 399 | ||
392 | 400 | ||
401 | |||
402 | |||
393 | /* Manufacturing Page 0 */ | 403 | /* Manufacturing Page 0 */ |
394 | 404 | ||
395 | typedef struct _MPI2_CONFIG_PAGE_MAN_0 | 405 | typedef struct _MPI2_CONFIG_PAGE_MAN_0 |
@@ -729,6 +739,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 | |||
729 | /* IO Unit Page 1 Flags defines */ | 739 | /* IO Unit Page 1 Flags defines */ |
730 | #define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800) | 740 | #define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800) |
731 | #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) | 741 | #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) |
742 | #define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT (9) | ||
732 | #define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) | 743 | #define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) |
733 | #define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) | 744 | #define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) |
734 | #define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400) | 745 | #define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400) |
@@ -736,8 +747,6 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 | |||
736 | #define MPI2_IOUNITPAGE1_DISABLE_IR (0x00000040) | 747 | #define MPI2_IOUNITPAGE1_DISABLE_IR (0x00000040) |
737 | #define MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING (0x00000020) | 748 | #define MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING (0x00000020) |
738 | #define MPI2_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) | 749 | #define MPI2_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) |
739 | #define MPI2_IOUNITPAGE1_MULTI_PATHING (0x00000002) | ||
740 | #define MPI2_IOUNITPAGE1_SINGLE_PATHING (0x00000000) | ||
741 | 750 | ||
742 | 751 | ||
743 | /* IO Unit Page 3 */ | 752 | /* IO Unit Page 3 */ |
@@ -1347,6 +1356,7 @@ typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0 | |||
1347 | #define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000) | 1356 | #define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000) |
1348 | #define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000) | 1357 | #define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000) |
1349 | #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) | ||
1350 | #define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040) | 1360 | #define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040) |
1351 | #define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020) | 1361 | #define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020) |
1352 | #define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000) | 1362 | #define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000) |
@@ -1469,11 +1479,15 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0 | |||
1469 | #define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03) | 1479 | #define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03) |
1470 | #define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04) | 1480 | #define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04) |
1471 | #define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05) | 1481 | #define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05) |
1482 | #define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE (0x06) | ||
1472 | #define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF) | 1483 | #define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF) |
1473 | 1484 | ||
1474 | /* PhysDiskAttributes defines */ | 1485 | /* PhysDiskAttributes defines */ |
1486 | #define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK (0x0C) | ||
1475 | #define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08) | 1487 | #define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08) |
1476 | #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) | ||
1477 | #define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02) | 1491 | #define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02) |
1478 | #define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01) | 1492 | #define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01) |
1479 | 1493 | ||
@@ -1545,6 +1559,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 | |||
1545 | #define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03) | 1559 | #define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03) |
1546 | #define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04) | 1560 | #define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04) |
1547 | #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) | ||
1548 | #define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08) | 1563 | #define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08) |
1549 | #define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09) | 1564 | #define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09) |
1550 | #define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A) | 1565 | #define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A) |
@@ -1571,6 +1586,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 | |||
1571 | #define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) | 1586 | #define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) |
1572 | 1587 | ||
1573 | #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) | ||
1574 | #define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) | 1590 | #define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) |
1575 | #define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) | 1591 | #define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) |
1576 | #define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) | 1592 | #define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) |
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt deleted file mode 100644 index bd6c92b5fae5..000000000000 --- a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt +++ /dev/null | |||
@@ -1,381 +0,0 @@ | |||
1 | ============================== | ||
2 | Fusion-MPT MPI 2.0 Header File Change History | ||
3 | ============================== | ||
4 | |||
5 | Copyright (c) 2000-2010 LSI Corporation. | ||
6 | |||
7 | --------------------------------------- | ||
8 | Header Set Release Version: 02.00.14 | ||
9 | Header Set Release Date: 10-28-09 | ||
10 | --------------------------------------- | ||
11 | |||
12 | Filename Current version Prior version | ||
13 | ---------- --------------- ------------- | ||
14 | mpi2.h 02.00.14 02.00.13 | ||
15 | mpi2_cnfg.h 02.00.13 02.00.12 | ||
16 | mpi2_init.h 02.00.08 02.00.07 | ||
17 | mpi2_ioc.h 02.00.13 02.00.12 | ||
18 | mpi2_raid.h 02.00.04 02.00.04 | ||
19 | mpi2_sas.h 02.00.03 02.00.02 | ||
20 | mpi2_targ.h 02.00.03 02.00.03 | ||
21 | mpi2_tool.h 02.00.04 02.00.04 | ||
22 | mpi2_type.h 02.00.00 02.00.00 | ||
23 | mpi2_ra.h 02.00.00 02.00.00 | ||
24 | mpi2_hbd.h 02.00.00 | ||
25 | mpi2_history.txt 02.00.14 02.00.13 | ||
26 | |||
27 | |||
28 | * Date Version Description | ||
29 | * -------- -------- ------------------------------------------------------ | ||
30 | |||
31 | mpi2.h | ||
32 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
33 | * 06-04-07 02.00.01 Bumped MPI2_HEADER_VERSION_UNIT. | ||
34 | * 06-26-07 02.00.02 Bumped MPI2_HEADER_VERSION_UNIT. | ||
35 | * 08-31-07 02.00.03 Bumped MPI2_HEADER_VERSION_UNIT. | ||
36 | * Moved ReplyPostHostIndex register to offset 0x6C of the | ||
37 | * MPI2_SYSTEM_INTERFACE_REGS and modified the define for | ||
38 | * MPI2_REPLY_POST_HOST_INDEX_OFFSET. | ||
39 | * Added union of request descriptors. | ||
40 | * Added union of reply descriptors. | ||
41 | * 10-31-07 02.00.04 Bumped MPI2_HEADER_VERSION_UNIT. | ||
42 | * Added define for MPI2_VERSION_02_00. | ||
43 | * Fixed the size of the FunctionDependent5 field in the | ||
44 | * MPI2_DEFAULT_REPLY structure. | ||
45 | * 12-18-07 02.00.05 Bumped MPI2_HEADER_VERSION_UNIT. | ||
46 | * Removed the MPI-defined Fault Codes and extended the | ||
47 | * product specific codes up to 0xEFFF. | ||
48 | * Added a sixth key value for the WriteSequence register | ||
49 | * and changed the flush value to 0x0. | ||
50 | * Added message function codes for Diagnostic Buffer Post | ||
51 | * and Diagnsotic Release. | ||
52 | * New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED | ||
53 | * Moved MPI2_VERSION_UNION from mpi2_ioc.h. | ||
54 | * 02-29-08 02.00.06 Bumped MPI2_HEADER_VERSION_UNIT. | ||
55 | * 03-03-08 02.00.07 Bumped MPI2_HEADER_VERSION_UNIT. | ||
56 | * 05-21-08 02.00.08 Bumped MPI2_HEADER_VERSION_UNIT. | ||
57 | * Added #defines for marking a reply descriptor as unused. | ||
58 | * 06-27-08 02.00.09 Bumped MPI2_HEADER_VERSION_UNIT. | ||
59 | * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT. | ||
60 | * Moved LUN field defines from mpi2_init.h. | ||
61 | * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT. | ||
62 | * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT. | ||
63 | * In all request and reply descriptors, replaced VF_ID | ||
64 | * field with MSIxIndex field. | ||
65 | * Removed DevHandle field from | ||
66 | * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those | ||
67 | * bytes reserved. | ||
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. | ||
74 | * -------------------------------------------------------------------------- | ||
75 | |||
76 | mpi2_cnfg.h | ||
77 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
78 | * 06-04-07 02.00.01 Added defines for SAS IO Unit Page 2 PhyFlags. | ||
79 | * Added Manufacturing Page 11. | ||
80 | * Added MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE | ||
81 | * define. | ||
82 | * 06-26-07 02.00.02 Adding generic structure for product-specific | ||
83 | * Manufacturing pages: MPI2_CONFIG_PAGE_MANUFACTURING_PS. | ||
84 | * Rework of BIOS Page 2 configuration page. | ||
85 | * Fixed MPI2_BIOSPAGE2_BOOT_DEVICE to be a union of the | ||
86 | * forms. | ||
87 | * Added configuration pages IOC Page 8 and Driver | ||
88 | * Persistent Mapping Page 0. | ||
89 | * 08-31-07 02.00.03 Modified configuration pages dealing with Integrated | ||
90 | * RAID (Manufacturing Page 4, RAID Volume Pages 0 and 1, | ||
91 | * RAID Physical Disk Pages 0 and 1, RAID Configuration | ||
92 | * Page 0). | ||
93 | * Added new value for AccessStatus field of SAS Device | ||
94 | * Page 0 (_SATA_NEEDS_INITIALIZATION). | ||
95 | * 10-31-07 02.00.04 Added missing SEPDevHandle field to | ||
96 | * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. | ||
97 | * 12-18-07 02.00.05 Modified IO Unit Page 0 to use 32-bit version fields for | ||
98 | * NVDATA. | ||
99 | * Modified IOC Page 7 to use masks and added field for | ||
100 | * SASBroadcastPrimitiveMasks. | ||
101 | * Added MPI2_CONFIG_PAGE_BIOS_4. | ||
102 | * Added MPI2_CONFIG_PAGE_LOG_0. | ||
103 | * 02-29-08 02.00.06 Modified various names to make them 32-character unique. | ||
104 | * Added SAS Device IDs. | ||
105 | * Updated Integrated RAID configuration pages including | ||
106 | * Manufacturing Page 4, IOC Page 6, and RAID Configuration | ||
107 | * Page 0. | ||
108 | * 05-21-08 02.00.07 Added define MPI2_MANPAGE4_MIX_SSD_SAS_SATA. | ||
109 | * Added define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION. | ||
110 | * Fixed define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING. | ||
111 | * Added missing MaxNumRoutedSasAddresses field to | ||
112 | * MPI2_CONFIG_PAGE_EXPANDER_0. | ||
113 | * Added SAS Port Page 0. | ||
114 | * Modified structure layout for | ||
115 | * MPI2_CONFIG_PAGE_DRIVER_MAPPING_0. | ||
116 | * 06-27-08 02.00.08 Changed MPI2_CONFIG_PAGE_RD_PDISK_1 to use | ||
117 | * MPI2_RAID_PHYS_DISK1_PATH_MAX to size the array. | ||
118 | * 10-02-08 02.00.09 Changed MPI2_RAID_PGAD_CONFIGNUM_MASK from 0x0000FFFF | ||
119 | * to 0x000000FF. | ||
120 | * Added two new values for the Physical Disk Coercion Size | ||
121 | * bits in the Flags field of Manufacturing Page 4. | ||
122 | * Added product-specific Manufacturing pages 16 to 31. | ||
123 | * Modified Flags bits for controlling write cache on SATA | ||
124 | * drives in IO Unit Page 1. | ||
125 | * Added new bit to AdditionalControlFlags of SAS IO Unit | ||
126 | * Page 1 to control Invalid Topology Correction. | ||
127 | * Added SupportedPhysDisks field to RAID Volume Page 1 and | ||
128 | * added related defines. | ||
129 | * Added additional defines for RAID Volume Page 0 | ||
130 | * VolumeStatusFlags field. | ||
131 | * Modified meaning of RAID Volume Page 0 VolumeSettings | ||
132 | * define for auto-configure of hot-swap drives. | ||
133 | * Added PhysDiskAttributes field (and related defines) to | ||
134 | * RAID Physical Disk Page 0. | ||
135 | * Added MPI2_SAS_PHYINFO_PHY_VACANT define. | ||
136 | * Added three new DiscoveryStatus bits for SAS IO Unit | ||
137 | * Page 0 and SAS Expander Page 0. | ||
138 | * Removed multiplexing information from SAS IO Unit pages. | ||
139 | * Added BootDeviceWaitTime field to SAS IO Unit Page 4. | ||
140 | * Removed Zone Address Resolved bit from PhyInfo and from | ||
141 | * Expander Page 0 Flags field. | ||
142 | * Added two new AccessStatus values to SAS Device Page 0 | ||
143 | * for indicating routing problems. Added 3 reserved words | ||
144 | * to this page. | ||
145 | * 01-19-09 02.00.10 Fixed defines for GPIOVal field of IO Unit Page 3. | ||
146 | * Inserted missing reserved field into structure for IOC | ||
147 | * Page 6. | ||
148 | * Added more pending task bits to RAID Volume Page 0 | ||
149 | * VolumeStatusFlags defines. | ||
150 | * Added MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED define. | ||
151 | * Added a new DiscoveryStatus bit for SAS IO Unit Page 0 | ||
152 | * and SAS Expander Page 0 to flag a downstream initiator | ||
153 | * when in simplified routing mode. | ||
154 | * Removed SATA Init Failure defines for DiscoveryStatus | ||
155 | * fields of SAS IO Unit Page 0 and SAS Expander Page 0. | ||
156 | * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define. | ||
157 | * Added PortGroups, DmaGroup, and ControlGroup fields to | ||
158 | * SAS Device Page 0. | ||
159 | * 05-06-09 02.00.11 Added structures and defines for IO Unit Page 5 and IO | ||
160 | * Unit Page 6. | ||
161 | * Added expander reduced functionality data to SAS | ||
162 | * Expander Page 0. | ||
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. | ||
173 | * -------------------------------------------------------------------------- | ||
174 | |||
175 | mpi2_init.h | ||
176 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
177 | * 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t. | ||
178 | * 12-18-07 02.00.02 Modified Task Management Target Reset Method defines. | ||
179 | * 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention. | ||
180 | * 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY. | ||
181 | * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. | ||
182 | * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO | ||
183 | * Control field Task Attribute flags. | ||
184 | * Moved LUN field defines to mpi2.h becasue they are | ||
185 | * common to many structures. | ||
186 | * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to | ||
187 | * Query Asynchronous Event. | ||
188 | * Defined two new bits in the SlotStatus field of the SCSI | ||
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. | ||
194 | * -------------------------------------------------------------------------- | ||
195 | |||
196 | mpi2_ioc.h | ||
197 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
198 | * 06-04-07 02.00.01 In IOCFacts Reply structure, renamed MaxDevices to | ||
199 | * MaxTargets. | ||
200 | * Added TotalImageSize field to FWDownload Request. | ||
201 | * Added reserved words to FWUpload Request. | ||
202 | * 06-26-07 02.00.02 Added IR Configuration Change List Event. | ||
203 | * 08-31-07 02.00.03 Removed SystemReplyQueueDepth field from the IOCInit | ||
204 | * request and replaced it with | ||
205 | * ReplyDescriptorPostQueueDepth and ReplyFreeQueueDepth. | ||
206 | * Replaced the MinReplyQueueDepth field of the IOCFacts | ||
207 | * reply with MaxReplyDescriptorPostQueueDepth. | ||
208 | * Added MPI2_RDPQ_DEPTH_MIN define to specify the minimum | ||
209 | * depth for the Reply Descriptor Post Queue. | ||
210 | * Added SASAddress field to Initiator Device Table | ||
211 | * Overflow Event data. | ||
212 | * 10-31-07 02.00.04 Added ReasonCode MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING | ||
213 | * for SAS Initiator Device Status Change Event data. | ||
214 | * Modified Reason Code defines for SAS Topology Change | ||
215 | * List Event data, including adding a bit for PHY Vacant | ||
216 | * status, and adding a mask for the Reason Code. | ||
217 | * Added define for | ||
218 | * MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING. | ||
219 | * Added define for MPI2_EXT_IMAGE_TYPE_MEGARAID. | ||
220 | * 12-18-07 02.00.05 Added Boot Status defines for the IOCExceptions field of | ||
221 | * the IOCFacts Reply. | ||
222 | * Removed MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. | ||
223 | * Moved MPI2_VERSION_UNION to mpi2.h. | ||
224 | * Changed MPI2_EVENT_NOTIFICATION_REQUEST to use masks | ||
225 | * instead of enables, and added SASBroadcastPrimitiveMasks | ||
226 | * field. | ||
227 | * Added Log Entry Added Event and related structure. | ||
228 | * 02-29-08 02.00.06 Added define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID. | ||
229 | * Removed define MPI2_IOCFACTS_PROTOCOL_SMP_TARGET. | ||
230 | * Added MaxVolumes and MaxPersistentEntries fields to | ||
231 | * IOCFacts reply. | ||
232 | * Added ProtocalFlags and IOCCapabilities fields to | ||
233 | * MPI2_FW_IMAGE_HEADER. | ||
234 | * Removed MPI2_PORTENABLE_FLAGS_ENABLE_SINGLE_PORT. | ||
235 | * 03-03-08 02.00.07 Fixed MPI2_FW_IMAGE_HEADER by changing Reserved26 to | ||
236 | * a U16 (from a U32). | ||
237 | * Removed extra 's' from EventMasks name. | ||
238 | * 06-27-08 02.00.08 Fixed an offset in a comment. | ||
239 | * 10-02-08 02.00.09 Removed SystemReplyFrameSize from MPI2_IOC_INIT_REQUEST. | ||
240 | * Removed CurReplyFrameSize from MPI2_IOC_FACTS_REPLY and | ||
241 | * renamed MinReplyFrameSize to ReplyFrameSize. | ||
242 | * Added MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX. | ||
243 | * Added two new RAIDOperation values for Integrated RAID | ||
244 | * Operations Status Event data. | ||
245 | * Added four new IR Configuration Change List Event data | ||
246 | * ReasonCode values. | ||
247 | * Added two new ReasonCode defines for SAS Device Status | ||
248 | * Change Event data. | ||
249 | * Added three new DiscoveryStatus bits for the SAS | ||
250 | * Discovery event data. | ||
251 | * Added Multiplexing Status Change bit to the PhyStatus | ||
252 | * field of the SAS Topology Change List event data. | ||
253 | * Removed define for MPI2_INIT_IMAGE_BOOTFLAGS_XMEMCOPY. | ||
254 | * BootFlags are now product-specific. | ||
255 | * Added defines for the indivdual signature bytes | ||
256 | * for MPI2_INIT_IMAGE_FOOTER. | ||
257 | * 01-19-09 02.00.10 Added MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY define. | ||
258 | * Added MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR | ||
259 | * define. | ||
260 | * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE | ||
261 | * define. | ||
262 | * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define. | ||
263 | * 05-06-09 02.00.11 Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define. | ||
264 | * Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define. | ||
265 | * Added two new reason codes for SAS Device Status Change | ||
266 | * Event. | ||
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_). | ||
282 | * -------------------------------------------------------------------------- | ||
283 | |||
284 | mpi2_raid.h | ||
285 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
286 | * 08-31-07 02.00.01 Modifications to RAID Action request and reply, | ||
287 | * including the Actions and ActionData. | ||
288 | * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD. | ||
289 | * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that | ||
290 | * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT | ||
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 | * -------------------------------------------------------------------------- | ||
295 | |||
296 | mpi2_sas.h | ||
297 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
298 | * 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit | ||
299 | * Control Request. | ||
300 | * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control | ||
301 | * Request. | ||
302 | * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST | ||
303 | * to MPI2_SGE_IO_UNION since it supports chained SGLs. | ||
304 | * -------------------------------------------------------------------------- | ||
305 | |||
306 | mpi2_targ.h | ||
307 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
308 | * 08-31-07 02.00.01 Added Command Buffer Data Location Address Space bits to | ||
309 | * BufferPostFlags field of CommandBufferPostBase Request. | ||
310 | * 02-29-08 02.00.02 Modified various names to make them 32-character unique. | ||
311 | * 10-02-08 02.00.03 Removed NextCmdBufferOffset from | ||
312 | * MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST. | ||
313 | * Target Status Send Request only takes a single SGE for | ||
314 | * response data. | ||
315 | * -------------------------------------------------------------------------- | ||
316 | |||
317 | mpi2_tool.h | ||
318 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
319 | * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release | ||
320 | * structures and defines. | ||
321 | * 02-29-08 02.00.02 Modified various names to make them 32-character unique. | ||
322 | * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. | ||
323 | * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request | ||
324 | * and reply messages. | ||
325 | * Added MPI2_DIAG_BUF_TYPE_EXTENDED. | ||
326 | * Incremented MPI2_DIAG_BUF_TYPE_COUNT. | ||
327 | * -------------------------------------------------------------------------- | ||
328 | |||
329 | mpi2_type.h | ||
330 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. | ||
331 | * -------------------------------------------------------------------------- | ||
332 | |||
333 | mpi2_ra.h | ||
334 | * 05-06-09 02.00.00 Initial version. | ||
335 | * -------------------------------------------------------------------------- | ||
336 | |||
337 | mpi2_hbd.h | ||
338 | * 10-28-09 02.00.00 Initial version. | ||
339 | * -------------------------------------------------------------------------- | ||
340 | |||
341 | |||
342 | mpi2_history.txt Parts list history | ||
343 | |||
344 | Filename 02.00.14 02.00.13 02.00.12 | ||
345 | ---------- -------- -------- -------- | ||
346 | mpi2.h 02.00.14 02.00.13 02.00.12 | ||
347 | mpi2_cnfg.h 02.00.13 02.00.12 02.00.11 | ||
348 | mpi2_init.h 02.00.08 02.00.07 02.00.07 | ||
349 | mpi2_ioc.h 02.00.13 02.00.12 02.00.11 | ||
350 | mpi2_raid.h 02.00.04 02.00.04 02.00.03 | ||
351 | mpi2_sas.h 02.00.03 02.00.02 02.00.02 | ||
352 | mpi2_targ.h 02.00.03 02.00.03 02.00.03 | ||
353 | mpi2_tool.h 02.00.04 02.00.04 02.00.03 | ||
354 | mpi2_type.h 02.00.00 02.00.00 02.00.00 | ||
355 | mpi2_ra.h 02.00.00 02.00.00 02.00.00 | ||
356 | mpi2_hbd.h 02.00.00 | ||
357 | |||
358 | Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 | ||
359 | ---------- -------- -------- -------- -------- -------- -------- | ||
360 | mpi2.h 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 | ||
361 | mpi2_cnfg.h 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 02.00.06 | ||
362 | mpi2_init.h 02.00.06 02.00.06 02.00.05 02.00.05 02.00.04 02.00.03 | ||
363 | mpi2_ioc.h 02.00.10 02.00.09 02.00.08 02.00.07 02.00.07 02.00.06 | ||
364 | mpi2_raid.h 02.00.03 02.00.03 02.00.03 02.00.03 02.00.02 02.00.02 | ||
365 | mpi2_sas.h 02.00.02 02.00.02 02.00.01 02.00.01 02.00.01 02.00.01 | ||
366 | mpi2_targ.h 02.00.03 02.00.03 02.00.02 02.00.02 02.00.02 02.00.02 | ||
367 | mpi2_tool.h 02.00.02 02.00.02 02.00.02 02.00.02 02.00.02 02.00.02 | ||
368 | mpi2_type.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 | ||
369 | |||
370 | Filename 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00 | ||
371 | ---------- -------- -------- -------- -------- -------- -------- | ||
372 | mpi2.h 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00 | ||
373 | mpi2_cnfg.h 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00 | ||
374 | mpi2_init.h 02.00.02 02.00.01 02.00.00 02.00.00 02.00.00 02.00.00 | ||
375 | mpi2_ioc.h 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00 | ||
376 | mpi2_raid.h 02.00.01 02.00.01 02.00.01 02.00.00 02.00.00 02.00.00 | ||
377 | mpi2_sas.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.00 02.00.00 | ||
378 | mpi2_targ.h 02.00.01 02.00.01 02.00.01 02.00.00 02.00.00 02.00.00 | ||
379 | mpi2_tool.h 02.00.01 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 | ||
380 | mpi2_type.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 | ||
381 | |||
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h index c4c99dfcb820..165454d52591 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h | |||
@@ -6,7 +6,7 @@ | |||
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.09 | 9 | * mpi2_init.h Version: 02.00.10 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -21,7 +21,7 @@ | |||
21 | * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. | 21 | * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. |
22 | * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO | 22 | * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO |
23 | * Control field Task Attribute flags. | 23 | * Control field Task Attribute flags. |
24 | * Moved LUN field defines to mpi2.h becasue they are | 24 | * Moved LUN field defines to mpi2.h because they are |
25 | * common to many structures. | 25 | * common to many structures. |
26 | * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to | 26 | * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to |
27 | * Query Asynchronous Event. | 27 | * Query Asynchronous Event. |
@@ -32,6 +32,7 @@ | |||
32 | * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. | 32 | * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. |
33 | * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define. | 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. | 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. | ||
35 | * -------------------------------------------------------------------------- | 36 | * -------------------------------------------------------------------------- |
36 | */ | 37 | */ |
37 | 38 | ||
@@ -98,7 +99,13 @@ typedef struct _MPI2_SCSI_IO_REQUEST | |||
98 | U8 LUN[8]; /* 0x34 */ | 99 | U8 LUN[8]; /* 0x34 */ |
99 | U32 Control; /* 0x3C */ | 100 | U32 Control; /* 0x3C */ |
100 | 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 | |||
101 | MPI2_SGE_IO_UNION SGL; /* 0x60 */ | 107 | MPI2_SGE_IO_UNION SGL; /* 0x60 */ |
108 | |||
102 | } MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST, | 109 | } MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST, |
103 | Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t; | 110 | Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t; |
104 | 111 | ||
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h index 495bedc4d1f7..761cbdb8a033 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | |||
@@ -6,7 +6,7 @@ | |||
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.14 | 9 | * mpi2_ioc.h Version: 02.00.15 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -101,6 +101,8 @@ | |||
101 | * 02-10-10 02.00.14 Added SAS Quiesce Event structure and defines. | 101 | * 02-10-10 02.00.14 Added SAS Quiesce Event structure and defines. |
102 | * Added PowerManagementControl Request structures and | 102 | * Added PowerManagementControl Request structures and |
103 | * defines. | 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. | ||
104 | * -------------------------------------------------------------------------- | 106 | * -------------------------------------------------------------------------- |
105 | */ | 107 | */ |
106 | 108 | ||
@@ -456,7 +458,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY | |||
456 | #define MPI2_EVENT_STATE_CHANGE (0x0002) | 458 | #define MPI2_EVENT_STATE_CHANGE (0x0002) |
457 | #define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005) | 459 | #define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005) |
458 | #define MPI2_EVENT_EVENT_CHANGE (0x000A) | 460 | #define MPI2_EVENT_EVENT_CHANGE (0x000A) |
459 | #define MPI2_EVENT_TASK_SET_FULL (0x000E) | 461 | #define MPI2_EVENT_TASK_SET_FULL (0x000E) /* obsolete */ |
460 | #define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F) | 462 | #define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F) |
461 | #define MPI2_EVENT_IR_OPERATION_STATUS (0x0014) | 463 | #define MPI2_EVENT_IR_OPERATION_STATUS (0x0014) |
462 | #define MPI2_EVENT_SAS_DISCOVERY (0x0016) | 464 | #define MPI2_EVENT_SAS_DISCOVERY (0x0016) |
@@ -517,6 +519,7 @@ typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED | |||
517 | MPI2_POINTER pMpi2EventDataHardResetReceived_t; | 519 | MPI2_POINTER pMpi2EventDataHardResetReceived_t; |
518 | 520 | ||
519 | /* Task Set Full Event data */ | 521 | /* Task Set Full Event data */ |
522 | /* this event is obsolete */ | ||
520 | 523 | ||
521 | typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL | 524 | typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL |
522 | { | 525 | { |
@@ -831,6 +834,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST | |||
831 | #define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03) | 834 | #define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03) |
832 | #define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04) | 835 | #define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04) |
833 | #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) | ||
834 | #define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08) | 838 | #define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08) |
835 | #define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09) | 839 | #define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09) |
836 | #define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A) | 840 | #define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A) |
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h index 5160c33d2a00..bd61a7b60a2b 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 2d8aeed51392..fdffde1ebc0f 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.03 | 9 | * mpi2_sas.h Version: 02.00.05 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -20,6 +20,8 @@ | |||
20 | * Request. | 20 | * Request. |
21 | * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_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. | 22 | * to MPI2_SGE_IO_UNION since it supports chained SGLs. |
23 | * 05-12-10 02.00.04 Modified some comments. | ||
24 | * 08-11-10 02.00.05 Added NCQ operations to SAS IO Unit Control. | ||
23 | * -------------------------------------------------------------------------- | 25 | * -------------------------------------------------------------------------- |
24 | */ | 26 | */ |
25 | 27 | ||
@@ -110,7 +112,7 @@ typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST | |||
110 | /* values for PassthroughFlags field */ | 112 | /* values for PassthroughFlags field */ |
111 | #define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) | 113 | #define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) |
112 | 114 | ||
113 | /* values for SGLFlags field are in the SGL section of mpi2.h */ | 115 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ |
114 | 116 | ||
115 | 117 | ||
116 | /* SMP Passthrough Reply Message */ | 118 | /* SMP Passthrough Reply Message */ |
@@ -162,7 +164,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST | |||
162 | U32 Reserved4; /* 0x14 */ | 164 | U32 Reserved4; /* 0x14 */ |
163 | U32 DataLength; /* 0x18 */ | 165 | U32 DataLength; /* 0x18 */ |
164 | U8 CommandFIS[20]; /* 0x1C */ | 166 | U8 CommandFIS[20]; /* 0x1C */ |
165 | MPI2_SGE_IO_UNION SGL; /* 0x20 */ | 167 | MPI2_SGE_IO_UNION SGL; /* 0x30 */ |
166 | } MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST, | 168 | } MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST, |
167 | Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t; | 169 | Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t; |
168 | 170 | ||
@@ -174,7 +176,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST | |||
174 | #define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002) | 176 | #define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002) |
175 | #define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001) | 177 | #define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001) |
176 | 178 | ||
177 | /* values for SGLFlags field are in the SGL section of mpi2.h */ | 179 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ |
178 | 180 | ||
179 | 181 | ||
180 | /* SATA Passthrough Reply Message */ | 182 | /* SATA Passthrough Reply Message */ |
@@ -245,6 +247,8 @@ typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST | |||
245 | #define MPI2_SAS_OP_REMOVE_DEVICE (0x0D) | 247 | #define MPI2_SAS_OP_REMOVE_DEVICE (0x0D) |
246 | #define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E) | 248 | #define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E) |
247 | #define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F) | 249 | #define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F) |
250 | #define MPI2_SAS_OP_DEV_ENABLE_NCQ (0x14) | ||
251 | #define MPI2_SAS_OP_DEV_DISABLE_NCQ (0x15) | ||
248 | #define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80) | 252 | #define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80) |
249 | 253 | ||
250 | /* values for the PrimFlags field */ | 254 | /* values for the PrimFlags field */ |
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h index 686b09b81219..2a4bceda364b 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h | |||
@@ -6,7 +6,7 @@ | |||
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.06 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -22,6 +22,9 @@ | |||
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. | ||
26 | * 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer | ||
27 | * Post Request. | ||
25 | * -------------------------------------------------------------------------- | 28 | * -------------------------------------------------------------------------- |
26 | */ | 29 | */ |
27 | 30 | ||
@@ -37,6 +40,7 @@ | |||
37 | /* defines for the Tools */ | 40 | /* defines for the Tools */ |
38 | #define MPI2_TOOLBOX_CLEAN_TOOL (0x00) | 41 | #define MPI2_TOOLBOX_CLEAN_TOOL (0x00) |
39 | #define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) | 42 | #define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) |
43 | #define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) | ||
40 | #define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) | 44 | #define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) |
41 | #define MPI2_TOOLBOX_BEACON_TOOL (0x05) | 45 | #define MPI2_TOOLBOX_BEACON_TOOL (0x05) |
42 | #define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) | 46 | #define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) |
@@ -102,8 +106,7 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST | |||
102 | * Toolbox Memory Move request | 106 | * Toolbox Memory Move request |
103 | ****************************************************************************/ | 107 | ****************************************************************************/ |
104 | 108 | ||
105 | typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST | 109 | typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST { |
106 | { | ||
107 | U8 Tool; /* 0x00 */ | 110 | U8 Tool; /* 0x00 */ |
108 | U8 Reserved1; /* 0x01 */ | 111 | U8 Reserved1; /* 0x01 */ |
109 | U8 ChainOffset; /* 0x02 */ | 112 | U8 ChainOffset; /* 0x02 */ |
@@ -120,6 +123,44 @@ typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST | |||
120 | 123 | ||
121 | 124 | ||
122 | /**************************************************************************** | 125 | /**************************************************************************** |
126 | * Toolbox Diagnostic Data Upload request | ||
127 | ****************************************************************************/ | ||
128 | |||
129 | typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST { | ||
130 | U8 Tool; /* 0x00 */ | ||
131 | U8 Reserved1; /* 0x01 */ | ||
132 | U8 ChainOffset; /* 0x02 */ | ||
133 | U8 Function; /* 0x03 */ | ||
134 | U16 Reserved2; /* 0x04 */ | ||
135 | U8 Reserved3; /* 0x06 */ | ||
136 | U8 MsgFlags; /* 0x07 */ | ||
137 | U8 VP_ID; /* 0x08 */ | ||
138 | U8 VF_ID; /* 0x09 */ | ||
139 | U16 Reserved4; /* 0x0A */ | ||
140 | U8 SGLFlags; /* 0x0C */ | ||
141 | U8 Reserved5; /* 0x0D */ | ||
142 | U16 Reserved6; /* 0x0E */ | ||
143 | U32 Flags; /* 0x10 */ | ||
144 | U32 DataLength; /* 0x14 */ | ||
145 | MPI2_SGE_SIMPLE_UNION SGL; /* 0x18 */ | ||
146 | } MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, | ||
147 | MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, | ||
148 | Mpi2ToolboxDiagDataUploadRequest_t, | ||
149 | MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t; | ||
150 | |||
151 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ | ||
152 | |||
153 | |||
154 | typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER { | ||
155 | U32 DiagDataLength; /* 00h */ | ||
156 | U8 FormatCode; /* 04h */ | ||
157 | U8 Reserved1; /* 05h */ | ||
158 | U16 Reserved2; /* 06h */ | ||
159 | } MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER, | ||
160 | Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t; | ||
161 | |||
162 | |||
163 | /**************************************************************************** | ||
123 | * Toolbox ISTWI Read Write Tool | 164 | * Toolbox ISTWI Read Write Tool |
124 | ****************************************************************************/ | 165 | ****************************************************************************/ |
125 | 166 | ||
@@ -162,7 +203,7 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST { | |||
162 | #define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) | 203 | #define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) |
163 | #define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) | 204 | #define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) |
164 | 205 | ||
165 | /* values for SGLFlags field are in the SGL section of mpi2.h */ | 206 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ |
166 | 207 | ||
167 | 208 | ||
168 | /* Toolbox ISTWI Read Write Tool reply message */ | 209 | /* Toolbox ISTWI Read Write Tool reply message */ |
@@ -248,7 +289,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { | |||
248 | Mpi2ToolboxDiagnosticCliRequest_t, | 289 | Mpi2ToolboxDiagnosticCliRequest_t, |
249 | MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t; | 290 | MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t; |
250 | 291 | ||
251 | /* values for SGLFlags field are in the SGL section of mpi2.h */ | 292 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ |
252 | 293 | ||
253 | 294 | ||
254 | /* Toolbox Diagnostic CLI Tool reply message */ | 295 | /* Toolbox Diagnostic CLI Tool reply message */ |
@@ -315,6 +356,10 @@ typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST | |||
315 | /* count of the number of buffer types */ | 356 | /* count of the number of buffer types */ |
316 | #define MPI2_DIAG_BUF_TYPE_COUNT (0x03) | 357 | #define MPI2_DIAG_BUF_TYPE_COUNT (0x03) |
317 | 358 | ||
359 | /* values for the Flags field */ | ||
360 | #define MPI2_DIAG_BUF_FLAG_RELEASE_ON_FULL (0x00000002) | ||
361 | #define MPI2_DIAG_BUF_FLAG_IMMEDIATE_RELEASE (0x00000001) | ||
362 | |||
318 | 363 | ||
319 | /**************************************************************************** | 364 | /**************************************************************************** |
320 | * Diagnostic Buffer Post reply | 365 | * Diagnostic Buffer Post reply |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 57bcd5c9dcff..efa0255491c2 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -65,7 +65,6 @@ | |||
65 | static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; | 65 | static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; |
66 | 66 | ||
67 | #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ | 67 | #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ |
68 | #define MPT2SAS_MAX_REQUEST_QUEUE 600 /* maximum controller queue depth */ | ||
69 | 68 | ||
70 | static int max_queue_depth = -1; | 69 | static int max_queue_depth = -1; |
71 | module_param(max_queue_depth, int, 0); | 70 | module_param(max_queue_depth, int, 0); |
@@ -79,6 +78,10 @@ static int msix_disable = -1; | |||
79 | module_param(msix_disable, int, 0); | 78 | module_param(msix_disable, int, 0); |
80 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); | 79 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); |
81 | 80 | ||
81 | static int missing_delay[2] = {-1, -1}; | ||
82 | module_param_array(missing_delay, int, NULL, 0); | ||
83 | MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); | ||
84 | |||
82 | /* diag_buffer_enable is bitwise | 85 | /* diag_buffer_enable is bitwise |
83 | * bit 0 set = TRACE | 86 | * bit 0 set = TRACE |
84 | * bit 1 set = SNAPSHOT | 87 | * bit 1 set = SNAPSHOT |
@@ -515,14 +518,12 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
515 | case MPI2_EVENT_EVENT_CHANGE: | 518 | case MPI2_EVENT_EVENT_CHANGE: |
516 | desc = "Event Change"; | 519 | desc = "Event Change"; |
517 | break; | 520 | break; |
518 | case MPI2_EVENT_TASK_SET_FULL: | ||
519 | desc = "Task Set Full"; | ||
520 | break; | ||
521 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | 521 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: |
522 | desc = "Device Status Change"; | 522 | desc = "Device Status Change"; |
523 | break; | 523 | break; |
524 | case MPI2_EVENT_IR_OPERATION_STATUS: | 524 | case MPI2_EVENT_IR_OPERATION_STATUS: |
525 | desc = "IR Operation Status"; | 525 | if (!ioc->hide_ir_msg) |
526 | desc = "IR Operation Status"; | ||
526 | break; | 527 | break; |
527 | case MPI2_EVENT_SAS_DISCOVERY: | 528 | case MPI2_EVENT_SAS_DISCOVERY: |
528 | { | 529 | { |
@@ -534,7 +535,7 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
534 | if (event_data->DiscoveryStatus) | 535 | if (event_data->DiscoveryStatus) |
535 | printk("discovery_status(0x%08x)", | 536 | printk("discovery_status(0x%08x)", |
536 | le32_to_cpu(event_data->DiscoveryStatus)); | 537 | le32_to_cpu(event_data->DiscoveryStatus)); |
537 | printk("\n"); | 538 | printk("\n"); |
538 | return; | 539 | return; |
539 | } | 540 | } |
540 | case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: | 541 | case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: |
@@ -553,16 +554,20 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
553 | desc = "SAS Enclosure Device Status Change"; | 554 | desc = "SAS Enclosure Device Status Change"; |
554 | break; | 555 | break; |
555 | case MPI2_EVENT_IR_VOLUME: | 556 | case MPI2_EVENT_IR_VOLUME: |
556 | desc = "IR Volume"; | 557 | if (!ioc->hide_ir_msg) |
558 | desc = "IR Volume"; | ||
557 | break; | 559 | break; |
558 | case MPI2_EVENT_IR_PHYSICAL_DISK: | 560 | case MPI2_EVENT_IR_PHYSICAL_DISK: |
559 | desc = "IR Physical Disk"; | 561 | if (!ioc->hide_ir_msg) |
562 | desc = "IR Physical Disk"; | ||
560 | break; | 563 | break; |
561 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: | 564 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: |
562 | desc = "IR Configuration Change List"; | 565 | if (!ioc->hide_ir_msg) |
566 | desc = "IR Configuration Change List"; | ||
563 | break; | 567 | break; |
564 | case MPI2_EVENT_LOG_ENTRY_ADDED: | 568 | case MPI2_EVENT_LOG_ENTRY_ADDED: |
565 | desc = "Log Entry Added"; | 569 | if (!ioc->hide_ir_msg) |
570 | desc = "Log Entry Added"; | ||
566 | break; | 571 | break; |
567 | } | 572 | } |
568 | 573 | ||
@@ -616,7 +621,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) | |||
616 | originator_str = "PL"; | 621 | originator_str = "PL"; |
617 | break; | 622 | break; |
618 | case 2: | 623 | case 2: |
619 | originator_str = "IR"; | 624 | if (!ioc->hide_ir_msg) |
625 | originator_str = "IR"; | ||
626 | else | ||
627 | originator_str = "WarpDrive"; | ||
620 | break; | 628 | break; |
621 | } | 629 | } |
622 | 630 | ||
@@ -752,20 +760,19 @@ static u8 | |||
752 | _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid) | 760 | _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid) |
753 | { | 761 | { |
754 | int i; | 762 | int i; |
755 | u8 cb_idx = 0xFF; | 763 | u8 cb_idx; |
756 | 764 | ||
757 | if (smid >= ioc->hi_priority_smid) { | 765 | if (smid < ioc->hi_priority_smid) { |
758 | if (smid < ioc->internal_smid) { | ||
759 | i = smid - ioc->hi_priority_smid; | ||
760 | cb_idx = ioc->hpr_lookup[i].cb_idx; | ||
761 | } else { | ||
762 | i = smid - ioc->internal_smid; | ||
763 | cb_idx = ioc->internal_lookup[i].cb_idx; | ||
764 | } | ||
765 | } else { | ||
766 | i = smid - 1; | 766 | i = smid - 1; |
767 | cb_idx = ioc->scsi_lookup[i].cb_idx; | 767 | cb_idx = ioc->scsi_lookup[i].cb_idx; |
768 | } | 768 | } else if (smid < ioc->internal_smid) { |
769 | i = smid - ioc->hi_priority_smid; | ||
770 | cb_idx = ioc->hpr_lookup[i].cb_idx; | ||
771 | } else if (smid <= ioc->hba_queue_depth) { | ||
772 | i = smid - ioc->internal_smid; | ||
773 | cb_idx = ioc->internal_lookup[i].cb_idx; | ||
774 | } else | ||
775 | cb_idx = 0xFF; | ||
769 | return cb_idx; | 776 | return cb_idx; |
770 | } | 777 | } |
771 | 778 | ||
@@ -848,6 +855,7 @@ _base_interrupt(int irq, void *bus_id) | |||
848 | return IRQ_NONE; | 855 | return IRQ_NONE; |
849 | 856 | ||
850 | completed_cmds = 0; | 857 | completed_cmds = 0; |
858 | cb_idx = 0xFF; | ||
851 | do { | 859 | do { |
852 | rd.word = rpf->Words; | 860 | rd.word = rpf->Words; |
853 | if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) | 861 | if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) |
@@ -860,6 +868,9 @@ _base_interrupt(int irq, void *bus_id) | |||
860 | MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { | 868 | MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { |
861 | reply = le32_to_cpu | 869 | reply = le32_to_cpu |
862 | (rpf->AddressReply.ReplyFrameAddress); | 870 | (rpf->AddressReply.ReplyFrameAddress); |
871 | if (reply > ioc->reply_dma_max_address || | ||
872 | reply < ioc->reply_dma_min_address) | ||
873 | reply = 0; | ||
863 | } else if (request_desript_type == | 874 | } else if (request_desript_type == |
864 | MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER) | 875 | MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER) |
865 | goto next; | 876 | goto next; |
@@ -922,7 +933,7 @@ _base_interrupt(int irq, void *bus_id) | |||
922 | } | 933 | } |
923 | 934 | ||
924 | /** | 935 | /** |
925 | * mpt2sas_base_release_callback_handler - clear interupt callback handler | 936 | * mpt2sas_base_release_callback_handler - clear interrupt callback handler |
926 | * @cb_idx: callback index | 937 | * @cb_idx: callback index |
927 | * | 938 | * |
928 | * Return nothing. | 939 | * Return nothing. |
@@ -1110,7 +1121,7 @@ _base_restore_msix_table(struct MPT2SAS_ADAPTER *ioc) | |||
1110 | * @ioc: per adapter object | 1121 | * @ioc: per adapter object |
1111 | * | 1122 | * |
1112 | * Check to see if card is capable of MSIX, and set number | 1123 | * Check to see if card is capable of MSIX, and set number |
1113 | * of avaliable msix vectors | 1124 | * of available msix vectors |
1114 | */ | 1125 | */ |
1115 | static int | 1126 | static int |
1116 | _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) | 1127 | _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) |
@@ -1426,7 +1437,7 @@ mpt2sas_base_get_smid_scsiio(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx, | |||
1426 | struct scsi_cmnd *scmd) | 1437 | struct scsi_cmnd *scmd) |
1427 | { | 1438 | { |
1428 | unsigned long flags; | 1439 | unsigned long flags; |
1429 | struct request_tracker *request; | 1440 | struct scsiio_tracker *request; |
1430 | u16 smid; | 1441 | u16 smid; |
1431 | 1442 | ||
1432 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | 1443 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); |
@@ -1438,7 +1449,7 @@ mpt2sas_base_get_smid_scsiio(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx, | |||
1438 | } | 1449 | } |
1439 | 1450 | ||
1440 | request = list_entry(ioc->free_list.next, | 1451 | request = list_entry(ioc->free_list.next, |
1441 | struct request_tracker, tracker_list); | 1452 | struct scsiio_tracker, tracker_list); |
1442 | request->scmd = scmd; | 1453 | request->scmd = scmd; |
1443 | request->cb_idx = cb_idx; | 1454 | request->cb_idx = cb_idx; |
1444 | smid = request->smid; | 1455 | smid = request->smid; |
@@ -1489,42 +1500,51 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
1489 | { | 1500 | { |
1490 | unsigned long flags; | 1501 | unsigned long flags; |
1491 | int i; | 1502 | int i; |
1503 | struct chain_tracker *chain_req, *next; | ||
1492 | 1504 | ||
1493 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | 1505 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); |
1494 | if (smid >= ioc->hi_priority_smid) { | 1506 | if (smid < ioc->hi_priority_smid) { |
1495 | if (smid < ioc->internal_smid) { | 1507 | /* scsiio queue */ |
1496 | /* hi-priority */ | 1508 | i = smid - 1; |
1497 | i = smid - ioc->hi_priority_smid; | 1509 | if (!list_empty(&ioc->scsi_lookup[i].chain_list)) { |
1498 | ioc->hpr_lookup[i].cb_idx = 0xFF; | 1510 | list_for_each_entry_safe(chain_req, next, |
1499 | list_add_tail(&ioc->hpr_lookup[i].tracker_list, | 1511 | &ioc->scsi_lookup[i].chain_list, tracker_list) { |
1500 | &ioc->hpr_free_list); | 1512 | list_del_init(&chain_req->tracker_list); |
1501 | } else { | 1513 | list_add_tail(&chain_req->tracker_list, |
1502 | /* internal queue */ | 1514 | &ioc->free_chain_list); |
1503 | i = smid - ioc->internal_smid; | 1515 | } |
1504 | ioc->internal_lookup[i].cb_idx = 0xFF; | ||
1505 | list_add_tail(&ioc->internal_lookup[i].tracker_list, | ||
1506 | &ioc->internal_free_list); | ||
1507 | } | 1516 | } |
1517 | ioc->scsi_lookup[i].cb_idx = 0xFF; | ||
1518 | ioc->scsi_lookup[i].scmd = NULL; | ||
1519 | ioc->scsi_lookup[i].direct_io = 0; | ||
1520 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, | ||
1521 | &ioc->free_list); | ||
1508 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | 1522 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
1523 | |||
1524 | /* | ||
1525 | * See _wait_for_commands_to_complete() call with regards | ||
1526 | * to this code. | ||
1527 | */ | ||
1528 | if (ioc->shost_recovery && ioc->pending_io_count) { | ||
1529 | if (ioc->pending_io_count == 1) | ||
1530 | wake_up(&ioc->reset_wq); | ||
1531 | ioc->pending_io_count--; | ||
1532 | } | ||
1509 | return; | 1533 | return; |
1534 | } else if (smid < ioc->internal_smid) { | ||
1535 | /* hi-priority */ | ||
1536 | i = smid - ioc->hi_priority_smid; | ||
1537 | ioc->hpr_lookup[i].cb_idx = 0xFF; | ||
1538 | list_add_tail(&ioc->hpr_lookup[i].tracker_list, | ||
1539 | &ioc->hpr_free_list); | ||
1540 | } else if (smid <= ioc->hba_queue_depth) { | ||
1541 | /* internal queue */ | ||
1542 | i = smid - ioc->internal_smid; | ||
1543 | ioc->internal_lookup[i].cb_idx = 0xFF; | ||
1544 | list_add_tail(&ioc->internal_lookup[i].tracker_list, | ||
1545 | &ioc->internal_free_list); | ||
1510 | } | 1546 | } |
1511 | |||
1512 | /* scsiio queue */ | ||
1513 | i = smid - 1; | ||
1514 | ioc->scsi_lookup[i].cb_idx = 0xFF; | ||
1515 | ioc->scsi_lookup[i].scmd = NULL; | ||
1516 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, | ||
1517 | &ioc->free_list); | ||
1518 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | 1547 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
1519 | |||
1520 | /* | ||
1521 | * See _wait_for_commands_to_complete() call with regards to this code. | ||
1522 | */ | ||
1523 | if (ioc->shost_recovery && ioc->pending_io_count) { | ||
1524 | if (ioc->pending_io_count == 1) | ||
1525 | wake_up(&ioc->reset_wq); | ||
1526 | ioc->pending_io_count--; | ||
1527 | } | ||
1528 | } | 1548 | } |
1529 | 1549 | ||
1530 | /** | 1550 | /** |
@@ -1584,7 +1604,7 @@ mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u16 handle) | |||
1584 | 1604 | ||
1585 | 1605 | ||
1586 | /** | 1606 | /** |
1587 | * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware | 1607 | * mpt2sas_base_put_smid_hi_priority - send Task Management request to firmware |
1588 | * @ioc: per adapter object | 1608 | * @ioc: per adapter object |
1589 | * @smid: system request message index | 1609 | * @smid: system request message index |
1590 | * | 1610 | * |
@@ -1712,6 +1732,79 @@ _base_display_dell_branding(struct MPT2SAS_ADAPTER *ioc) | |||
1712 | } | 1732 | } |
1713 | 1733 | ||
1714 | /** | 1734 | /** |
1735 | * _base_display_intel_branding - Display branding string | ||
1736 | * @ioc: per adapter object | ||
1737 | * | ||
1738 | * Return nothing. | ||
1739 | */ | ||
1740 | static void | ||
1741 | _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc) | ||
1742 | { | ||
1743 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_INTEL && | ||
1744 | ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008) { | ||
1745 | |||
1746 | switch (ioc->pdev->subsystem_device) { | ||
1747 | case MPT2SAS_INTEL_RMS2LL080_SSDID: | ||
1748 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1749 | MPT2SAS_INTEL_RMS2LL080_BRANDING); | ||
1750 | break; | ||
1751 | case MPT2SAS_INTEL_RMS2LL040_SSDID: | ||
1752 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1753 | MPT2SAS_INTEL_RMS2LL040_BRANDING); | ||
1754 | break; | ||
1755 | } | ||
1756 | } | ||
1757 | } | ||
1758 | |||
1759 | /** | ||
1760 | * _base_display_hp_branding - Display branding string | ||
1761 | * @ioc: per adapter object | ||
1762 | * | ||
1763 | * Return nothing. | ||
1764 | */ | ||
1765 | static void | ||
1766 | _base_display_hp_branding(struct MPT2SAS_ADAPTER *ioc) | ||
1767 | { | ||
1768 | if (ioc->pdev->subsystem_vendor != MPT2SAS_HP_3PAR_SSVID) | ||
1769 | return; | ||
1770 | |||
1771 | switch (ioc->pdev->device) { | ||
1772 | case MPI2_MFGPAGE_DEVID_SAS2004: | ||
1773 | switch (ioc->pdev->subsystem_device) { | ||
1774 | case MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID: | ||
1775 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1776 | MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING); | ||
1777 | break; | ||
1778 | default: | ||
1779 | break; | ||
1780 | } | ||
1781 | case MPI2_MFGPAGE_DEVID_SAS2308_2: | ||
1782 | switch (ioc->pdev->subsystem_device) { | ||
1783 | case MPT2SAS_HP_2_4_INTERNAL_SSDID: | ||
1784 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1785 | MPT2SAS_HP_2_4_INTERNAL_BRANDING); | ||
1786 | break; | ||
1787 | case MPT2SAS_HP_2_4_EXTERNAL_SSDID: | ||
1788 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1789 | MPT2SAS_HP_2_4_EXTERNAL_BRANDING); | ||
1790 | break; | ||
1791 | case MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID: | ||
1792 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1793 | MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING); | ||
1794 | break; | ||
1795 | case MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID: | ||
1796 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | ||
1797 | MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING); | ||
1798 | break; | ||
1799 | default: | ||
1800 | break; | ||
1801 | } | ||
1802 | default: | ||
1803 | break; | ||
1804 | } | ||
1805 | } | ||
1806 | |||
1807 | /** | ||
1715 | * _base_display_ioc_capabilities - Disply IOC's capabilities. | 1808 | * _base_display_ioc_capabilities - Disply IOC's capabilities. |
1716 | * @ioc: per adapter object | 1809 | * @ioc: per adapter object |
1717 | * | 1810 | * |
@@ -1741,6 +1834,8 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) | |||
1741 | ioc->bios_pg3.BiosVersion & 0x000000FF); | 1834 | ioc->bios_pg3.BiosVersion & 0x000000FF); |
1742 | 1835 | ||
1743 | _base_display_dell_branding(ioc); | 1836 | _base_display_dell_branding(ioc); |
1837 | _base_display_intel_branding(ioc); | ||
1838 | _base_display_hp_branding(ioc); | ||
1744 | 1839 | ||
1745 | printk(MPT2SAS_INFO_FMT "Protocol=(", ioc->name); | 1840 | printk(MPT2SAS_INFO_FMT "Protocol=(", ioc->name); |
1746 | 1841 | ||
@@ -1758,10 +1853,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) | |||
1758 | printk("), "); | 1853 | printk("), "); |
1759 | printk("Capabilities=("); | 1854 | printk("Capabilities=("); |
1760 | 1855 | ||
1761 | if (ioc->facts.IOCCapabilities & | 1856 | if (!ioc->hide_ir_msg) { |
1762 | MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { | 1857 | if (ioc->facts.IOCCapabilities & |
1763 | printk("Raid"); | 1858 | MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { |
1764 | i++; | 1859 | printk("Raid"); |
1860 | i++; | ||
1861 | } | ||
1765 | } | 1862 | } |
1766 | 1863 | ||
1767 | if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { | 1864 | if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { |
@@ -1819,6 +1916,97 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) | |||
1819 | } | 1916 | } |
1820 | 1917 | ||
1821 | /** | 1918 | /** |
1919 | * _base_update_missing_delay - change the missing delay timers | ||
1920 | * @ioc: per adapter object | ||
1921 | * @device_missing_delay: amount of time till device is reported missing | ||
1922 | * @io_missing_delay: interval IO is returned when there is a missing device | ||
1923 | * | ||
1924 | * Return nothing. | ||
1925 | * | ||
1926 | * Passed on the command line, this function will modify the device missing | ||
1927 | * delay, as well as the io missing delay. This should be called at driver | ||
1928 | * load time. | ||
1929 | */ | ||
1930 | static void | ||
1931 | _base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc, | ||
1932 | u16 device_missing_delay, u8 io_missing_delay) | ||
1933 | { | ||
1934 | u16 dmd, dmd_new, dmd_orignal; | ||
1935 | u8 io_missing_delay_original; | ||
1936 | u16 sz; | ||
1937 | Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; | ||
1938 | Mpi2ConfigReply_t mpi_reply; | ||
1939 | u8 num_phys = 0; | ||
1940 | u16 ioc_status; | ||
1941 | |||
1942 | mpt2sas_config_get_number_hba_phys(ioc, &num_phys); | ||
1943 | if (!num_phys) | ||
1944 | return; | ||
1945 | |||
1946 | sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys * | ||
1947 | sizeof(Mpi2SasIOUnit1PhyData_t)); | ||
1948 | sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); | ||
1949 | if (!sas_iounit_pg1) { | ||
1950 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1951 | ioc->name, __FILE__, __LINE__, __func__); | ||
1952 | goto out; | ||
1953 | } | ||
1954 | if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, | ||
1955 | sas_iounit_pg1, sz))) { | ||
1956 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1957 | ioc->name, __FILE__, __LINE__, __func__); | ||
1958 | goto out; | ||
1959 | } | ||
1960 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1961 | MPI2_IOCSTATUS_MASK; | ||
1962 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
1963 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1964 | ioc->name, __FILE__, __LINE__, __func__); | ||
1965 | goto out; | ||
1966 | } | ||
1967 | |||
1968 | /* device missing delay */ | ||
1969 | dmd = sas_iounit_pg1->ReportDeviceMissingDelay; | ||
1970 | if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) | ||
1971 | dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; | ||
1972 | else | ||
1973 | dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; | ||
1974 | dmd_orignal = dmd; | ||
1975 | if (device_missing_delay > 0x7F) { | ||
1976 | dmd = (device_missing_delay > 0x7F0) ? 0x7F0 : | ||
1977 | device_missing_delay; | ||
1978 | dmd = dmd / 16; | ||
1979 | dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16; | ||
1980 | } else | ||
1981 | dmd = device_missing_delay; | ||
1982 | sas_iounit_pg1->ReportDeviceMissingDelay = dmd; | ||
1983 | |||
1984 | /* io missing delay */ | ||
1985 | io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay; | ||
1986 | sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay; | ||
1987 | |||
1988 | if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, | ||
1989 | sz)) { | ||
1990 | if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) | ||
1991 | dmd_new = (dmd & | ||
1992 | MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; | ||
1993 | else | ||
1994 | dmd_new = | ||
1995 | dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; | ||
1996 | printk(MPT2SAS_INFO_FMT "device_missing_delay: old(%d), " | ||
1997 | "new(%d)\n", ioc->name, dmd_orignal, dmd_new); | ||
1998 | printk(MPT2SAS_INFO_FMT "ioc_missing_delay: old(%d), " | ||
1999 | "new(%d)\n", ioc->name, io_missing_delay_original, | ||
2000 | io_missing_delay); | ||
2001 | ioc->device_missing_delay = dmd_new; | ||
2002 | ioc->io_missing_delay = io_missing_delay; | ||
2003 | } | ||
2004 | |||
2005 | out: | ||
2006 | kfree(sas_iounit_pg1); | ||
2007 | } | ||
2008 | |||
2009 | /** | ||
1822 | * _base_static_config_pages - static start of day config pages | 2010 | * _base_static_config_pages - static start of day config pages |
1823 | * @ioc: per adapter object | 2011 | * @ioc: per adapter object |
1824 | * | 2012 | * |
@@ -1855,6 +2043,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) | |||
1855 | MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; | 2043 | MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; |
1856 | ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); | 2044 | ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); |
1857 | mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); | 2045 | mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); |
2046 | |||
1858 | } | 2047 | } |
1859 | 2048 | ||
1860 | /** | 2049 | /** |
@@ -1868,6 +2057,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) | |||
1868 | static void | 2057 | static void |
1869 | _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) | 2058 | _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) |
1870 | { | 2059 | { |
2060 | int i; | ||
2061 | |||
1871 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 2062 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1872 | __func__)); | 2063 | __func__)); |
1873 | 2064 | ||
@@ -1932,6 +2123,20 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) | |||
1932 | } | 2123 | } |
1933 | kfree(ioc->hpr_lookup); | 2124 | kfree(ioc->hpr_lookup); |
1934 | kfree(ioc->internal_lookup); | 2125 | kfree(ioc->internal_lookup); |
2126 | if (ioc->chain_lookup) { | ||
2127 | for (i = 0; i < ioc->chain_depth; i++) { | ||
2128 | if (ioc->chain_lookup[i].chain_buffer) | ||
2129 | pci_pool_free(ioc->chain_dma_pool, | ||
2130 | ioc->chain_lookup[i].chain_buffer, | ||
2131 | ioc->chain_lookup[i].chain_buffer_dma); | ||
2132 | } | ||
2133 | if (ioc->chain_dma_pool) | ||
2134 | pci_pool_destroy(ioc->chain_dma_pool); | ||
2135 | } | ||
2136 | if (ioc->chain_lookup) { | ||
2137 | free_pages((ulong)ioc->chain_lookup, ioc->chain_pages); | ||
2138 | ioc->chain_lookup = NULL; | ||
2139 | } | ||
1935 | } | 2140 | } |
1936 | 2141 | ||
1937 | 2142 | ||
@@ -1953,6 +2158,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
1953 | u32 sz, total_sz; | 2158 | u32 sz, total_sz; |
1954 | u32 retry_sz; | 2159 | u32 retry_sz; |
1955 | u16 max_request_credit; | 2160 | u16 max_request_credit; |
2161 | int i; | ||
1956 | 2162 | ||
1957 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 2163 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1958 | __func__)); | 2164 | __func__)); |
@@ -1970,14 +2176,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
1970 | } | 2176 | } |
1971 | 2177 | ||
1972 | /* command line tunables for max controller queue depth */ | 2178 | /* command line tunables for max controller queue depth */ |
1973 | if (max_queue_depth != -1) { | 2179 | if (max_queue_depth != -1) |
1974 | max_request_credit = (max_queue_depth < facts->RequestCredit) | 2180 | max_request_credit = (max_queue_depth < facts->RequestCredit) |
1975 | ? max_queue_depth : facts->RequestCredit; | 2181 | ? max_queue_depth : facts->RequestCredit; |
1976 | } else { | 2182 | else |
1977 | max_request_credit = (facts->RequestCredit > | 2183 | max_request_credit = facts->RequestCredit; |
1978 | MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE : | ||
1979 | facts->RequestCredit; | ||
1980 | } | ||
1981 | 2184 | ||
1982 | ioc->hba_queue_depth = max_request_credit; | 2185 | ioc->hba_queue_depth = max_request_credit; |
1983 | ioc->hi_priority_depth = facts->HighPriorityCredit; | 2186 | ioc->hi_priority_depth = facts->HighPriorityCredit; |
@@ -2057,9 +2260,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2057 | /* adjust hba_queue_depth, reply_free_queue_depth, | 2260 | /* adjust hba_queue_depth, reply_free_queue_depth, |
2058 | * and queue_size | 2261 | * and queue_size |
2059 | */ | 2262 | */ |
2060 | ioc->hba_queue_depth -= queue_diff; | 2263 | ioc->hba_queue_depth -= (queue_diff / 2); |
2061 | ioc->reply_free_queue_depth -= queue_diff; | 2264 | ioc->reply_free_queue_depth -= (queue_diff / 2); |
2062 | queue_size -= queue_diff; | 2265 | queue_size = facts->MaxReplyDescriptorPostQueueDepth; |
2063 | } | 2266 | } |
2064 | ioc->reply_post_queue_depth = queue_size; | 2267 | ioc->reply_post_queue_depth = queue_size; |
2065 | 2268 | ||
@@ -2083,7 +2286,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2083 | * "frame for smid=0 | 2286 | * "frame for smid=0 |
2084 | */ | 2287 | */ |
2085 | ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth; | 2288 | ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth; |
2086 | sz = ((ioc->scsiio_depth + 1 + ioc->chain_depth) * ioc->request_sz); | 2289 | sz = ((ioc->scsiio_depth + 1) * ioc->request_sz); |
2087 | 2290 | ||
2088 | /* hi-priority queue */ | 2291 | /* hi-priority queue */ |
2089 | sz += (ioc->hi_priority_depth * ioc->request_sz); | 2292 | sz += (ioc->hi_priority_depth * ioc->request_sz); |
@@ -2124,26 +2327,18 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2124 | ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * | 2327 | ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * |
2125 | ioc->request_sz); | 2328 | ioc->request_sz); |
2126 | 2329 | ||
2127 | ioc->chain = ioc->internal + (ioc->internal_depth * | ||
2128 | ioc->request_sz); | ||
2129 | ioc->chain_dma = ioc->internal_dma + (ioc->internal_depth * | ||
2130 | ioc->request_sz); | ||
2131 | 2330 | ||
2132 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): " | 2331 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): " |
2133 | "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, | 2332 | "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, |
2134 | ioc->request, ioc->hba_queue_depth, ioc->request_sz, | 2333 | ioc->request, ioc->hba_queue_depth, ioc->request_sz, |
2135 | (ioc->hba_queue_depth * ioc->request_sz)/1024)); | 2334 | (ioc->hba_queue_depth * ioc->request_sz)/1024)); |
2136 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth" | ||
2137 | "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain, | ||
2138 | ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth * | ||
2139 | ioc->request_sz))/1024)); | ||
2140 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n", | 2335 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n", |
2141 | ioc->name, (unsigned long long) ioc->request_dma)); | 2336 | ioc->name, (unsigned long long) ioc->request_dma)); |
2142 | total_sz += sz; | 2337 | total_sz += sz; |
2143 | 2338 | ||
2144 | sz = ioc->scsiio_depth * sizeof(struct request_tracker); | 2339 | sz = ioc->scsiio_depth * sizeof(struct scsiio_tracker); |
2145 | ioc->scsi_lookup_pages = get_order(sz); | 2340 | ioc->scsi_lookup_pages = get_order(sz); |
2146 | ioc->scsi_lookup = (struct request_tracker *)__get_free_pages( | 2341 | ioc->scsi_lookup = (struct scsiio_tracker *)__get_free_pages( |
2147 | GFP_KERNEL, ioc->scsi_lookup_pages); | 2342 | GFP_KERNEL, ioc->scsi_lookup_pages); |
2148 | if (!ioc->scsi_lookup) { | 2343 | if (!ioc->scsi_lookup) { |
2149 | printk(MPT2SAS_ERR_FMT "scsi_lookup: get_free_pages failed, " | 2344 | printk(MPT2SAS_ERR_FMT "scsi_lookup: get_free_pages failed, " |
@@ -2155,6 +2350,38 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2155 | "depth(%d)\n", ioc->name, ioc->request, | 2350 | "depth(%d)\n", ioc->name, ioc->request, |
2156 | ioc->scsiio_depth)); | 2351 | ioc->scsiio_depth)); |
2157 | 2352 | ||
2353 | /* loop till the allocation succeeds */ | ||
2354 | do { | ||
2355 | sz = ioc->chain_depth * sizeof(struct chain_tracker); | ||
2356 | ioc->chain_pages = get_order(sz); | ||
2357 | ioc->chain_lookup = (struct chain_tracker *)__get_free_pages( | ||
2358 | GFP_KERNEL, ioc->chain_pages); | ||
2359 | if (ioc->chain_lookup == NULL) | ||
2360 | ioc->chain_depth -= 100; | ||
2361 | } while (ioc->chain_lookup == NULL); | ||
2362 | ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev, | ||
2363 | ioc->request_sz, 16, 0); | ||
2364 | if (!ioc->chain_dma_pool) { | ||
2365 | printk(MPT2SAS_ERR_FMT "chain_dma_pool: pci_pool_create " | ||
2366 | "failed\n", ioc->name); | ||
2367 | goto out; | ||
2368 | } | ||
2369 | for (i = 0; i < ioc->chain_depth; i++) { | ||
2370 | ioc->chain_lookup[i].chain_buffer = pci_pool_alloc( | ||
2371 | ioc->chain_dma_pool , GFP_KERNEL, | ||
2372 | &ioc->chain_lookup[i].chain_buffer_dma); | ||
2373 | if (!ioc->chain_lookup[i].chain_buffer) { | ||
2374 | ioc->chain_depth = i; | ||
2375 | goto chain_done; | ||
2376 | } | ||
2377 | total_sz += ioc->request_sz; | ||
2378 | } | ||
2379 | chain_done: | ||
2380 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool depth" | ||
2381 | "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, | ||
2382 | ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth * | ||
2383 | ioc->request_sz))/1024)); | ||
2384 | |||
2158 | /* initialize hi-priority queue smid's */ | 2385 | /* initialize hi-priority queue smid's */ |
2159 | ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, | 2386 | ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, |
2160 | sizeof(struct request_tracker), GFP_KERNEL); | 2387 | sizeof(struct request_tracker), GFP_KERNEL); |
@@ -2221,6 +2448,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2221 | ioc->name); | 2448 | ioc->name); |
2222 | goto out; | 2449 | goto out; |
2223 | } | 2450 | } |
2451 | ioc->reply_dma_min_address = (u32)(ioc->reply_dma); | ||
2452 | ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz; | ||
2224 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth" | 2453 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth" |
2225 | "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply, | 2454 | "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply, |
2226 | ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024)); | 2455 | ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024)); |
@@ -2302,7 +2531,6 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2302 | return 0; | 2531 | return 0; |
2303 | 2532 | ||
2304 | out: | 2533 | out: |
2305 | _base_release_memory_pools(ioc); | ||
2306 | return -ENOMEM; | 2534 | return -ENOMEM; |
2307 | } | 2535 | } |
2308 | 2536 | ||
@@ -2382,7 +2610,7 @@ _base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout, | |||
2382 | int_status = readl(&ioc->chip->HostInterruptStatus); | 2610 | int_status = readl(&ioc->chip->HostInterruptStatus); |
2383 | if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { | 2611 | if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { |
2384 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | 2612 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
2385 | "successfull count(%d), timeout(%d)\n", ioc->name, | 2613 | "successful count(%d), timeout(%d)\n", ioc->name, |
2386 | __func__, count, timeout)); | 2614 | __func__, count, timeout)); |
2387 | return 0; | 2615 | return 0; |
2388 | } | 2616 | } |
@@ -2423,7 +2651,7 @@ _base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout, | |||
2423 | int_status = readl(&ioc->chip->HostInterruptStatus); | 2651 | int_status = readl(&ioc->chip->HostInterruptStatus); |
2424 | if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { | 2652 | if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { |
2425 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | 2653 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
2426 | "successfull count(%d), timeout(%d)\n", ioc->name, | 2654 | "successful count(%d), timeout(%d)\n", ioc->name, |
2427 | __func__, count, timeout)); | 2655 | __func__, count, timeout)); |
2428 | return 0; | 2656 | return 0; |
2429 | } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { | 2657 | } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { |
@@ -2471,7 +2699,7 @@ _base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout, | |||
2471 | doorbell_reg = readl(&ioc->chip->Doorbell); | 2699 | doorbell_reg = readl(&ioc->chip->Doorbell); |
2472 | if (!(doorbell_reg & MPI2_DOORBELL_USED)) { | 2700 | if (!(doorbell_reg & MPI2_DOORBELL_USED)) { |
2473 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | 2701 | dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
2474 | "successfull count(%d), timeout(%d)\n", ioc->name, | 2702 | "successful count(%d), timeout(%d)\n", ioc->name, |
2475 | __func__, count, timeout)); | 2703 | __func__, count, timeout)); |
2476 | return 0; | 2704 | return 0; |
2477 | } | 2705 | } |
@@ -3463,6 +3691,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3463 | u32 reply_address; | 3691 | u32 reply_address; |
3464 | u16 smid; | 3692 | u16 smid; |
3465 | struct _tr_list *delayed_tr, *delayed_tr_next; | 3693 | struct _tr_list *delayed_tr, *delayed_tr_next; |
3694 | u8 hide_flag; | ||
3466 | 3695 | ||
3467 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 3696 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3468 | __func__)); | 3697 | __func__)); |
@@ -3485,9 +3714,11 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3485 | INIT_LIST_HEAD(&ioc->free_list); | 3714 | INIT_LIST_HEAD(&ioc->free_list); |
3486 | smid = 1; | 3715 | smid = 1; |
3487 | for (i = 0; i < ioc->scsiio_depth; i++, smid++) { | 3716 | for (i = 0; i < ioc->scsiio_depth; i++, smid++) { |
3717 | INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list); | ||
3488 | ioc->scsi_lookup[i].cb_idx = 0xFF; | 3718 | ioc->scsi_lookup[i].cb_idx = 0xFF; |
3489 | ioc->scsi_lookup[i].smid = smid; | 3719 | ioc->scsi_lookup[i].smid = smid; |
3490 | ioc->scsi_lookup[i].scmd = NULL; | 3720 | ioc->scsi_lookup[i].scmd = NULL; |
3721 | ioc->scsi_lookup[i].direct_io = 0; | ||
3491 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, | 3722 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, |
3492 | &ioc->free_list); | 3723 | &ioc->free_list); |
3493 | } | 3724 | } |
@@ -3511,6 +3742,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3511 | list_add_tail(&ioc->internal_lookup[i].tracker_list, | 3742 | list_add_tail(&ioc->internal_lookup[i].tracker_list, |
3512 | &ioc->internal_free_list); | 3743 | &ioc->internal_free_list); |
3513 | } | 3744 | } |
3745 | |||
3746 | /* chain pool */ | ||
3747 | INIT_LIST_HEAD(&ioc->free_chain_list); | ||
3748 | for (i = 0; i < ioc->chain_depth; i++) | ||
3749 | list_add_tail(&ioc->chain_lookup[i].tracker_list, | ||
3750 | &ioc->free_chain_list); | ||
3751 | |||
3514 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | 3752 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
3515 | 3753 | ||
3516 | /* initialize Reply Free Queue */ | 3754 | /* initialize Reply Free Queue */ |
@@ -3541,6 +3779,15 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3541 | if (sleep_flag == CAN_SLEEP) | 3779 | if (sleep_flag == CAN_SLEEP) |
3542 | _base_static_config_pages(ioc); | 3780 | _base_static_config_pages(ioc); |
3543 | 3781 | ||
3782 | if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) { | ||
3783 | if (ioc->manu_pg10.OEMIdentifier == 0x80) { | ||
3784 | hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & | ||
3785 | MFG_PAGE10_HIDE_SSDS_MASK); | ||
3786 | if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) | ||
3787 | ioc->mfg_pg10_hide_flag = hide_flag; | ||
3788 | } | ||
3789 | } | ||
3790 | |||
3544 | if (ioc->wait_for_port_enable_to_complete) { | 3791 | if (ioc->wait_for_port_enable_to_complete) { |
3545 | if (diag_buffer_enable != 0) | 3792 | if (diag_buffer_enable != 0) |
3546 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | 3793 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); |
@@ -3708,12 +3955,15 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3708 | _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME); | 3955 | _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME); |
3709 | _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); | 3956 | _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); |
3710 | _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); | 3957 | _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); |
3711 | _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL); | ||
3712 | _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); | 3958 | _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); |
3713 | r = _base_make_ioc_operational(ioc, CAN_SLEEP); | 3959 | r = _base_make_ioc_operational(ioc, CAN_SLEEP); |
3714 | if (r) | 3960 | if (r) |
3715 | goto out_free_resources; | 3961 | goto out_free_resources; |
3716 | 3962 | ||
3963 | if (missing_delay[0] != -1 && missing_delay[1] != -1) | ||
3964 | _base_update_missing_delay(ioc, missing_delay[0], | ||
3965 | missing_delay[1]); | ||
3966 | |||
3717 | mpt2sas_base_start_watchdog(ioc); | 3967 | mpt2sas_base_start_watchdog(ioc); |
3718 | return 0; | 3968 | return 0; |
3719 | 3969 | ||
@@ -3786,6 +4036,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | |||
3786 | static void | 4036 | static void |
3787 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | 4037 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) |
3788 | { | 4038 | { |
4039 | mpt2sas_scsih_reset_handler(ioc, reset_phase); | ||
4040 | mpt2sas_ctl_reset_handler(ioc, reset_phase); | ||
3789 | switch (reset_phase) { | 4041 | switch (reset_phase) { |
3790 | case MPT2_IOC_PRE_RESET: | 4042 | case MPT2_IOC_PRE_RESET: |
3791 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | 4043 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
@@ -3816,8 +4068,6 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
3816 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | 4068 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); |
3817 | break; | 4069 | break; |
3818 | } | 4070 | } |
3819 | mpt2sas_scsih_reset_handler(ioc, reset_phase); | ||
3820 | mpt2sas_ctl_reset_handler(ioc, reset_phase); | ||
3821 | } | 4071 | } |
3822 | 4072 | ||
3823 | /** | 4073 | /** |
@@ -3871,6 +4121,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3871 | { | 4121 | { |
3872 | int r; | 4122 | int r; |
3873 | unsigned long flags; | 4123 | unsigned long flags; |
4124 | u8 pe_complete = ioc->wait_for_port_enable_to_complete; | ||
3874 | 4125 | ||
3875 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 4126 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
3876 | __func__)); | 4127 | __func__)); |
@@ -3913,6 +4164,14 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3913 | if (r) | 4164 | if (r) |
3914 | goto out; | 4165 | goto out; |
3915 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); | 4166 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); |
4167 | |||
4168 | /* If this hard reset is called while port enable is active, then | ||
4169 | * there is no reason to call make_ioc_operational | ||
4170 | */ | ||
4171 | if (pe_complete) { | ||
4172 | r = -EFAULT; | ||
4173 | goto out; | ||
4174 | } | ||
3916 | r = _base_make_ioc_operational(ioc, sleep_flag); | 4175 | r = _base_make_ioc_operational(ioc, sleep_flag); |
3917 | if (!r) | 4176 | if (!r) |
3918 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); | 4177 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 0b15a8bdebfc..dcc289c25459 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -69,11 +69,11 @@ | |||
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 "06.100.00.00" | 72 | #define MPT2SAS_DRIVER_VERSION "08.100.00.02" |
73 | #define MPT2SAS_MAJOR_VERSION 06 | 73 | #define MPT2SAS_MAJOR_VERSION 08 |
74 | #define MPT2SAS_MINOR_VERSION 100 | 74 | #define MPT2SAS_MINOR_VERSION 100 |
75 | #define MPT2SAS_BUILD_VERSION 00 | 75 | #define MPT2SAS_BUILD_VERSION 00 |
76 | #define MPT2SAS_RELEASE_VERSION 00 | 76 | #define MPT2SAS_RELEASE_VERSION 02 |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Set MPT2SAS_SG_DEPTH value based on user input. | 79 | * Set MPT2SAS_SG_DEPTH value based on user input. |
@@ -101,7 +101,8 @@ | |||
101 | #define MPT_NAME_LENGTH 32 /* generic length of strings */ | 101 | #define MPT_NAME_LENGTH 32 /* generic length of strings */ |
102 | #define MPT_STRING_LENGTH 64 | 102 | #define MPT_STRING_LENGTH 64 |
103 | 103 | ||
104 | #define MPT_MAX_CALLBACKS 16 | 104 | #define MPT_MAX_CALLBACKS 16 |
105 | |||
105 | 106 | ||
106 | #define CAN_SLEEP 1 | 107 | #define CAN_SLEEP 1 |
107 | #define NO_SLEEP 0 | 108 | #define NO_SLEEP 0 |
@@ -154,6 +155,50 @@ | |||
154 | #define MPT2SAS_DELL_6GBPS_SAS_SSDID 0x1F22 | 155 | #define MPT2SAS_DELL_6GBPS_SAS_SSDID 0x1F22 |
155 | 156 | ||
156 | /* | 157 | /* |
158 | * Intel HBA branding | ||
159 | */ | ||
160 | #define MPT2SAS_INTEL_RMS2LL080_BRANDING \ | ||
161 | "Intel Integrated RAID Module RMS2LL080" | ||
162 | #define MPT2SAS_INTEL_RMS2LL040_BRANDING \ | ||
163 | "Intel Integrated RAID Module RMS2LL040" | ||
164 | |||
165 | /* | ||
166 | * Intel HBA SSDIDs | ||
167 | */ | ||
168 | #define MPT2SAS_INTEL_RMS2LL080_SSDID 0x350E | ||
169 | #define MPT2SAS_INTEL_RMS2LL040_SSDID 0x350F | ||
170 | |||
171 | |||
172 | /* | ||
173 | * HP HBA branding | ||
174 | */ | ||
175 | #define MPT2SAS_HP_3PAR_SSVID 0x1590 | ||
176 | #define MPT2SAS_HP_2_4_INTERNAL_BRANDING "HP H220 Host Bus Adapter" | ||
177 | #define MPT2SAS_HP_2_4_EXTERNAL_BRANDING "HP H221 Host Bus Adapter" | ||
178 | #define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING "HP H222 Host Bus Adapter" | ||
179 | #define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING "HP H220i Host Bus Adapter" | ||
180 | #define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING "HP H210i Host Bus Adapter" | ||
181 | |||
182 | /* | ||
183 | * HO HBA SSDIDs | ||
184 | */ | ||
185 | #define MPT2SAS_HP_2_4_INTERNAL_SSDID 0x0041 | ||
186 | #define MPT2SAS_HP_2_4_EXTERNAL_SSDID 0x0042 | ||
187 | #define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID 0x0043 | ||
188 | #define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID 0x0044 | ||
189 | #define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 | ||
190 | |||
191 | /* | ||
192 | * WarpDrive Specific Log codes | ||
193 | */ | ||
194 | |||
195 | #define MPT2_WARPDRIVE_LOGENTRY (0x8002) | ||
196 | #define MPT2_WARPDRIVE_LC_SSDT (0x41) | ||
197 | #define MPT2_WARPDRIVE_LC_SSDLW (0x43) | ||
198 | #define MPT2_WARPDRIVE_LC_SSDLF (0x44) | ||
199 | #define MPT2_WARPDRIVE_LC_BRMF (0x4D) | ||
200 | |||
201 | /* | ||
157 | * per target private data | 202 | * per target private data |
158 | */ | 203 | */ |
159 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 | 204 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 |
@@ -164,6 +209,7 @@ | |||
164 | * struct MPT2SAS_TARGET - starget private hostdata | 209 | * struct MPT2SAS_TARGET - starget private hostdata |
165 | * @starget: starget object | 210 | * @starget: starget object |
166 | * @sas_address: target sas address | 211 | * @sas_address: target sas address |
212 | * @raid_device: raid_device pointer to access volume data | ||
167 | * @handle: device handle | 213 | * @handle: device handle |
168 | * @num_luns: number luns | 214 | * @num_luns: number luns |
169 | * @flags: MPT_TARGET_FLAGS_XXX flags | 215 | * @flags: MPT_TARGET_FLAGS_XXX flags |
@@ -173,6 +219,7 @@ | |||
173 | struct MPT2SAS_TARGET { | 219 | struct MPT2SAS_TARGET { |
174 | struct scsi_target *starget; | 220 | struct scsi_target *starget; |
175 | u64 sas_address; | 221 | u64 sas_address; |
222 | struct _raid_device *raid_device; | ||
176 | u16 handle; | 223 | u16 handle; |
177 | int num_luns; | 224 | int num_luns; |
178 | u32 flags; | 225 | u32 flags; |
@@ -180,6 +227,7 @@ struct MPT2SAS_TARGET { | |||
180 | u8 tm_busy; | 227 | u8 tm_busy; |
181 | }; | 228 | }; |
182 | 229 | ||
230 | |||
183 | /* | 231 | /* |
184 | * per device private data | 232 | * per device private data |
185 | */ | 233 | */ |
@@ -227,6 +275,12 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_10 { | |||
227 | MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10, | 275 | MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10, |
228 | Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t; | 276 | Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t; |
229 | 277 | ||
278 | #define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003) | ||
279 | #define MFG_PAGE10_HIDE_ALL_DISKS (0x00) | ||
280 | #define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01) | ||
281 | #define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02) | ||
282 | |||
283 | |||
230 | struct MPT2SAS_DEVICE { | 284 | struct MPT2SAS_DEVICE { |
231 | struct MPT2SAS_TARGET *sas_target; | 285 | struct MPT2SAS_TARGET *sas_target; |
232 | unsigned int lun; | 286 | unsigned int lun; |
@@ -306,6 +360,7 @@ struct _sas_device { | |||
306 | * @sdev: scsi device struct (volumes are single lun) | 360 | * @sdev: scsi device struct (volumes are single lun) |
307 | * @wwid: unique identifier for the volume | 361 | * @wwid: unique identifier for the volume |
308 | * @handle: device handle | 362 | * @handle: device handle |
363 | * @block_size: Block size of the volume | ||
309 | * @id: target id | 364 | * @id: target id |
310 | * @channel: target channel | 365 | * @channel: target channel |
311 | * @volume_type: the raid level | 366 | * @volume_type: the raid level |
@@ -313,20 +368,33 @@ struct _sas_device { | |||
313 | * @num_pds: number of hidden raid components | 368 | * @num_pds: number of hidden raid components |
314 | * @responding: used in _scsih_raid_device_mark_responding | 369 | * @responding: used in _scsih_raid_device_mark_responding |
315 | * @percent_complete: resync percent complete | 370 | * @percent_complete: resync percent complete |
371 | * @direct_io_enabled: Whether direct io to PDs are allowed or not | ||
372 | * @stripe_exponent: X where 2powX is the stripe sz in blocks | ||
373 | * @max_lba: Maximum number of LBA in the volume | ||
374 | * @stripe_sz: Stripe Size of the volume | ||
375 | * @device_info: Device info of the volume member disk | ||
376 | * @pd_handle: Array of handles of the physical drives for direct I/O in le16 | ||
316 | */ | 377 | */ |
378 | #define MPT_MAX_WARPDRIVE_PDS 8 | ||
317 | struct _raid_device { | 379 | struct _raid_device { |
318 | struct list_head list; | 380 | struct list_head list; |
319 | struct scsi_target *starget; | 381 | struct scsi_target *starget; |
320 | struct scsi_device *sdev; | 382 | struct scsi_device *sdev; |
321 | u64 wwid; | 383 | u64 wwid; |
322 | u16 handle; | 384 | u16 handle; |
385 | u16 block_sz; | ||
323 | int id; | 386 | int id; |
324 | int channel; | 387 | int channel; |
325 | u8 volume_type; | 388 | u8 volume_type; |
326 | u32 device_info; | ||
327 | u8 num_pds; | 389 | u8 num_pds; |
328 | u8 responding; | 390 | u8 responding; |
329 | u8 percent_complete; | 391 | u8 percent_complete; |
392 | u8 direct_io_enabled; | ||
393 | u8 stripe_exponent; | ||
394 | u64 max_lba; | ||
395 | u32 stripe_sz; | ||
396 | u32 device_info; | ||
397 | u16 pd_handle[MPT_MAX_WARPDRIVE_PDS]; | ||
330 | }; | 398 | }; |
331 | 399 | ||
332 | /** | 400 | /** |
@@ -419,17 +487,44 @@ enum reset_type { | |||
419 | }; | 487 | }; |
420 | 488 | ||
421 | /** | 489 | /** |
422 | * struct request_tracker - firmware request tracker | 490 | * struct chain_tracker - firmware chain tracker |
491 | * @chain_buffer: chain buffer | ||
492 | * @chain_buffer_dma: physical address | ||
493 | * @tracker_list: list of free request (ioc->free_chain_list) | ||
494 | */ | ||
495 | struct chain_tracker { | ||
496 | void *chain_buffer; | ||
497 | dma_addr_t chain_buffer_dma; | ||
498 | struct list_head tracker_list; | ||
499 | }; | ||
500 | |||
501 | /** | ||
502 | * struct scsiio_tracker - scsi mf request tracker | ||
423 | * @smid: system message id | 503 | * @smid: system message id |
424 | * @scmd: scsi request pointer | 504 | * @scmd: scsi request pointer |
425 | * @cb_idx: callback index | 505 | * @cb_idx: callback index |
506 | * @direct_io: To indicate whether I/O is direct (WARPDRIVE) | ||
426 | * @chain_list: list of chains associated to this IO | 507 | * @chain_list: list of chains associated to this IO |
427 | * @tracker_list: list of free request (ioc->free_list) | 508 | * @tracker_list: list of free request (ioc->free_list) |
428 | */ | 509 | */ |
429 | struct request_tracker { | 510 | struct scsiio_tracker { |
430 | u16 smid; | 511 | u16 smid; |
431 | struct scsi_cmnd *scmd; | 512 | struct scsi_cmnd *scmd; |
432 | u8 cb_idx; | 513 | u8 cb_idx; |
514 | u8 direct_io; | ||
515 | struct list_head chain_list; | ||
516 | struct list_head tracker_list; | ||
517 | }; | ||
518 | |||
519 | /** | ||
520 | * struct request_tracker - firmware request tracker | ||
521 | * @smid: system message id | ||
522 | * @cb_idx: callback index | ||
523 | * @tracker_list: list of free request (ioc->free_list) | ||
524 | */ | ||
525 | struct request_tracker { | ||
526 | u16 smid; | ||
527 | u8 cb_idx; | ||
433 | struct list_head tracker_list; | 528 | struct list_head tracker_list; |
434 | }; | 529 | }; |
435 | 530 | ||
@@ -696,7 +791,7 @@ struct MPT2SAS_ADAPTER { | |||
696 | u8 *request; | 791 | u8 *request; |
697 | dma_addr_t request_dma; | 792 | dma_addr_t request_dma; |
698 | u32 request_dma_sz; | 793 | u32 request_dma_sz; |
699 | struct request_tracker *scsi_lookup; | 794 | struct scsiio_tracker *scsi_lookup; |
700 | ulong scsi_lookup_pages; | 795 | ulong scsi_lookup_pages; |
701 | spinlock_t scsi_lookup_lock; | 796 | spinlock_t scsi_lookup_lock; |
702 | struct list_head free_list; | 797 | struct list_head free_list; |
@@ -704,8 +799,10 @@ struct MPT2SAS_ADAPTER { | |||
704 | wait_queue_head_t reset_wq; | 799 | wait_queue_head_t reset_wq; |
705 | 800 | ||
706 | /* chain */ | 801 | /* chain */ |
707 | u8 *chain; | 802 | struct chain_tracker *chain_lookup; |
708 | dma_addr_t chain_dma; | 803 | struct list_head free_chain_list; |
804 | struct dma_pool *chain_dma_pool; | ||
805 | ulong chain_pages; | ||
709 | u16 max_sges_in_main_message; | 806 | u16 max_sges_in_main_message; |
710 | u16 max_sges_in_chain_message; | 807 | u16 max_sges_in_chain_message; |
711 | u16 chains_needed_per_io; | 808 | u16 chains_needed_per_io; |
@@ -737,6 +834,8 @@ struct MPT2SAS_ADAPTER { | |||
737 | u16 reply_sz; | 834 | u16 reply_sz; |
738 | u8 *reply; | 835 | u8 *reply; |
739 | dma_addr_t reply_dma; | 836 | dma_addr_t reply_dma; |
837 | u32 reply_dma_max_address; | ||
838 | u32 reply_dma_min_address; | ||
740 | struct dma_pool *reply_dma_pool; | 839 | struct dma_pool *reply_dma_pool; |
741 | 840 | ||
742 | /* reply free queue */ | 841 | /* reply free queue */ |
@@ -767,6 +866,11 @@ struct MPT2SAS_ADAPTER { | |||
767 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; | 866 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; |
768 | u32 ring_buffer_offset; | 867 | u32 ring_buffer_offset; |
769 | u32 ring_buffer_sz; | 868 | u32 ring_buffer_sz; |
869 | u8 is_warpdrive; | ||
870 | u8 hide_ir_msg; | ||
871 | u8 mfg_pg10_hide_flag; | ||
872 | u8 hide_drives; | ||
873 | |||
770 | }; | 874 | }; |
771 | 875 | ||
772 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 876 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
@@ -832,6 +936,8 @@ int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
832 | ulong timeout, struct scsi_cmnd *scmd); | 936 | ulong timeout, struct scsi_cmnd *scmd); |
833 | void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); | 937 | void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); |
834 | void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); | 938 | void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); |
939 | void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | ||
940 | void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | ||
835 | struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, | 941 | struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, |
836 | u16 handle); | 942 | u16 handle); |
837 | struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER | 943 | struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 6afd67b324fe..6861244249a3 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c | |||
@@ -93,7 +93,7 @@ struct config_request{ | |||
93 | * @mpi_reply: reply message frame | 93 | * @mpi_reply: reply message frame |
94 | * Context: none. | 94 | * Context: none. |
95 | * | 95 | * |
96 | * Function for displaying debug info helpfull when debugging issues | 96 | * Function for displaying debug info helpful when debugging issues |
97 | * in this module. | 97 | * in this module. |
98 | */ | 98 | */ |
99 | static void | 99 | static void |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index b774973f0765..437c2d94c45a 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
@@ -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 | ||
64 | static DEFINE_MUTEX(_ctl_mutex); | ||
64 | static struct fasync_struct *async_queue; | 65 | static struct fasync_struct *async_queue; |
65 | static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait); | 66 | static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait); |
66 | 67 | ||
@@ -80,6 +81,7 @@ enum block_state { | |||
80 | BLOCKING, | 81 | BLOCKING, |
81 | }; | 82 | }; |
82 | 83 | ||
84 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | ||
83 | /** | 85 | /** |
84 | * _ctl_sas_device_find_by_handle - sas device search | 86 | * _ctl_sas_device_find_by_handle - sas device search |
85 | * @ioc: per adapter object | 87 | * @ioc: per adapter object |
@@ -106,7 +108,6 @@ _ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
106 | return r; | 108 | return r; |
107 | } | 109 | } |
108 | 110 | ||
109 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | ||
110 | /** | 111 | /** |
111 | * _ctl_display_some_debug - debug routine | 112 | * _ctl_display_some_debug - debug routine |
112 | * @ioc: per adapter object | 113 | * @ioc: per adapter object |
@@ -115,7 +116,7 @@ _ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
115 | * @mpi_reply: reply message frame | 116 | * @mpi_reply: reply message frame |
116 | * Context: none. | 117 | * Context: none. |
117 | * | 118 | * |
118 | * Function for displaying debug info helpfull when debugging issues | 119 | * Function for displaying debug info helpful when debugging issues |
119 | * in this module. | 120 | * in this module. |
120 | */ | 121 | */ |
121 | static void | 122 | static void |
@@ -687,6 +688,13 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
687 | goto out; | 688 | goto out; |
688 | } | 689 | } |
689 | 690 | ||
691 | /* Check for overflow and wraparound */ | ||
692 | if (karg.data_sge_offset * 4 > ioc->request_sz || | ||
693 | karg.data_sge_offset > (UINT_MAX / 4)) { | ||
694 | ret = -EINVAL; | ||
695 | goto out; | ||
696 | } | ||
697 | |||
690 | /* copy in request message frame from user */ | 698 | /* copy in request message frame from user */ |
691 | if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { | 699 | if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { |
692 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, | 700 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, |
@@ -1033,7 +1041,10 @@ _ctl_getiocinfo(void __user *arg) | |||
1033 | __func__)); | 1041 | __func__)); |
1034 | 1042 | ||
1035 | memset(&karg, 0 , sizeof(karg)); | 1043 | memset(&karg, 0 , sizeof(karg)); |
1036 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; | 1044 | if (ioc->is_warpdrive) |
1045 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200; | ||
1046 | else | ||
1047 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; | ||
1037 | if (ioc->pfacts) | 1048 | if (ioc->pfacts) |
1038 | karg.port_number = ioc->pfacts[0].PortNumber; | 1049 | karg.port_number = ioc->pfacts[0].PortNumber; |
1039 | pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); | 1050 | pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); |
@@ -1962,7 +1973,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
1962 | Mpi2DiagBufferPostReply_t *mpi_reply; | 1973 | Mpi2DiagBufferPostReply_t *mpi_reply; |
1963 | int rc, i; | 1974 | int rc, i; |
1964 | u8 buffer_type; | 1975 | u8 buffer_type; |
1965 | unsigned long timeleft; | 1976 | unsigned long timeleft, request_size, copy_size; |
1966 | u16 smid; | 1977 | u16 smid; |
1967 | u16 ioc_status; | 1978 | u16 ioc_status; |
1968 | u8 issue_reset = 0; | 1979 | u8 issue_reset = 0; |
@@ -1998,6 +2009,8 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
1998 | return -ENOMEM; | 2009 | return -ENOMEM; |
1999 | } | 2010 | } |
2000 | 2011 | ||
2012 | request_size = ioc->diag_buffer_sz[buffer_type]; | ||
2013 | |||
2001 | if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { | 2014 | if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { |
2002 | printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " | 2015 | printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " |
2003 | "or bytes_to_read are not 4 byte aligned\n", ioc->name, | 2016 | "or bytes_to_read are not 4 byte aligned\n", ioc->name, |
@@ -2005,13 +2018,23 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
2005 | return -EINVAL; | 2018 | return -EINVAL; |
2006 | } | 2019 | } |
2007 | 2020 | ||
2021 | if (karg.starting_offset > request_size) | ||
2022 | return -EINVAL; | ||
2023 | |||
2008 | diag_data = (void *)(request_data + karg.starting_offset); | 2024 | diag_data = (void *)(request_data + karg.starting_offset); |
2009 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), " | 2025 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), " |
2010 | "offset(%d), sz(%d)\n", ioc->name, __func__, | 2026 | "offset(%d), sz(%d)\n", ioc->name, __func__, |
2011 | diag_data, karg.starting_offset, karg.bytes_to_read)); | 2027 | diag_data, karg.starting_offset, karg.bytes_to_read)); |
2012 | 2028 | ||
2029 | /* Truncate data on requests that are too large */ | ||
2030 | if ((diag_data + karg.bytes_to_read < diag_data) || | ||
2031 | (diag_data + karg.bytes_to_read > request_data + request_size)) | ||
2032 | copy_size = request_size - karg.starting_offset; | ||
2033 | else | ||
2034 | copy_size = karg.bytes_to_read; | ||
2035 | |||
2013 | if (copy_to_user((void __user *)uarg->diagnostic_data, | 2036 | if (copy_to_user((void __user *)uarg->diagnostic_data, |
2014 | diag_data, karg.bytes_to_read)) { | 2037 | diag_data, copy_size)) { |
2015 | printk(MPT2SAS_ERR_FMT "%s: Unable to write " | 2038 | printk(MPT2SAS_ERR_FMT "%s: Unable to write " |
2016 | "mpt_diag_read_buffer_t data @ %p\n", ioc->name, | 2039 | "mpt_diag_read_buffer_t data @ %p\n", ioc->name, |
2017 | __func__, diag_data); | 2040 | __func__, diag_data); |
@@ -2238,9 +2261,9 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2238 | { | 2261 | { |
2239 | long ret; | 2262 | long ret; |
2240 | 2263 | ||
2241 | lock_kernel(); | 2264 | mutex_lock(&_ctl_mutex); |
2242 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); | 2265 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); |
2243 | unlock_kernel(); | 2266 | mutex_unlock(&_ctl_mutex); |
2244 | return ret; | 2267 | return ret; |
2245 | } | 2268 | } |
2246 | 2269 | ||
@@ -2309,12 +2332,12 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) | |||
2309 | { | 2332 | { |
2310 | long ret; | 2333 | long ret; |
2311 | 2334 | ||
2312 | lock_kernel(); | 2335 | mutex_lock(&_ctl_mutex); |
2313 | if (cmd == MPT2COMMAND32) | 2336 | if (cmd == MPT2COMMAND32) |
2314 | ret = _ctl_compat_mpt_command(file, cmd, arg); | 2337 | ret = _ctl_compat_mpt_command(file, cmd, arg); |
2315 | else | 2338 | else |
2316 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); | 2339 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); |
2317 | unlock_kernel(); | 2340 | mutex_unlock(&_ctl_mutex); |
2318 | return ret; | 2341 | return ret; |
2319 | } | 2342 | } |
2320 | #endif | 2343 | #endif |
@@ -2952,6 +2975,7 @@ static const struct file_operations ctl_fops = { | |||
2952 | #ifdef CONFIG_COMPAT | 2975 | #ifdef CONFIG_COMPAT |
2953 | .compat_ioctl = _ctl_ioctl_compat, | 2976 | .compat_ioctl = _ctl_ioctl_compat, |
2954 | #endif | 2977 | #endif |
2978 | .llseek = noop_llseek, | ||
2955 | }; | 2979 | }; |
2956 | 2980 | ||
2957 | static struct miscdevice ctl_dev = { | 2981 | static struct miscdevice ctl_dev = { |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h index 69916e46e04f..11ff1d5fb8f0 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h | |||
@@ -133,6 +133,7 @@ struct mpt2_ioctl_pci_info { | |||
133 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) | 133 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) |
134 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) | 134 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) |
135 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) | 135 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) |
136 | #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) | ||
136 | #define MPT2_IOCTL_VERSION_LENGTH (32) | 137 | #define MPT2_IOCTL_VERSION_LENGTH (32) |
137 | 138 | ||
138 | /** | 139 | /** |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 16e99b686354..a7dbc6825f5f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -113,6 +113,7 @@ struct sense_info { | |||
113 | }; | 113 | }; |
114 | 114 | ||
115 | 115 | ||
116 | #define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) | ||
116 | #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) | 117 | #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) |
117 | 118 | ||
118 | /** | 119 | /** |
@@ -121,6 +122,7 @@ struct sense_info { | |||
121 | * @work: work object (ioc->fault_reset_work_q) | 122 | * @work: work object (ioc->fault_reset_work_q) |
122 | * @cancel_pending_work: flag set during reset handling | 123 | * @cancel_pending_work: flag set during reset handling |
123 | * @ioc: per adapter object | 124 | * @ioc: per adapter object |
125 | * @device_handle: device handle | ||
124 | * @VF_ID: virtual function id | 126 | * @VF_ID: virtual function id |
125 | * @VP_ID: virtual port id | 127 | * @VP_ID: virtual port id |
126 | * @ignore: flag meaning this event has been marked to ignore | 128 | * @ignore: flag meaning this event has been marked to ignore |
@@ -134,6 +136,7 @@ struct fw_event_work { | |||
134 | u8 cancel_pending_work; | 136 | u8 cancel_pending_work; |
135 | struct delayed_work delayed_work; | 137 | struct delayed_work delayed_work; |
136 | struct MPT2SAS_ADAPTER *ioc; | 138 | struct MPT2SAS_ADAPTER *ioc; |
139 | u16 device_handle; | ||
137 | u8 VF_ID; | 140 | u8 VF_ID; |
138 | u8 VP_ID; | 141 | u8 VP_ID; |
139 | u8 ignore; | 142 | u8 ignore; |
@@ -233,6 +236,9 @@ static struct pci_device_id scsih_pci_table[] = { | |||
233 | PCI_ANY_ID, PCI_ANY_ID }, | 236 | PCI_ANY_ID, PCI_ANY_ID }, |
234 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, | 237 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, |
235 | PCI_ANY_ID, PCI_ANY_ID }, | 238 | PCI_ANY_ID, PCI_ANY_ID }, |
239 | /* SSS6200 */ | ||
240 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, | ||
241 | PCI_ANY_ID, PCI_ANY_ID }, | ||
236 | {0} /* Terminating entry */ | 242 | {0} /* Terminating entry */ |
237 | }; | 243 | }; |
238 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); | 244 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); |
@@ -397,7 +403,7 @@ _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
397 | * @is_raid: [flag] 1 = raid object, 0 = sas object | 403 | * @is_raid: [flag] 1 = raid object, 0 = sas object |
398 | * | 404 | * |
399 | * Determines whether this device should be first reported device to | 405 | * Determines whether this device should be first reported device to |
400 | * to scsi-ml or sas transport, this purpose is for persistant boot device. | 406 | * to scsi-ml or sas transport, this purpose is for persistent boot device. |
401 | * There are primary, alternate, and current entries in bios page 2. The order | 407 | * There are primary, alternate, and current entries in bios page 2. The order |
402 | * priority is primary, alternate, then current. This routine saves | 408 | * priority is primary, alternate, then current. This routine saves |
403 | * the corresponding device object and is_raid flag in the ioc object. | 409 | * the corresponding device object and is_raid flag in the ioc object. |
@@ -819,7 +825,7 @@ _scsih_is_end_device(u32 device_info) | |||
819 | } | 825 | } |
820 | 826 | ||
821 | /** | 827 | /** |
822 | * mptscsih_get_scsi_lookup - returns scmd entry | 828 | * _scsih_scsi_lookup_get - returns scmd entry |
823 | * @ioc: per adapter object | 829 | * @ioc: per adapter object |
824 | * @smid: system request message index | 830 | * @smid: system request message index |
825 | * | 831 | * |
@@ -832,6 +838,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
832 | } | 838 | } |
833 | 839 | ||
834 | /** | 840 | /** |
841 | * _scsih_scsi_lookup_get_clear - returns scmd entry | ||
842 | * @ioc: per adapter object | ||
843 | * @smid: system request message index | ||
844 | * | ||
845 | * Returns the smid stored scmd pointer. | ||
846 | * Then will derefrence the stored scmd pointer. | ||
847 | */ | ||
848 | static inline struct scsi_cmnd * | ||
849 | _scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid) | ||
850 | { | ||
851 | unsigned long flags; | ||
852 | struct scsi_cmnd *scmd; | ||
853 | |||
854 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
855 | scmd = ioc->scsi_lookup[smid - 1].scmd; | ||
856 | ioc->scsi_lookup[smid - 1].scmd = NULL; | ||
857 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
858 | |||
859 | return scmd; | ||
860 | } | ||
861 | |||
862 | /** | ||
835 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup | 863 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup |
836 | * @ioc: per adapter object | 864 | * @ioc: per adapter object |
837 | * @smid: system request message index | 865 | * @smid: system request message index |
@@ -931,31 +959,32 @@ _scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id, | |||
931 | } | 959 | } |
932 | 960 | ||
933 | /** | 961 | /** |
934 | * _scsih_get_chain_buffer_dma - obtain block of chains (dma address) | 962 | * _scsih_get_chain_buffer_tracker - obtain chain tracker |
935 | * @ioc: per adapter object | 963 | * @ioc: per adapter object |
936 | * @smid: system request message index | 964 | * @smid: smid associated to an IO request |
937 | * | 965 | * |
938 | * Returns phys pointer to chain buffer. | 966 | * Returns chain tracker(from ioc->free_chain_list) |
939 | */ | 967 | */ |
940 | static dma_addr_t | 968 | static struct chain_tracker * |
941 | _scsih_get_chain_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) | 969 | _scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid) |
942 | { | 970 | { |
943 | return ioc->chain_dma + ((smid - 1) * (ioc->request_sz * | 971 | struct chain_tracker *chain_req; |
944 | ioc->chains_needed_per_io)); | 972 | unsigned long flags; |
945 | } | ||
946 | 973 | ||
947 | /** | 974 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); |
948 | * _scsih_get_chain_buffer - obtain block of chains assigned to a mf request | 975 | if (list_empty(&ioc->free_chain_list)) { |
949 | * @ioc: per adapter object | 976 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
950 | * @smid: system request message index | 977 | printk(MPT2SAS_WARN_FMT "chain buffers not available\n", |
951 | * | 978 | ioc->name); |
952 | * Returns virt pointer to chain buffer. | 979 | return NULL; |
953 | */ | 980 | } |
954 | static void * | 981 | chain_req = list_entry(ioc->free_chain_list.next, |
955 | _scsih_get_chain_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid) | 982 | struct chain_tracker, tracker_list); |
956 | { | 983 | list_del_init(&chain_req->tracker_list); |
957 | return (void *)(ioc->chain + ((smid - 1) * (ioc->request_sz * | 984 | list_add_tail(&chain_req->tracker_list, |
958 | ioc->chains_needed_per_io))); | 985 | &ioc->scsi_lookup[smid - 1].chain_list); |
986 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
987 | return chain_req; | ||
959 | } | 988 | } |
960 | 989 | ||
961 | /** | 990 | /** |
@@ -986,6 +1015,7 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc, | |||
986 | u32 sgl_flags; | 1015 | u32 sgl_flags; |
987 | u32 sgl_flags_last_element; | 1016 | u32 sgl_flags_last_element; |
988 | u32 sgl_flags_end_buffer; | 1017 | u32 sgl_flags_end_buffer; |
1018 | struct chain_tracker *chain_req; | ||
989 | 1019 | ||
990 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | 1020 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); |
991 | 1021 | ||
@@ -1033,8 +1063,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc, | |||
1033 | 1063 | ||
1034 | /* initializing the chain flags and pointers */ | 1064 | /* initializing the chain flags and pointers */ |
1035 | chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT; | 1065 | chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT; |
1036 | chain = _scsih_get_chain_buffer(ioc, smid); | 1066 | chain_req = _scsih_get_chain_buffer_tracker(ioc, smid); |
1037 | chain_dma = _scsih_get_chain_buffer_dma(ioc, smid); | 1067 | if (!chain_req) |
1068 | return -1; | ||
1069 | chain = chain_req->chain_buffer; | ||
1070 | chain_dma = chain_req->chain_buffer_dma; | ||
1038 | do { | 1071 | do { |
1039 | sges_in_segment = (sges_left <= | 1072 | sges_in_segment = (sges_left <= |
1040 | ioc->max_sges_in_chain_message) ? sges_left : | 1073 | ioc->max_sges_in_chain_message) ? sges_left : |
@@ -1070,8 +1103,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc, | |||
1070 | sges_in_segment--; | 1103 | sges_in_segment--; |
1071 | } | 1104 | } |
1072 | 1105 | ||
1073 | chain_dma += ioc->request_sz; | 1106 | chain_req = _scsih_get_chain_buffer_tracker(ioc, smid); |
1074 | chain += ioc->request_sz; | 1107 | if (!chain_req) |
1108 | return -1; | ||
1109 | chain = chain_req->chain_buffer; | ||
1110 | chain_dma = chain_req->chain_buffer_dma; | ||
1075 | } while (1); | 1111 | } while (1); |
1076 | 1112 | ||
1077 | 1113 | ||
@@ -1094,28 +1130,24 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc, | |||
1094 | } | 1130 | } |
1095 | 1131 | ||
1096 | /** | 1132 | /** |
1097 | * _scsih_change_queue_depth - setting device queue depth | 1133 | * _scsih_adjust_queue_depth - setting device queue depth |
1098 | * @sdev: scsi device struct | 1134 | * @sdev: scsi device struct |
1099 | * @qdepth: requested queue depth | 1135 | * @qdepth: requested queue depth |
1100 | * @reason: calling context | ||
1101 | * | 1136 | * |
1102 | * Returns queue depth. | 1137 | * |
1138 | * Returns nothing | ||
1103 | */ | 1139 | */ |
1104 | static int | 1140 | static void |
1105 | _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) | 1141 | _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) |
1106 | { | 1142 | { |
1107 | struct Scsi_Host *shost = sdev->host; | 1143 | struct Scsi_Host *shost = sdev->host; |
1108 | int max_depth; | 1144 | int max_depth; |
1109 | int tag_type; | ||
1110 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | 1145 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
1111 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 1146 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
1112 | struct MPT2SAS_TARGET *sas_target_priv_data; | 1147 | struct MPT2SAS_TARGET *sas_target_priv_data; |
1113 | struct _sas_device *sas_device; | 1148 | struct _sas_device *sas_device; |
1114 | unsigned long flags; | 1149 | unsigned long flags; |
1115 | 1150 | ||
1116 | if (reason != SCSI_QDEPTH_DEFAULT) | ||
1117 | return -EOPNOTSUPP; | ||
1118 | |||
1119 | max_depth = shost->can_queue; | 1151 | max_depth = shost->can_queue; |
1120 | 1152 | ||
1121 | /* limit max device queue for SATA to 32 */ | 1153 | /* limit max device queue for SATA to 32 */ |
@@ -1141,8 +1173,27 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) | |||
1141 | max_depth = 1; | 1173 | max_depth = 1; |
1142 | if (qdepth > max_depth) | 1174 | if (qdepth > max_depth) |
1143 | qdepth = max_depth; | 1175 | qdepth = max_depth; |
1144 | tag_type = (qdepth == 1) ? 0 : MSG_SIMPLE_TAG; | 1176 | scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); |
1145 | scsi_adjust_queue_depth(sdev, tag_type, qdepth); | 1177 | } |
1178 | |||
1179 | /** | ||
1180 | * _scsih_change_queue_depth - setting device queue depth | ||
1181 | * @sdev: scsi device struct | ||
1182 | * @qdepth: requested queue depth | ||
1183 | * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP | ||
1184 | * (see include/scsi/scsi_host.h for definition) | ||
1185 | * | ||
1186 | * Returns queue depth. | ||
1187 | */ | ||
1188 | static int | ||
1189 | _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) | ||
1190 | { | ||
1191 | if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) | ||
1192 | _scsih_adjust_queue_depth(sdev, qdepth); | ||
1193 | else if (reason == SCSI_QDEPTH_QFULL) | ||
1194 | scsi_track_queue_full(sdev, qdepth); | ||
1195 | else | ||
1196 | return -EOPNOTSUPP; | ||
1146 | 1197 | ||
1147 | if (sdev->inquiry_len > 7) | 1198 | if (sdev->inquiry_len > 7) |
1148 | sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " | 1199 | sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " |
@@ -1211,6 +1262,7 @@ _scsih_target_alloc(struct scsi_target *starget) | |||
1211 | sas_target_priv_data->handle = raid_device->handle; | 1262 | sas_target_priv_data->handle = raid_device->handle; |
1212 | sas_target_priv_data->sas_address = raid_device->wwid; | 1263 | sas_target_priv_data->sas_address = raid_device->wwid; |
1213 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; | 1264 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; |
1265 | sas_target_priv_data->raid_device = raid_device; | ||
1214 | raid_device->starget = starget; | 1266 | raid_device->starget = starget; |
1215 | } | 1267 | } |
1216 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1268 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
@@ -1410,7 +1462,10 @@ static int | |||
1410 | _scsih_is_raid(struct device *dev) | 1462 | _scsih_is_raid(struct device *dev) |
1411 | { | 1463 | { |
1412 | struct scsi_device *sdev = to_scsi_device(dev); | 1464 | struct scsi_device *sdev = to_scsi_device(dev); |
1465 | struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
1413 | 1466 | ||
1467 | if (ioc->is_warpdrive) | ||
1468 | return 0; | ||
1414 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; | 1469 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; |
1415 | } | 1470 | } |
1416 | 1471 | ||
@@ -1435,7 +1490,7 @@ _scsih_get_resync(struct device *dev) | |||
1435 | sdev->channel); | 1490 | sdev->channel); |
1436 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1491 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1437 | 1492 | ||
1438 | if (!raid_device) | 1493 | if (!raid_device || ioc->is_warpdrive) |
1439 | goto out; | 1494 | goto out; |
1440 | 1495 | ||
1441 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, | 1496 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, |
@@ -1595,6 +1650,212 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
1595 | 1650 | ||
1596 | kfree(vol_pg0); | 1651 | kfree(vol_pg0); |
1597 | } | 1652 | } |
1653 | /** | ||
1654 | * _scsih_disable_ddio - Disable direct I/O for all the volumes | ||
1655 | * @ioc: per adapter object | ||
1656 | */ | ||
1657 | static void | ||
1658 | _scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc) | ||
1659 | { | ||
1660 | Mpi2RaidVolPage1_t vol_pg1; | ||
1661 | Mpi2ConfigReply_t mpi_reply; | ||
1662 | struct _raid_device *raid_device; | ||
1663 | u16 handle; | ||
1664 | u16 ioc_status; | ||
1665 | |||
1666 | handle = 0xFFFF; | ||
1667 | while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | ||
1668 | &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { | ||
1669 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1670 | MPI2_IOCSTATUS_MASK; | ||
1671 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | ||
1672 | break; | ||
1673 | handle = le16_to_cpu(vol_pg1.DevHandle); | ||
1674 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | ||
1675 | if (raid_device) | ||
1676 | raid_device->direct_io_enabled = 0; | ||
1677 | } | ||
1678 | return; | ||
1679 | } | ||
1680 | |||
1681 | |||
1682 | /** | ||
1683 | * _scsih_get_num_volumes - Get number of volumes in the ioc | ||
1684 | * @ioc: per adapter object | ||
1685 | */ | ||
1686 | static u8 | ||
1687 | _scsih_get_num_volumes(struct MPT2SAS_ADAPTER *ioc) | ||
1688 | { | ||
1689 | Mpi2RaidVolPage1_t vol_pg1; | ||
1690 | Mpi2ConfigReply_t mpi_reply; | ||
1691 | u16 handle; | ||
1692 | u8 vol_cnt = 0; | ||
1693 | u16 ioc_status; | ||
1694 | |||
1695 | handle = 0xFFFF; | ||
1696 | while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | ||
1697 | &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { | ||
1698 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1699 | MPI2_IOCSTATUS_MASK; | ||
1700 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | ||
1701 | break; | ||
1702 | vol_cnt++; | ||
1703 | handle = le16_to_cpu(vol_pg1.DevHandle); | ||
1704 | } | ||
1705 | return vol_cnt; | ||
1706 | } | ||
1707 | |||
1708 | |||
1709 | /** | ||
1710 | * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O. | ||
1711 | * @ioc: per adapter object | ||
1712 | * @raid_device: the raid_device object | ||
1713 | */ | ||
1714 | static void | ||
1715 | _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc, | ||
1716 | struct _raid_device *raid_device) | ||
1717 | { | ||
1718 | Mpi2RaidVolPage0_t *vol_pg0; | ||
1719 | Mpi2RaidPhysDiskPage0_t pd_pg0; | ||
1720 | Mpi2ConfigReply_t mpi_reply; | ||
1721 | u16 sz; | ||
1722 | u8 num_pds, count; | ||
1723 | u64 mb = 1024 * 1024; | ||
1724 | u64 tb_2 = 2 * mb * mb; | ||
1725 | u64 capacity; | ||
1726 | u32 stripe_sz; | ||
1727 | u8 i, stripe_exp; | ||
1728 | |||
1729 | if (!ioc->is_warpdrive) | ||
1730 | return; | ||
1731 | |||
1732 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) { | ||
1733 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1734 | "globally as drives are exposed\n", ioc->name); | ||
1735 | return; | ||
1736 | } | ||
1737 | if (_scsih_get_num_volumes(ioc) > 1) { | ||
1738 | _scsih_disable_ddio(ioc); | ||
1739 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1740 | "globally as number of drives > 1\n", ioc->name); | ||
1741 | return; | ||
1742 | } | ||
1743 | if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, | ||
1744 | &num_pds)) || !num_pds) { | ||
1745 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1746 | "Failure in computing number of drives\n", ioc->name); | ||
1747 | return; | ||
1748 | } | ||
1749 | |||
1750 | sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * | ||
1751 | sizeof(Mpi2RaidVol0PhysDisk_t)); | ||
1752 | vol_pg0 = kzalloc(sz, GFP_KERNEL); | ||
1753 | if (!vol_pg0) { | ||
1754 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1755 | "Memory allocation failure for RVPG0\n", ioc->name); | ||
1756 | return; | ||
1757 | } | ||
1758 | |||
1759 | if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, | ||
1760 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { | ||
1761 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1762 | "Failure in retrieving RVPG0\n", ioc->name); | ||
1763 | kfree(vol_pg0); | ||
1764 | return; | ||
1765 | } | ||
1766 | |||
1767 | /* | ||
1768 | * WARPDRIVE:If number of physical disks in a volume exceeds the max pds | ||
1769 | * assumed for WARPDRIVE, disable direct I/O | ||
1770 | */ | ||
1771 | if (num_pds > MPT_MAX_WARPDRIVE_PDS) { | ||
1772 | printk(MPT2SAS_WARN_FMT "WarpDrive : Direct IO is disabled " | ||
1773 | "for the drive with handle(0x%04x): num_mem=%d, " | ||
1774 | "max_mem_allowed=%d\n", ioc->name, raid_device->handle, | ||
1775 | num_pds, MPT_MAX_WARPDRIVE_PDS); | ||
1776 | kfree(vol_pg0); | ||
1777 | return; | ||
1778 | } | ||
1779 | for (count = 0; count < num_pds; count++) { | ||
1780 | if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | ||
1781 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, | ||
1782 | vol_pg0->PhysDisk[count].PhysDiskNum) || | ||
1783 | pd_pg0.DevHandle == MPT2SAS_INVALID_DEVICE_HANDLE) { | ||
1784 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is " | ||
1785 | "disabled for the drive with handle(0x%04x) member" | ||
1786 | "handle retrieval failed for member number=%d\n", | ||
1787 | ioc->name, raid_device->handle, | ||
1788 | vol_pg0->PhysDisk[count].PhysDiskNum); | ||
1789 | goto out_error; | ||
1790 | } | ||
1791 | raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle); | ||
1792 | } | ||
1793 | |||
1794 | /* | ||
1795 | * Assumption for WD: Direct I/O is not supported if the volume is | ||
1796 | * not RAID0, if the stripe size is not 64KB, if the block size is | ||
1797 | * not 512 and if the volume size is >2TB | ||
1798 | */ | ||
1799 | if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 || | ||
1800 | le16_to_cpu(vol_pg0->BlockSize) != 512) { | ||
1801 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1802 | "for the drive with handle(0x%04x): type=%d, " | ||
1803 | "s_sz=%uK, blk_size=%u\n", ioc->name, | ||
1804 | raid_device->handle, raid_device->volume_type, | ||
1805 | le32_to_cpu(vol_pg0->StripeSize)/2, | ||
1806 | le16_to_cpu(vol_pg0->BlockSize)); | ||
1807 | goto out_error; | ||
1808 | } | ||
1809 | |||
1810 | capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) * | ||
1811 | (le64_to_cpu(vol_pg0->MaxLBA) + 1); | ||
1812 | |||
1813 | if (capacity > tb_2) { | ||
1814 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1815 | "for the drive with handle(0x%04x) since drive sz > 2TB\n", | ||
1816 | ioc->name, raid_device->handle); | ||
1817 | goto out_error; | ||
1818 | } | ||
1819 | |||
1820 | stripe_sz = le32_to_cpu(vol_pg0->StripeSize); | ||
1821 | stripe_exp = 0; | ||
1822 | for (i = 0; i < 32; i++) { | ||
1823 | if (stripe_sz & 1) | ||
1824 | break; | ||
1825 | stripe_exp++; | ||
1826 | stripe_sz >>= 1; | ||
1827 | } | ||
1828 | if (i == 32) { | ||
1829 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1830 | "for the drive with handle(0x%04x) invalid stripe sz %uK\n", | ||
1831 | ioc->name, raid_device->handle, | ||
1832 | le32_to_cpu(vol_pg0->StripeSize)/2); | ||
1833 | goto out_error; | ||
1834 | } | ||
1835 | raid_device->stripe_exponent = stripe_exp; | ||
1836 | raid_device->direct_io_enabled = 1; | ||
1837 | |||
1838 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive" | ||
1839 | " with handle(0x%04x)\n", ioc->name, raid_device->handle); | ||
1840 | /* | ||
1841 | * WARPDRIVE: Though the following fields are not used for direct IO, | ||
1842 | * stored for future purpose: | ||
1843 | */ | ||
1844 | raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA); | ||
1845 | raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize); | ||
1846 | raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize); | ||
1847 | |||
1848 | |||
1849 | kfree(vol_pg0); | ||
1850 | return; | ||
1851 | |||
1852 | out_error: | ||
1853 | raid_device->direct_io_enabled = 0; | ||
1854 | for (count = 0; count < num_pds; count++) | ||
1855 | raid_device->pd_handle[count] = 0; | ||
1856 | kfree(vol_pg0); | ||
1857 | return; | ||
1858 | } | ||
1598 | 1859 | ||
1599 | /** | 1860 | /** |
1600 | * _scsih_enable_tlr - setting TLR flags | 1861 | * _scsih_enable_tlr - setting TLR flags |
@@ -1665,6 +1926,11 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1665 | 1926 | ||
1666 | _scsih_get_volume_capabilities(ioc, raid_device); | 1927 | _scsih_get_volume_capabilities(ioc, raid_device); |
1667 | 1928 | ||
1929 | /* | ||
1930 | * WARPDRIVE: Initialize the required data for Direct IO | ||
1931 | */ | ||
1932 | _scsih_init_warpdrive_properties(ioc, raid_device); | ||
1933 | |||
1668 | /* RAID Queue Depth Support | 1934 | /* RAID Queue Depth Support |
1669 | * IS volume = underlying qdepth of drive type, either | 1935 | * IS volume = underlying qdepth of drive type, either |
1670 | * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH | 1936 | * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH |
@@ -1712,14 +1978,16 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1712 | break; | 1978 | break; |
1713 | } | 1979 | } |
1714 | 1980 | ||
1715 | sdev_printk(KERN_INFO, sdev, "%s: " | 1981 | if (!ioc->hide_ir_msg) |
1716 | "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n", | 1982 | sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " |
1717 | r_level, raid_device->handle, | 1983 | "wwid(0x%016llx), pd_count(%d), type(%s)\n", |
1718 | (unsigned long long)raid_device->wwid, | 1984 | r_level, raid_device->handle, |
1719 | raid_device->num_pds, ds); | 1985 | (unsigned long long)raid_device->wwid, |
1986 | raid_device->num_pds, ds); | ||
1720 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); | 1987 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
1721 | /* raid transport support */ | 1988 | /* raid transport support */ |
1722 | _scsih_set_level(sdev, raid_device); | 1989 | if (!ioc->is_warpdrive) |
1990 | _scsih_set_level(sdev, raid_device); | ||
1723 | return 0; | 1991 | return 0; |
1724 | } | 1992 | } |
1725 | 1993 | ||
@@ -2088,8 +2356,7 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel, | |||
2088 | switch (type) { | 2356 | switch (type) { |
2089 | case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: | 2357 | case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: |
2090 | scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task); | 2358 | scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task); |
2091 | if (scmd_lookup && (scmd_lookup->serial_number == | 2359 | if (scmd_lookup) |
2092 | scmd->serial_number)) | ||
2093 | rc = FAILED; | 2360 | rc = FAILED; |
2094 | else | 2361 | else |
2095 | rc = SUCCESS; | 2362 | rc = SUCCESS; |
@@ -2137,16 +2404,20 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2137 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; | 2404 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; |
2138 | struct _sas_device *sas_device = NULL; | 2405 | struct _sas_device *sas_device = NULL; |
2139 | unsigned long flags; | 2406 | unsigned long flags; |
2407 | char *device_str = NULL; | ||
2140 | 2408 | ||
2141 | if (!priv_target) | 2409 | if (!priv_target) |
2142 | return; | 2410 | return; |
2411 | if (ioc->hide_ir_msg) | ||
2412 | device_str = "WarpDrive"; | ||
2413 | else | ||
2414 | device_str = "volume"; | ||
2143 | 2415 | ||
2144 | scsi_print_command(scmd); | 2416 | scsi_print_command(scmd); |
2145 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { | 2417 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { |
2146 | starget_printk(KERN_INFO, starget, "volume handle(0x%04x), " | 2418 | starget_printk(KERN_INFO, starget, "%s handle(0x%04x), " |
2147 | "volume wwid(0x%016llx)\n", | 2419 | "%s wwid(0x%016llx)\n", device_str, priv_target->handle, |
2148 | priv_target->handle, | 2420 | device_str, (unsigned long long)priv_target->sas_address); |
2149 | (unsigned long long)priv_target->sas_address); | ||
2150 | } else { | 2421 | } else { |
2151 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2422 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2152 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 2423 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, |
@@ -2251,13 +2522,13 @@ _scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2251 | 2522 | ||
2252 | struct scsi_target *starget = scmd->device->sdev_target; | 2523 | struct scsi_target *starget = scmd->device->sdev_target; |
2253 | 2524 | ||
2254 | starget_printk(KERN_INFO, starget, "attempting target reset! " | 2525 | starget_printk(KERN_INFO, starget, "attempting device reset! " |
2255 | "scmd(%p)\n", scmd); | 2526 | "scmd(%p)\n", scmd); |
2256 | _scsih_tm_display_info(ioc, scmd); | 2527 | _scsih_tm_display_info(ioc, scmd); |
2257 | 2528 | ||
2258 | sas_device_priv_data = scmd->device->hostdata; | 2529 | sas_device_priv_data = scmd->device->hostdata; |
2259 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2530 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { |
2260 | starget_printk(KERN_INFO, starget, "target been deleted! " | 2531 | starget_printk(KERN_INFO, starget, "device been deleted! " |
2261 | "scmd(%p)\n", scmd); | 2532 | "scmd(%p)\n", scmd); |
2262 | scmd->result = DID_NO_CONNECT << 16; | 2533 | scmd->result = DID_NO_CONNECT << 16; |
2263 | scmd->scsi_done(scmd); | 2534 | scmd->scsi_done(scmd); |
@@ -2576,9 +2847,9 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc, | |||
2576 | &sas_expander->sas_port_list, port_list) { | 2847 | &sas_expander->sas_port_list, port_list) { |
2577 | 2848 | ||
2578 | if (mpt2sas_port->remote_identify.device_type == | 2849 | if (mpt2sas_port->remote_identify.device_type == |
2579 | MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || | 2850 | SAS_EDGE_EXPANDER_DEVICE || |
2580 | mpt2sas_port->remote_identify.device_type == | 2851 | mpt2sas_port->remote_identify.device_type == |
2581 | MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) { | 2852 | SAS_FANOUT_EXPANDER_DEVICE) { |
2582 | 2853 | ||
2583 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 2854 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
2584 | expander_sibling = | 2855 | expander_sibling = |
@@ -2626,10 +2897,10 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc, | |||
2626 | * @handle: device handle | 2897 | * @handle: device handle |
2627 | * Context: interrupt time. | 2898 | * Context: interrupt time. |
2628 | * | 2899 | * |
2629 | * This code is to initiate the device removal handshake protocal | 2900 | * This code is to initiate the device removal handshake protocol |
2630 | * with controller firmware. This function will issue target reset | 2901 | * with controller firmware. This function will issue target reset |
2631 | * using high priority request queue. It will send a sas iounit | 2902 | * using high priority request queue. It will send a sas iounit |
2632 | * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. | 2903 | * control request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. |
2633 | * | 2904 | * |
2634 | * This is designed to send muliple task management request at the same | 2905 | * This is designed to send muliple task management request at the same |
2635 | * time to the fifo. If the fifo is full, we will append the request, | 2906 | * time to the fifo. If the fifo is full, we will append the request, |
@@ -2704,9 +2975,9 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
2704 | * @reply: reply message frame(lower 32bit addr) | 2975 | * @reply: reply message frame(lower 32bit addr) |
2705 | * Context: interrupt time. | 2976 | * Context: interrupt time. |
2706 | * | 2977 | * |
2707 | * This is the sas iounit controll completion routine. | 2978 | * This is the sas iounit control completion routine. |
2708 | * This code is part of the code to initiate the device removal | 2979 | * This code is part of the code to initiate the device removal |
2709 | * handshake protocal with controller firmware. | 2980 | * handshake protocol with controller firmware. |
2710 | * | 2981 | * |
2711 | * Return 1 meaning mf should be freed from _base_interrupt | 2982 | * Return 1 meaning mf should be freed from _base_interrupt |
2712 | * 0 means the mf is freed from this function. | 2983 | * 0 means the mf is freed from this function. |
@@ -2715,9 +2986,10 @@ static u8 | |||
2715 | _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, | 2986 | _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, |
2716 | u8 msix_index, u32 reply) | 2987 | u8 msix_index, u32 reply) |
2717 | { | 2988 | { |
2989 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | ||
2718 | Mpi2SasIoUnitControlReply_t *mpi_reply = | 2990 | Mpi2SasIoUnitControlReply_t *mpi_reply = |
2719 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | 2991 | mpt2sas_base_get_reply_virt_addr(ioc, reply); |
2720 | 2992 | #endif | |
2721 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | 2993 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT |
2722 | "sc_complete:handle(0x%04x), (open) " | 2994 | "sc_complete:handle(0x%04x), (open) " |
2723 | "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", | 2995 | "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", |
@@ -2832,8 +3104,8 @@ _scsih_tm_volume_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, | |||
2832 | * | 3104 | * |
2833 | * This is the target reset completion routine. | 3105 | * This is the target reset completion routine. |
2834 | * This code is part of the code to initiate the device removal | 3106 | * This code is part of the code to initiate the device removal |
2835 | * handshake protocal with controller firmware. | 3107 | * handshake protocol with controller firmware. |
2836 | * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE) | 3108 | * It will send a sas iounit control request (MPI2_SAS_OP_REMOVE_DEVICE) |
2837 | * | 3109 | * |
2838 | * Return 1 meaning mf should be freed from _base_interrupt | 3110 | * Return 1 meaning mf should be freed from _base_interrupt |
2839 | * 0 means the mf is freed from this function. | 3111 | * 0 means the mf is freed from this function. |
@@ -2938,7 +3210,7 @@ _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
2938 | * | 3210 | * |
2939 | * This routine added to better handle cable breaker. | 3211 | * This routine added to better handle cable breaker. |
2940 | * | 3212 | * |
2941 | * This handles the case where driver recieves multiple expander | 3213 | * This handles the case where driver receives multiple expander |
2942 | * add and delete events in a single shot. When there is a delete event | 3214 | * add and delete events in a single shot. When there is a delete event |
2943 | * the routine will void any pending add events waiting in the event queue. | 3215 | * the routine will void any pending add events waiting in the event queue. |
2944 | * | 3216 | * |
@@ -2957,9 +3229,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, | |||
2957 | u16 handle; | 3229 | u16 handle; |
2958 | 3230 | ||
2959 | for (i = 0 ; i < event_data->NumEntries; i++) { | 3231 | for (i = 0 ; i < event_data->NumEntries; i++) { |
2960 | if (event_data->PHY[i].PhyStatus & | ||
2961 | MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) | ||
2962 | continue; | ||
2963 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | 3232 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); |
2964 | if (!handle) | 3233 | if (!handle) |
2965 | continue; | 3234 | continue; |
@@ -3087,6 +3356,9 @@ _scsih_check_ir_config_unhide_events(struct MPT2SAS_ADAPTER *ioc, | |||
3087 | a = 0; | 3356 | a = 0; |
3088 | b = 0; | 3357 | b = 0; |
3089 | 3358 | ||
3359 | if (ioc->is_warpdrive) | ||
3360 | return; | ||
3361 | |||
3090 | /* Volume Resets for Deleted or Removed */ | 3362 | /* Volume Resets for Deleted or Removed */ |
3091 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 3363 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
3092 | for (i = 0; i < event_data->NumElements; i++, element++) { | 3364 | for (i = 0; i < event_data->NumElements; i++, element++) { |
@@ -3186,7 +3458,7 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc) | |||
3186 | u16 count = 0; | 3458 | u16 count = 0; |
3187 | 3459 | ||
3188 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { | 3460 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { |
3189 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3461 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
3190 | if (!scmd) | 3462 | if (!scmd) |
3191 | continue; | 3463 | continue; |
3192 | count++; | 3464 | count++; |
@@ -3230,6 +3502,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
3230 | 3502 | ||
3231 | switch (prot_type) { | 3503 | switch (prot_type) { |
3232 | case SCSI_PROT_DIF_TYPE1: | 3504 | case SCSI_PROT_DIF_TYPE1: |
3505 | case SCSI_PROT_DIF_TYPE2: | ||
3233 | 3506 | ||
3234 | /* | 3507 | /* |
3235 | * enable ref/guard checking | 3508 | * enable ref/guard checking |
@@ -3242,13 +3515,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
3242 | cpu_to_be32(scsi_get_lba(scmd)); | 3515 | cpu_to_be32(scsi_get_lba(scmd)); |
3243 | break; | 3516 | break; |
3244 | 3517 | ||
3245 | case SCSI_PROT_DIF_TYPE2: | ||
3246 | |||
3247 | eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | | ||
3248 | MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | | ||
3249 | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; | ||
3250 | break; | ||
3251 | |||
3252 | case SCSI_PROT_DIF_TYPE3: | 3518 | case SCSI_PROT_DIF_TYPE3: |
3253 | 3519 | ||
3254 | /* | 3520 | /* |
@@ -3304,6 +3570,105 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) | |||
3304 | } | 3570 | } |
3305 | 3571 | ||
3306 | /** | 3572 | /** |
3573 | * _scsih_scsi_direct_io_get - returns direct io flag | ||
3574 | * @ioc: per adapter object | ||
3575 | * @smid: system request message index | ||
3576 | * | ||
3577 | * Returns the smid stored scmd pointer. | ||
3578 | */ | ||
3579 | static inline u8 | ||
3580 | _scsih_scsi_direct_io_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) | ||
3581 | { | ||
3582 | return ioc->scsi_lookup[smid - 1].direct_io; | ||
3583 | } | ||
3584 | |||
3585 | /** | ||
3586 | * _scsih_scsi_direct_io_set - sets direct io flag | ||
3587 | * @ioc: per adapter object | ||
3588 | * @smid: system request message index | ||
3589 | * @direct_io: Zero or non-zero value to set in the direct_io flag | ||
3590 | * | ||
3591 | * Returns Nothing. | ||
3592 | */ | ||
3593 | static inline void | ||
3594 | _scsih_scsi_direct_io_set(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 direct_io) | ||
3595 | { | ||
3596 | ioc->scsi_lookup[smid - 1].direct_io = direct_io; | ||
3597 | } | ||
3598 | |||
3599 | |||
3600 | /** | ||
3601 | * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O | ||
3602 | * @ioc: per adapter object | ||
3603 | * @scmd: pointer to scsi command object | ||
3604 | * @raid_device: pointer to raid device data structure | ||
3605 | * @mpi_request: pointer to the SCSI_IO reqest message frame | ||
3606 | * @smid: system request message index | ||
3607 | * | ||
3608 | * Returns nothing | ||
3609 | */ | ||
3610 | static void | ||
3611 | _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | ||
3612 | struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, | ||
3613 | u16 smid) | ||
3614 | { | ||
3615 | u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size; | ||
3616 | u32 stripe_sz, stripe_exp; | ||
3617 | u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2; | ||
3618 | u8 cdb0 = scmd->cmnd[0]; | ||
3619 | |||
3620 | /* | ||
3621 | * Try Direct I/O to RAID memeber disks | ||
3622 | */ | ||
3623 | if (cdb0 == READ_16 || cdb0 == READ_10 || | ||
3624 | cdb0 == WRITE_16 || cdb0 == WRITE_10) { | ||
3625 | cdb_ptr = mpi_request->CDB.CDB32; | ||
3626 | |||
3627 | if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4] | ||
3628 | | cdb_ptr[5])) { | ||
3629 | io_size = scsi_bufflen(scmd) >> 9; | ||
3630 | /* get virtual lba */ | ||
3631 | lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] : | ||
3632 | &cdb_ptr[6]; | ||
3633 | tmp_ptr = (u8 *)&v_lba + 3; | ||
3634 | *tmp_ptr-- = *lba_ptr1++; | ||
3635 | *tmp_ptr-- = *lba_ptr1++; | ||
3636 | *tmp_ptr-- = *lba_ptr1++; | ||
3637 | *tmp_ptr = *lba_ptr1; | ||
3638 | |||
3639 | if (((u64)v_lba + (u64)io_size - 1) <= | ||
3640 | (u32)raid_device->max_lba) { | ||
3641 | stripe_sz = raid_device->stripe_sz; | ||
3642 | stripe_exp = raid_device->stripe_exponent; | ||
3643 | stripe_off = v_lba & (stripe_sz - 1); | ||
3644 | |||
3645 | /* Check whether IO falls within a stripe */ | ||
3646 | if ((stripe_off + io_size) <= stripe_sz) { | ||
3647 | num_pds = raid_device->num_pds; | ||
3648 | p_lba = v_lba >> stripe_exp; | ||
3649 | stripe_unit = p_lba / num_pds; | ||
3650 | column = p_lba % num_pds; | ||
3651 | p_lba = (stripe_unit << stripe_exp) + | ||
3652 | stripe_off; | ||
3653 | mpi_request->DevHandle = | ||
3654 | cpu_to_le16(raid_device-> | ||
3655 | pd_handle[column]); | ||
3656 | tmp_ptr = (u8 *)&p_lba + 3; | ||
3657 | *lba_ptr2++ = *tmp_ptr--; | ||
3658 | *lba_ptr2++ = *tmp_ptr--; | ||
3659 | *lba_ptr2++ = *tmp_ptr--; | ||
3660 | *lba_ptr2 = *tmp_ptr; | ||
3661 | /* | ||
3662 | * WD: To indicate this I/O is directI/O | ||
3663 | */ | ||
3664 | _scsih_scsi_direct_io_set(ioc, smid, 1); | ||
3665 | } | ||
3666 | } | ||
3667 | } | ||
3668 | } | ||
3669 | } | ||
3670 | |||
3671 | /** | ||
3307 | * _scsih_qcmd - main scsi request entry point | 3672 | * _scsih_qcmd - main scsi request entry point |
3308 | * @scmd: pointer to scsi command object | 3673 | * @scmd: pointer to scsi command object |
3309 | * @done: function pointer to be invoked on completion | 3674 | * @done: function pointer to be invoked on completion |
@@ -3315,11 +3680,12 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) | |||
3315 | * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full | 3680 | * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full |
3316 | */ | 3681 | */ |
3317 | static int | 3682 | static int |
3318 | _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | 3683 | _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) |
3319 | { | 3684 | { |
3320 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 3685 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
3321 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 3686 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
3322 | struct MPT2SAS_TARGET *sas_target_priv_data; | 3687 | struct MPT2SAS_TARGET *sas_target_priv_data; |
3688 | struct _raid_device *raid_device; | ||
3323 | Mpi2SCSIIORequest_t *mpi_request; | 3689 | Mpi2SCSIIORequest_t *mpi_request; |
3324 | u32 mpi_control; | 3690 | u32 mpi_control; |
3325 | u16 smid; | 3691 | u16 smid; |
@@ -3381,8 +3747,10 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3381 | 3747 | ||
3382 | } else | 3748 | } else |
3383 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3749 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
3384 | /* Make sure Device is not raid volume */ | 3750 | /* Make sure Device is not raid volume. |
3385 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && | 3751 | * We do not expose raid functionality to upper layer for warpdrive. |
3752 | */ | ||
3753 | if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) && | ||
3386 | sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) | 3754 | sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) |
3387 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3755 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
3388 | 3756 | ||
@@ -3430,9 +3798,14 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3430 | } | 3798 | } |
3431 | } | 3799 | } |
3432 | 3800 | ||
3801 | raid_device = sas_target_priv_data->raid_device; | ||
3802 | if (raid_device && raid_device->direct_io_enabled) | ||
3803 | _scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request, | ||
3804 | smid); | ||
3805 | |||
3433 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) | 3806 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) |
3434 | mpt2sas_base_put_smid_scsi_io(ioc, smid, | 3807 | mpt2sas_base_put_smid_scsi_io(ioc, smid, |
3435 | sas_device_priv_data->sas_target->handle); | 3808 | le16_to_cpu(mpi_request->DevHandle)); |
3436 | else | 3809 | else |
3437 | mpt2sas_base_put_smid_default(ioc, smid); | 3810 | mpt2sas_base_put_smid_default(ioc, smid); |
3438 | return 0; | 3811 | return 0; |
@@ -3441,6 +3814,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3441 | return SCSI_MLQUEUE_HOST_BUSY; | 3814 | return SCSI_MLQUEUE_HOST_BUSY; |
3442 | } | 3815 | } |
3443 | 3816 | ||
3817 | static DEF_SCSI_QCMD(_scsih_qcmd) | ||
3818 | |||
3444 | /** | 3819 | /** |
3445 | * _scsih_normalize_sense - normalize descriptor and fixed format sense data | 3820 | * _scsih_normalize_sense - normalize descriptor and fixed format sense data |
3446 | * @sense_buffer: sense data returned by target | 3821 | * @sense_buffer: sense data returned by target |
@@ -3466,7 +3841,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data) | |||
3466 | 3841 | ||
3467 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 3842 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
3468 | /** | 3843 | /** |
3469 | * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request | 3844 | * _scsih_scsi_ioc_info - translated non-successful SCSI_IO request |
3470 | * @ioc: per adapter object | 3845 | * @ioc: per adapter object |
3471 | * @scmd: pointer to scsi command object | 3846 | * @scmd: pointer to scsi command object |
3472 | * @mpi_reply: reply mf payload returned from firmware | 3847 | * @mpi_reply: reply mf payload returned from firmware |
@@ -3495,10 +3870,16 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3495 | unsigned long flags; | 3870 | unsigned long flags; |
3496 | struct scsi_target *starget = scmd->device->sdev_target; | 3871 | struct scsi_target *starget = scmd->device->sdev_target; |
3497 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; | 3872 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; |
3873 | char *device_str = NULL; | ||
3498 | 3874 | ||
3499 | if (!priv_target) | 3875 | if (!priv_target) |
3500 | return; | 3876 | return; |
3501 | 3877 | ||
3878 | if (ioc->hide_ir_msg) | ||
3879 | device_str = "WarpDrive"; | ||
3880 | else | ||
3881 | device_str = "volume"; | ||
3882 | |||
3502 | if (log_info == 0x31170000) | 3883 | if (log_info == 0x31170000) |
3503 | return; | 3884 | return; |
3504 | 3885 | ||
@@ -3615,8 +3996,8 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3615 | scsi_print_command(scmd); | 3996 | scsi_print_command(scmd); |
3616 | 3997 | ||
3617 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { | 3998 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { |
3618 | printk(MPT2SAS_WARN_FMT "\tvolume wwid(0x%016llx)\n", ioc->name, | 3999 | printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name, |
3619 | (unsigned long long)priv_target->sas_address); | 4000 | device_str, (unsigned long long)priv_target->sas_address); |
3620 | } else { | 4001 | } else { |
3621 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4002 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
3622 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 4003 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, |
@@ -3663,17 +4044,75 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3663 | #endif | 4044 | #endif |
3664 | 4045 | ||
3665 | /** | 4046 | /** |
3666 | * _scsih_smart_predicted_fault - illuminate Fault LED | 4047 | * _scsih_turn_on_fault_led - illuminate Fault LED |
3667 | * @ioc: per adapter object | 4048 | * @ioc: per adapter object |
3668 | * @handle: device handle | 4049 | * @handle: device handle |
4050 | * Context: process | ||
3669 | * | 4051 | * |
3670 | * Return nothing. | 4052 | * Return nothing. |
3671 | */ | 4053 | */ |
3672 | static void | 4054 | static void |
3673 | _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 4055 | _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) |
3674 | { | 4056 | { |
3675 | Mpi2SepReply_t mpi_reply; | 4057 | Mpi2SepReply_t mpi_reply; |
3676 | Mpi2SepRequest_t mpi_request; | 4058 | Mpi2SepRequest_t mpi_request; |
4059 | |||
4060 | memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); | ||
4061 | mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | ||
4062 | mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; | ||
4063 | mpi_request.SlotStatus = | ||
4064 | cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); | ||
4065 | mpi_request.DevHandle = cpu_to_le16(handle); | ||
4066 | mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; | ||
4067 | if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, | ||
4068 | &mpi_request)) != 0) { | ||
4069 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, | ||
4070 | __FILE__, __LINE__, __func__); | ||
4071 | return; | ||
4072 | } | ||
4073 | |||
4074 | if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { | ||
4075 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: " | ||
4076 | "ioc_status (0x%04x), loginfo(0x%08x)\n", ioc->name, | ||
4077 | le16_to_cpu(mpi_reply.IOCStatus), | ||
4078 | le32_to_cpu(mpi_reply.IOCLogInfo))); | ||
4079 | return; | ||
4080 | } | ||
4081 | } | ||
4082 | |||
4083 | /** | ||
4084 | * _scsih_send_event_to_turn_on_fault_led - fire delayed event | ||
4085 | * @ioc: per adapter object | ||
4086 | * @handle: device handle | ||
4087 | * Context: interrupt. | ||
4088 | * | ||
4089 | * Return nothing. | ||
4090 | */ | ||
4091 | static void | ||
4092 | _scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
4093 | { | ||
4094 | struct fw_event_work *fw_event; | ||
4095 | |||
4096 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | ||
4097 | if (!fw_event) | ||
4098 | return; | ||
4099 | fw_event->event = MPT2SAS_TURN_ON_FAULT_LED; | ||
4100 | fw_event->device_handle = handle; | ||
4101 | fw_event->ioc = ioc; | ||
4102 | _scsih_fw_event_add(ioc, fw_event); | ||
4103 | } | ||
4104 | |||
4105 | /** | ||
4106 | * _scsih_smart_predicted_fault - process smart errors | ||
4107 | * @ioc: per adapter object | ||
4108 | * @handle: device handle | ||
4109 | * Context: interrupt. | ||
4110 | * | ||
4111 | * Return nothing. | ||
4112 | */ | ||
4113 | static void | ||
4114 | _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
4115 | { | ||
3677 | struct scsi_target *starget; | 4116 | struct scsi_target *starget; |
3678 | struct MPT2SAS_TARGET *sas_target_priv_data; | 4117 | struct MPT2SAS_TARGET *sas_target_priv_data; |
3679 | Mpi2EventNotificationReply_t *event_reply; | 4118 | Mpi2EventNotificationReply_t *event_reply; |
@@ -3700,30 +4139,8 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3700 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); | 4139 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); |
3701 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4140 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
3702 | 4141 | ||
3703 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) { | 4142 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) |
3704 | memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); | 4143 | _scsih_send_event_to_turn_on_fault_led(ioc, handle); |
3705 | mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | ||
3706 | mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; | ||
3707 | mpi_request.SlotStatus = | ||
3708 | cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); | ||
3709 | mpi_request.DevHandle = cpu_to_le16(handle); | ||
3710 | mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; | ||
3711 | if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, | ||
3712 | &mpi_request)) != 0) { | ||
3713 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
3714 | ioc->name, __FILE__, __LINE__, __func__); | ||
3715 | return; | ||
3716 | } | ||
3717 | |||
3718 | if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { | ||
3719 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
3720 | "enclosure_processor: ioc_status (0x%04x), " | ||
3721 | "loginfo(0x%08x)\n", ioc->name, | ||
3722 | le16_to_cpu(mpi_reply.IOCStatus), | ||
3723 | le32_to_cpu(mpi_reply.IOCLogInfo))); | ||
3724 | return; | ||
3725 | } | ||
3726 | } | ||
3727 | 4144 | ||
3728 | /* insert into event log */ | 4145 | /* insert into event log */ |
3729 | sz = offsetof(Mpi2EventNotificationReply_t, EventData) + | 4146 | sz = offsetof(Mpi2EventNotificationReply_t, EventData) + |
@@ -3778,7 +4195,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3778 | u32 response_code = 0; | 4195 | u32 response_code = 0; |
3779 | 4196 | ||
3780 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 4197 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
3781 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 4198 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
3782 | if (scmd == NULL) | 4199 | if (scmd == NULL) |
3783 | return 1; | 4200 | return 1; |
3784 | 4201 | ||
@@ -3795,6 +4212,20 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3795 | scmd->result = DID_NO_CONNECT << 16; | 4212 | scmd->result = DID_NO_CONNECT << 16; |
3796 | goto out; | 4213 | goto out; |
3797 | } | 4214 | } |
4215 | /* | ||
4216 | * WARPDRIVE: If direct_io is set then it is directIO, | ||
4217 | * the failed direct I/O should be redirected to volume | ||
4218 | */ | ||
4219 | if (_scsih_scsi_direct_io_get(ioc, smid)) { | ||
4220 | _scsih_scsi_direct_io_set(ioc, smid, 0); | ||
4221 | memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); | ||
4222 | mpi_request->DevHandle = | ||
4223 | cpu_to_le16(sas_device_priv_data->sas_target->handle); | ||
4224 | mpt2sas_base_put_smid_scsi_io(ioc, smid, | ||
4225 | sas_device_priv_data->sas_target->handle); | ||
4226 | return 0; | ||
4227 | } | ||
4228 | |||
3798 | 4229 | ||
3799 | /* turning off TLR */ | 4230 | /* turning off TLR */ |
3800 | scsi_state = mpi_reply->SCSIState; | 4231 | scsi_state = mpi_reply->SCSIState; |
@@ -3803,7 +4234,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3803 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | 4234 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; |
3804 | if (!sas_device_priv_data->tlr_snoop_check) { | 4235 | if (!sas_device_priv_data->tlr_snoop_check) { |
3805 | sas_device_priv_data->tlr_snoop_check++; | 4236 | sas_device_priv_data->tlr_snoop_check++; |
3806 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && | 4237 | /* Make sure Device is not raid volume. |
4238 | * We do not expose raid functionality to upper layer for warpdrive. | ||
4239 | */ | ||
4240 | if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) && | ||
3807 | sas_is_tlr_enabled(scmd->device) && | 4241 | sas_is_tlr_enabled(scmd->device) && |
3808 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { | 4242 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { |
3809 | sas_disable_tlr(scmd->device); | 4243 | sas_disable_tlr(scmd->device); |
@@ -3961,6 +4395,7 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc) | |||
3961 | Mpi2ConfigReply_t mpi_reply; | 4395 | Mpi2ConfigReply_t mpi_reply; |
3962 | Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; | 4396 | Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; |
3963 | u16 attached_handle; | 4397 | u16 attached_handle; |
4398 | u8 link_rate; | ||
3964 | 4399 | ||
3965 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 4400 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
3966 | "updating handles for sas_host(0x%016llx)\n", | 4401 | "updating handles for sas_host(0x%016llx)\n", |
@@ -3982,15 +4417,17 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc) | |||
3982 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) | 4417 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) |
3983 | goto out; | 4418 | goto out; |
3984 | for (i = 0; i < ioc->sas_hba.num_phys ; i++) { | 4419 | for (i = 0; i < ioc->sas_hba.num_phys ; i++) { |
4420 | link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4; | ||
3985 | if (i == 0) | 4421 | if (i == 0) |
3986 | ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> | 4422 | ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> |
3987 | PhyData[0].ControllerDevHandle); | 4423 | PhyData[0].ControllerDevHandle); |
3988 | ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; | 4424 | ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; |
3989 | attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. | 4425 | attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. |
3990 | AttachedDevHandle); | 4426 | AttachedDevHandle); |
4427 | if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) | ||
4428 | link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; | ||
3991 | mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, | 4429 | mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, |
3992 | attached_handle, i, sas_iounit_pg0->PhyData[i]. | 4430 | attached_handle, i, link_rate); |
3993 | NegotiatedLinkRate >> 4); | ||
3994 | } | 4431 | } |
3995 | out: | 4432 | out: |
3996 | kfree(sas_iounit_pg0); | 4433 | kfree(sas_iounit_pg0); |
@@ -4334,14 +4771,14 @@ _scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4334 | } | 4771 | } |
4335 | 4772 | ||
4336 | /** | 4773 | /** |
4337 | * _scsih_expander_remove - removing expander object | 4774 | * mpt2sas_expander_remove - removing expander object |
4338 | * @ioc: per adapter object | 4775 | * @ioc: per adapter object |
4339 | * @sas_address: expander sas_address | 4776 | * @sas_address: expander sas_address |
4340 | * | 4777 | * |
4341 | * Return nothing. | 4778 | * Return nothing. |
4342 | */ | 4779 | */ |
4343 | static void | 4780 | void |
4344 | _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) | 4781 | mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) |
4345 | { | 4782 | { |
4346 | struct _sas_node *sas_expander; | 4783 | struct _sas_node *sas_expander; |
4347 | unsigned long flags; | 4784 | unsigned long flags; |
@@ -4352,6 +4789,11 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) | |||
4352 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 4789 | spin_lock_irqsave(&ioc->sas_node_lock, flags); |
4353 | sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, | 4790 | sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, |
4354 | sas_address); | 4791 | sas_address); |
4792 | if (!sas_expander) { | ||
4793 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | ||
4794 | return; | ||
4795 | } | ||
4796 | list_del(&sas_expander->list); | ||
4355 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 4797 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
4356 | _scsih_expander_node_remove(ioc, sas_expander); | 4798 | _scsih_expander_node_remove(ioc, sas_expander); |
4357 | } | 4799 | } |
@@ -4628,8 +5070,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, | |||
4628 | 5070 | ||
4629 | _scsih_ublock_io_device(ioc, sas_device_backup.handle); | 5071 | _scsih_ublock_io_device(ioc, sas_device_backup.handle); |
4630 | 5072 | ||
4631 | mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address, | 5073 | if (!ioc->hide_drives) |
4632 | sas_device_backup.sas_address_parent); | 5074 | mpt2sas_transport_port_remove(ioc, |
5075 | sas_device_backup.sas_address, | ||
5076 | sas_device_backup.sas_address_parent); | ||
4633 | 5077 | ||
4634 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" | 5078 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" |
4635 | "(0x%016llx)\n", ioc->name, sas_device_backup.handle, | 5079 | "(0x%016llx)\n", ioc->name, sas_device_backup.handle, |
@@ -4641,6 +5085,33 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, | |||
4641 | sas_device_backup.sas_address)); | 5085 | sas_device_backup.sas_address)); |
4642 | } | 5086 | } |
4643 | 5087 | ||
5088 | /** | ||
5089 | * mpt2sas_device_remove - removing device object | ||
5090 | * @ioc: per adapter object | ||
5091 | * @sas_address: expander sas_address | ||
5092 | * | ||
5093 | * Return nothing. | ||
5094 | */ | ||
5095 | void | ||
5096 | mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) | ||
5097 | { | ||
5098 | struct _sas_device *sas_device; | ||
5099 | unsigned long flags; | ||
5100 | |||
5101 | if (ioc->shost_recovery) | ||
5102 | return; | ||
5103 | |||
5104 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
5105 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
5106 | sas_address); | ||
5107 | if (!sas_device) { | ||
5108 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5109 | return; | ||
5110 | } | ||
5111 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5112 | _scsih_remove_device(ioc, sas_device); | ||
5113 | } | ||
5114 | |||
4644 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5115 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
4645 | /** | 5116 | /** |
4646 | * _scsih_sas_topology_change_event_debug - debug for topology event | 5117 | * _scsih_sas_topology_change_event_debug - debug for topology event |
@@ -4735,7 +5206,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4735 | int i; | 5206 | int i; |
4736 | u16 parent_handle, handle; | 5207 | u16 parent_handle, handle; |
4737 | u16 reason_code; | 5208 | u16 reason_code; |
4738 | u8 phy_number; | 5209 | u8 phy_number, max_phys; |
4739 | struct _sas_node *sas_expander; | 5210 | struct _sas_node *sas_expander; |
4740 | struct _sas_device *sas_device; | 5211 | struct _sas_device *sas_device; |
4741 | u64 sas_address; | 5212 | u64 sas_address; |
@@ -4773,11 +5244,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4773 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, | 5244 | sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, |
4774 | parent_handle); | 5245 | parent_handle); |
4775 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | 5246 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); |
4776 | if (sas_expander) | 5247 | if (sas_expander) { |
4777 | sas_address = sas_expander->sas_address; | 5248 | sas_address = sas_expander->sas_address; |
4778 | else if (parent_handle < ioc->sas_hba.num_phys) | 5249 | max_phys = sas_expander->num_phys; |
5250 | } else if (parent_handle < ioc->sas_hba.num_phys) { | ||
4779 | sas_address = ioc->sas_hba.sas_address; | 5251 | sas_address = ioc->sas_hba.sas_address; |
4780 | else | 5252 | max_phys = ioc->sas_hba.num_phys; |
5253 | } else | ||
4781 | return; | 5254 | return; |
4782 | 5255 | ||
4783 | /* handle siblings events */ | 5256 | /* handle siblings events */ |
@@ -4791,6 +5264,8 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4791 | ioc->pci_error_recovery) | 5264 | ioc->pci_error_recovery) |
4792 | return; | 5265 | return; |
4793 | phy_number = event_data->StartPhyNum + i; | 5266 | phy_number = event_data->StartPhyNum + i; |
5267 | if (phy_number >= max_phys) | ||
5268 | continue; | ||
4794 | reason_code = event_data->PHY[i].PhyStatus & | 5269 | reason_code = event_data->PHY[i].PhyStatus & |
4795 | MPI2_EVENT_SAS_TOPO_RC_MASK; | 5270 | MPI2_EVENT_SAS_TOPO_RC_MASK; |
4796 | if ((event_data->PHY[i].PhyStatus & | 5271 | if ((event_data->PHY[i].PhyStatus & |
@@ -4842,7 +5317,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4842 | /* handle expander removal */ | 5317 | /* handle expander removal */ |
4843 | if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && | 5318 | if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && |
4844 | sas_expander) | 5319 | sas_expander) |
4845 | _scsih_expander_remove(ioc, sas_address); | 5320 | mpt2sas_expander_remove(ioc, sas_address); |
4846 | 5321 | ||
4847 | } | 5322 | } |
4848 | 5323 | ||
@@ -4940,6 +5415,12 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
4940 | event_data); | 5415 | event_data); |
4941 | #endif | 5416 | #endif |
4942 | 5417 | ||
5418 | /* In MPI Revision K (0xC), the internal device reset complete was | ||
5419 | * implemented, so avoid setting tm_busy flag for older firmware. | ||
5420 | */ | ||
5421 | if ((ioc->facts.HeaderVersion >> 8) < 0xC) | ||
5422 | return; | ||
5423 | |||
4943 | if (event_data->ReasonCode != | 5424 | if (event_data->ReasonCode != |
4944 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && | 5425 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && |
4945 | event_data->ReasonCode != | 5426 | event_data->ReasonCode != |
@@ -5034,6 +5515,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5034 | struct fw_event_work *fw_event) | 5515 | struct fw_event_work *fw_event) |
5035 | { | 5516 | { |
5036 | struct scsi_cmnd *scmd; | 5517 | struct scsi_cmnd *scmd; |
5518 | struct scsi_device *sdev; | ||
5037 | u16 smid, handle; | 5519 | u16 smid, handle; |
5038 | u32 lun; | 5520 | u32 lun; |
5039 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 5521 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
@@ -5044,12 +5526,17 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5044 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; | 5526 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; |
5045 | #endif | 5527 | #endif |
5046 | u16 ioc_status; | 5528 | u16 ioc_status; |
5047 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " | 5529 | unsigned long flags; |
5530 | int r; | ||
5531 | |||
5532 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primitive: " | ||
5048 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, | 5533 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, |
5049 | event_data->PortWidth)); | 5534 | event_data->PortWidth)); |
5050 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 5535 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
5051 | __func__)); | 5536 | __func__)); |
5052 | 5537 | ||
5538 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5539 | ioc->broadcast_aen_busy = 0; | ||
5053 | termination_count = 0; | 5540 | termination_count = 0; |
5054 | query_count = 0; | 5541 | query_count = 0; |
5055 | mpi_reply = ioc->tm_cmds.reply; | 5542 | mpi_reply = ioc->tm_cmds.reply; |
@@ -5057,7 +5544,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5057 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 5544 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
5058 | if (!scmd) | 5545 | if (!scmd) |
5059 | continue; | 5546 | continue; |
5060 | sas_device_priv_data = scmd->device->hostdata; | 5547 | sdev = scmd->device; |
5548 | sas_device_priv_data = sdev->hostdata; | ||
5061 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) | 5549 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) |
5062 | continue; | 5550 | continue; |
5063 | /* skip hidden raid components */ | 5551 | /* skip hidden raid components */ |
@@ -5073,6 +5561,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5073 | lun = sas_device_priv_data->lun; | 5561 | lun = sas_device_priv_data->lun; |
5074 | query_count++; | 5562 | query_count++; |
5075 | 5563 | ||
5564 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
5076 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5565 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, |
5077 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); | 5566 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); |
5078 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 5567 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
@@ -5082,14 +5571,20 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
5082 | (mpi_reply->ResponseCode == | 5571 | (mpi_reply->ResponseCode == |
5083 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || | 5572 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || |
5084 | mpi_reply->ResponseCode == | 5573 | mpi_reply->ResponseCode == |
5085 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) | 5574 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) { |
5575 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5086 | continue; | 5576 | continue; |
5087 | 5577 | } | |
5088 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5578 | r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, |
5089 | MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL); | 5579 | sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, |
5580 | scmd); | ||
5581 | if (r == FAILED) | ||
5582 | sdev_printk(KERN_WARNING, sdev, "task abort: FAILED " | ||
5583 | "scmd(%p)\n", scmd); | ||
5090 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); | 5584 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); |
5585 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
5091 | } | 5586 | } |
5092 | ioc->broadcast_aen_busy = 0; | 5587 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
5093 | 5588 | ||
5094 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 5589 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
5095 | "%s - exit, query_count = %d termination_count = %d\n", | 5590 | "%s - exit, query_count = %d termination_count = %d\n", |
@@ -5309,6 +5804,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc, | |||
5309 | &sas_device->volume_wwid); | 5804 | &sas_device->volume_wwid); |
5310 | set_bit(handle, ioc->pd_handles); | 5805 | set_bit(handle, ioc->pd_handles); |
5311 | _scsih_reprobe_target(sas_device->starget, 1); | 5806 | _scsih_reprobe_target(sas_device->starget, 1); |
5807 | |||
5312 | } | 5808 | } |
5313 | 5809 | ||
5314 | /** | 5810 | /** |
@@ -5487,7 +5983,8 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
5487 | Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data; | 5983 | Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data; |
5488 | 5984 | ||
5489 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5985 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
5490 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5986 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
5987 | && !ioc->hide_ir_msg) | ||
5491 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); | 5988 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); |
5492 | 5989 | ||
5493 | #endif | 5990 | #endif |
@@ -5510,16 +6007,20 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
5510 | le16_to_cpu(element->VolDevHandle)); | 6007 | le16_to_cpu(element->VolDevHandle)); |
5511 | break; | 6008 | break; |
5512 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: | 6009 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: |
5513 | _scsih_sas_pd_hide(ioc, element); | 6010 | if (!ioc->is_warpdrive) |
6011 | _scsih_sas_pd_hide(ioc, element); | ||
5514 | break; | 6012 | break; |
5515 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: | 6013 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: |
5516 | _scsih_sas_pd_expose(ioc, element); | 6014 | if (!ioc->is_warpdrive) |
6015 | _scsih_sas_pd_expose(ioc, element); | ||
5517 | break; | 6016 | break; |
5518 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: | 6017 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: |
5519 | _scsih_sas_pd_add(ioc, element); | 6018 | if (!ioc->is_warpdrive) |
6019 | _scsih_sas_pd_add(ioc, element); | ||
5520 | break; | 6020 | break; |
5521 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: | 6021 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: |
5522 | _scsih_sas_pd_delete(ioc, element); | 6022 | if (!ioc->is_warpdrive) |
6023 | _scsih_sas_pd_delete(ioc, element); | ||
5523 | break; | 6024 | break; |
5524 | } | 6025 | } |
5525 | } | 6026 | } |
@@ -5550,9 +6051,10 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, | |||
5550 | 6051 | ||
5551 | handle = le16_to_cpu(event_data->VolDevHandle); | 6052 | handle = le16_to_cpu(event_data->VolDevHandle); |
5552 | state = le32_to_cpu(event_data->NewValue); | 6053 | state = le32_to_cpu(event_data->NewValue); |
5553 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " | 6054 | if (!ioc->hide_ir_msg) |
5554 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, | 6055 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " |
5555 | le32_to_cpu(event_data->PreviousValue), state)); | 6056 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, |
6057 | le32_to_cpu(event_data->PreviousValue), state)); | ||
5556 | 6058 | ||
5557 | switch (state) { | 6059 | switch (state) { |
5558 | case MPI2_RAID_VOL_STATE_MISSING: | 6060 | case MPI2_RAID_VOL_STATE_MISSING: |
@@ -5632,9 +6134,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
5632 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); | 6134 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); |
5633 | state = le32_to_cpu(event_data->NewValue); | 6135 | state = le32_to_cpu(event_data->NewValue); |
5634 | 6136 | ||
5635 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " | 6137 | if (!ioc->hide_ir_msg) |
5636 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, | 6138 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " |
5637 | le32_to_cpu(event_data->PreviousValue), state)); | 6139 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, |
6140 | le32_to_cpu(event_data->PreviousValue), state)); | ||
5638 | 6141 | ||
5639 | switch (state) { | 6142 | switch (state) { |
5640 | case MPI2_RAID_PD_STATE_ONLINE: | 6143 | case MPI2_RAID_PD_STATE_ONLINE: |
@@ -5643,7 +6146,8 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
5643 | case MPI2_RAID_PD_STATE_OPTIMAL: | 6146 | case MPI2_RAID_PD_STATE_OPTIMAL: |
5644 | case MPI2_RAID_PD_STATE_HOT_SPARE: | 6147 | case MPI2_RAID_PD_STATE_HOT_SPARE: |
5645 | 6148 | ||
5646 | set_bit(handle, ioc->pd_handles); | 6149 | if (!ioc->is_warpdrive) |
6150 | set_bit(handle, ioc->pd_handles); | ||
5647 | 6151 | ||
5648 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6152 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5649 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6153 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
@@ -5747,7 +6251,8 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, | |||
5747 | u16 handle; | 6251 | u16 handle; |
5748 | 6252 | ||
5749 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 6253 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
5750 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 6254 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
6255 | && !ioc->hide_ir_msg) | ||
5751 | _scsih_sas_ir_operation_status_event_debug(ioc, | 6256 | _scsih_sas_ir_operation_status_event_debug(ioc, |
5752 | event_data); | 6257 | event_data); |
5753 | #endif | 6258 | #endif |
@@ -5771,90 +6276,6 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, | |||
5771 | } | 6276 | } |
5772 | 6277 | ||
5773 | /** | 6278 | /** |
5774 | * _scsih_task_set_full - handle task set full | ||
5775 | * @ioc: per adapter object | ||
5776 | * @fw_event: The fw_event_work object | ||
5777 | * Context: user. | ||
5778 | * | ||
5779 | * Throttle back qdepth. | ||
5780 | */ | ||
5781 | static void | ||
5782 | _scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work | ||
5783 | *fw_event) | ||
5784 | { | ||
5785 | unsigned long flags; | ||
5786 | struct _sas_device *sas_device; | ||
5787 | static struct _raid_device *raid_device; | ||
5788 | struct scsi_device *sdev; | ||
5789 | int depth; | ||
5790 | u16 current_depth; | ||
5791 | u16 handle; | ||
5792 | int id, channel; | ||
5793 | u64 sas_address; | ||
5794 | Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data; | ||
5795 | |||
5796 | current_depth = le16_to_cpu(event_data->CurrentDepth); | ||
5797 | handle = le16_to_cpu(event_data->DevHandle); | ||
5798 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
5799 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
5800 | if (!sas_device) { | ||
5801 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5802 | return; | ||
5803 | } | ||
5804 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5805 | id = sas_device->id; | ||
5806 | channel = sas_device->channel; | ||
5807 | sas_address = sas_device->sas_address; | ||
5808 | |||
5809 | /* if hidden raid component, then change to volume characteristics */ | ||
5810 | if (test_bit(handle, ioc->pd_handles) && sas_device->volume_handle) { | ||
5811 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
5812 | raid_device = _scsih_raid_device_find_by_handle( | ||
5813 | ioc, sas_device->volume_handle); | ||
5814 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
5815 | if (raid_device) { | ||
5816 | id = raid_device->id; | ||
5817 | channel = raid_device->channel; | ||
5818 | handle = raid_device->handle; | ||
5819 | sas_address = raid_device->wwid; | ||
5820 | } | ||
5821 | } | ||
5822 | |||
5823 | if (ioc->logging_level & MPT_DEBUG_TASK_SET_FULL) | ||
5824 | starget_printk(KERN_INFO, sas_device->starget, "task set " | ||
5825 | "full: handle(0x%04x), sas_addr(0x%016llx), depth(%d)\n", | ||
5826 | handle, (unsigned long long)sas_address, current_depth); | ||
5827 | |||
5828 | shost_for_each_device(sdev, ioc->shost) { | ||
5829 | if (sdev->id == id && sdev->channel == channel) { | ||
5830 | if (current_depth > sdev->queue_depth) { | ||
5831 | if (ioc->logging_level & | ||
5832 | MPT_DEBUG_TASK_SET_FULL) | ||
5833 | sdev_printk(KERN_INFO, sdev, "strange " | ||
5834 | "observation, the queue depth is" | ||
5835 | " (%d) meanwhile fw queue depth " | ||
5836 | "is (%d)\n", sdev->queue_depth, | ||
5837 | current_depth); | ||
5838 | continue; | ||
5839 | } | ||
5840 | depth = scsi_track_queue_full(sdev, | ||
5841 | current_depth - 1); | ||
5842 | if (depth > 0) | ||
5843 | sdev_printk(KERN_INFO, sdev, "Queue depth " | ||
5844 | "reduced to (%d)\n", depth); | ||
5845 | else if (depth < 0) | ||
5846 | sdev_printk(KERN_INFO, sdev, "Tagged Command " | ||
5847 | "Queueing is being disabled\n"); | ||
5848 | else if (depth == 0) | ||
5849 | if (ioc->logging_level & | ||
5850 | MPT_DEBUG_TASK_SET_FULL) | ||
5851 | sdev_printk(KERN_INFO, sdev, | ||
5852 | "Queue depth not changed yet\n"); | ||
5853 | } | ||
5854 | } | ||
5855 | } | ||
5856 | |||
5857 | /** | ||
5858 | * _scsih_prep_device_scan - initialize parameters prior to device scan | 6279 | * _scsih_prep_device_scan - initialize parameters prior to device scan |
5859 | * @ioc: per adapter object | 6280 | * @ioc: per adapter object |
5860 | * | 6281 | * |
@@ -5890,7 +6311,7 @@ static void | |||
5890 | _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 6311 | _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, |
5891 | u16 slot, u16 handle) | 6312 | u16 slot, u16 handle) |
5892 | { | 6313 | { |
5893 | struct MPT2SAS_TARGET *sas_target_priv_data; | 6314 | struct MPT2SAS_TARGET *sas_target_priv_data = NULL; |
5894 | struct scsi_target *starget; | 6315 | struct scsi_target *starget; |
5895 | struct _sas_device *sas_device; | 6316 | struct _sas_device *sas_device; |
5896 | unsigned long flags; | 6317 | unsigned long flags; |
@@ -5898,7 +6319,7 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5898 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6319 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5899 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) { | 6320 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) { |
5900 | if (sas_device->sas_address == sas_address && | 6321 | if (sas_device->sas_address == sas_address && |
5901 | sas_device->slot == slot && sas_device->starget) { | 6322 | sas_device->slot == slot) { |
5902 | sas_device->responding = 1; | 6323 | sas_device->responding = 1; |
5903 | starget = sas_device->starget; | 6324 | starget = sas_device->starget; |
5904 | if (starget && starget->hostdata) { | 6325 | if (starget && starget->hostdata) { |
@@ -5907,13 +6328,15 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5907 | sas_target_priv_data->deleted = 0; | 6328 | sas_target_priv_data->deleted = 0; |
5908 | } else | 6329 | } else |
5909 | sas_target_priv_data = NULL; | 6330 | sas_target_priv_data = NULL; |
5910 | starget_printk(KERN_INFO, sas_device->starget, | 6331 | if (starget) |
5911 | "handle(0x%04x), sas_addr(0x%016llx), enclosure " | 6332 | starget_printk(KERN_INFO, starget, |
5912 | "logical id(0x%016llx), slot(%d)\n", handle, | 6333 | "handle(0x%04x), sas_addr(0x%016llx), " |
5913 | (unsigned long long)sas_device->sas_address, | 6334 | "enclosure logical id(0x%016llx), " |
5914 | (unsigned long long) | 6335 | "slot(%d)\n", handle, |
5915 | sas_device->enclosure_logical_id, | 6336 | (unsigned long long)sas_device->sas_address, |
5916 | sas_device->slot); | 6337 | (unsigned long long) |
6338 | sas_device->enclosure_logical_id, | ||
6339 | sas_device->slot); | ||
5917 | if (sas_device->handle == handle) | 6340 | if (sas_device->handle == handle) |
5918 | goto out; | 6341 | goto out; |
5919 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", | 6342 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", |
@@ -6005,6 +6428,12 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid, | |||
6005 | starget_printk(KERN_INFO, raid_device->starget, | 6428 | starget_printk(KERN_INFO, raid_device->starget, |
6006 | "handle(0x%04x), wwid(0x%016llx)\n", handle, | 6429 | "handle(0x%04x), wwid(0x%016llx)\n", handle, |
6007 | (unsigned long long)raid_device->wwid); | 6430 | (unsigned long long)raid_device->wwid); |
6431 | /* | ||
6432 | * WARPDRIVE: The handles of the PDs might have changed | ||
6433 | * across the host reset so re-initialize the | ||
6434 | * required data for Direct IO | ||
6435 | */ | ||
6436 | _scsih_init_warpdrive_properties(ioc, raid_device); | ||
6008 | if (raid_device->handle == handle) | 6437 | if (raid_device->handle == handle) |
6009 | goto out; | 6438 | goto out; |
6010 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", | 6439 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", |
@@ -6066,18 +6495,20 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc) | |||
6066 | } | 6495 | } |
6067 | 6496 | ||
6068 | /* refresh the pd_handles */ | 6497 | /* refresh the pd_handles */ |
6069 | phys_disk_num = 0xFF; | 6498 | if (!ioc->is_warpdrive) { |
6070 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); | 6499 | phys_disk_num = 0xFF; |
6071 | while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | 6500 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); |
6072 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, | 6501 | while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, |
6073 | phys_disk_num))) { | 6502 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, |
6074 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | 6503 | phys_disk_num))) { |
6075 | MPI2_IOCSTATUS_MASK; | 6504 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & |
6076 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | 6505 | MPI2_IOCSTATUS_MASK; |
6077 | break; | 6506 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) |
6078 | phys_disk_num = pd_pg0.PhysDiskNum; | 6507 | break; |
6079 | handle = le16_to_cpu(pd_pg0.DevHandle); | 6508 | phys_disk_num = pd_pg0.PhysDiskNum; |
6080 | set_bit(handle, ioc->pd_handles); | 6509 | handle = le16_to_cpu(pd_pg0.DevHandle); |
6510 | set_bit(handle, ioc->pd_handles); | ||
6511 | } | ||
6081 | } | 6512 | } |
6082 | } | 6513 | } |
6083 | 6514 | ||
@@ -6217,12 +6648,56 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc) | |||
6217 | sas_expander->responding = 0; | 6648 | sas_expander->responding = 0; |
6218 | continue; | 6649 | continue; |
6219 | } | 6650 | } |
6220 | _scsih_expander_remove(ioc, sas_expander->sas_address); | 6651 | mpt2sas_expander_remove(ioc, sas_expander->sas_address); |
6221 | goto retry_expander_search; | 6652 | goto retry_expander_search; |
6222 | } | 6653 | } |
6223 | } | 6654 | } |
6224 | 6655 | ||
6225 | /** | 6656 | /** |
6657 | * _scsih_hide_unhide_sas_devices - add/remove device to/from OS | ||
6658 | * @ioc: per adapter object | ||
6659 | * | ||
6660 | * Return nothing. | ||
6661 | */ | ||
6662 | static void | ||
6663 | _scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc) | ||
6664 | { | ||
6665 | struct _sas_device *sas_device, *sas_device_next; | ||
6666 | |||
6667 | if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag != | ||
6668 | MFG_PAGE10_HIDE_IF_VOL_PRESENT) | ||
6669 | return; | ||
6670 | |||
6671 | if (ioc->hide_drives) { | ||
6672 | if (_scsih_get_num_volumes(ioc)) | ||
6673 | return; | ||
6674 | ioc->hide_drives = 0; | ||
6675 | list_for_each_entry_safe(sas_device, sas_device_next, | ||
6676 | &ioc->sas_device_list, list) { | ||
6677 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | ||
6678 | sas_device->sas_address_parent)) { | ||
6679 | _scsih_sas_device_remove(ioc, sas_device); | ||
6680 | } else if (!sas_device->starget) { | ||
6681 | mpt2sas_transport_port_remove(ioc, | ||
6682 | sas_device->sas_address, | ||
6683 | sas_device->sas_address_parent); | ||
6684 | _scsih_sas_device_remove(ioc, sas_device); | ||
6685 | } | ||
6686 | } | ||
6687 | } else { | ||
6688 | if (!_scsih_get_num_volumes(ioc)) | ||
6689 | return; | ||
6690 | ioc->hide_drives = 1; | ||
6691 | list_for_each_entry_safe(sas_device, sas_device_next, | ||
6692 | &ioc->sas_device_list, list) { | ||
6693 | mpt2sas_transport_port_remove(ioc, | ||
6694 | sas_device->sas_address, | ||
6695 | sas_device->sas_address_parent); | ||
6696 | } | ||
6697 | } | ||
6698 | } | ||
6699 | |||
6700 | /** | ||
6226 | * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) | 6701 | * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) |
6227 | * @ioc: per adapter object | 6702 | * @ioc: per adapter object |
6228 | * @reset_phase: phase | 6703 | * @reset_phase: phase |
@@ -6306,10 +6781,14 @@ _firmware_event_work(struct work_struct *work) | |||
6306 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, | 6781 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, |
6307 | flags); | 6782 | flags); |
6308 | _scsih_remove_unresponding_sas_devices(ioc); | 6783 | _scsih_remove_unresponding_sas_devices(ioc); |
6784 | _scsih_hide_unhide_sas_devices(ioc); | ||
6309 | return; | 6785 | return; |
6310 | } | 6786 | } |
6311 | 6787 | ||
6312 | switch (fw_event->event) { | 6788 | switch (fw_event->event) { |
6789 | case MPT2SAS_TURN_ON_FAULT_LED: | ||
6790 | _scsih_turn_on_fault_led(ioc, fw_event->device_handle); | ||
6791 | break; | ||
6313 | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: | 6792 | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: |
6314 | _scsih_sas_topology_change_event(ioc, fw_event); | 6793 | _scsih_sas_topology_change_event(ioc, fw_event); |
6315 | break; | 6794 | break; |
@@ -6341,9 +6820,6 @@ _firmware_event_work(struct work_struct *work) | |||
6341 | case MPI2_EVENT_IR_OPERATION_STATUS: | 6820 | case MPI2_EVENT_IR_OPERATION_STATUS: |
6342 | _scsih_sas_ir_operation_status_event(ioc, fw_event); | 6821 | _scsih_sas_ir_operation_status_event(ioc, fw_event); |
6343 | break; | 6822 | break; |
6344 | case MPI2_EVENT_TASK_SET_FULL: | ||
6345 | _scsih_task_set_full(ioc, fw_event); | ||
6346 | break; | ||
6347 | } | 6823 | } |
6348 | _scsih_fw_event_free(ioc, fw_event); | 6824 | _scsih_fw_event_free(ioc, fw_event); |
6349 | } | 6825 | } |
@@ -6408,12 +6884,58 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
6408 | (Mpi2EventDataIrVolume_t *) | 6884 | (Mpi2EventDataIrVolume_t *) |
6409 | mpi_reply->EventData); | 6885 | mpi_reply->EventData); |
6410 | break; | 6886 | break; |
6887 | case MPI2_EVENT_LOG_ENTRY_ADDED: | ||
6888 | { | ||
6889 | Mpi2EventDataLogEntryAdded_t *log_entry; | ||
6890 | u32 *log_code; | ||
6891 | |||
6892 | if (!ioc->is_warpdrive) | ||
6893 | break; | ||
6894 | |||
6895 | log_entry = (Mpi2EventDataLogEntryAdded_t *) | ||
6896 | mpi_reply->EventData; | ||
6897 | log_code = (u32 *)log_entry->LogData; | ||
6898 | |||
6899 | if (le16_to_cpu(log_entry->LogEntryQualifier) | ||
6900 | != MPT2_WARPDRIVE_LOGENTRY) | ||
6901 | break; | ||
6902 | |||
6903 | switch (le32_to_cpu(*log_code)) { | ||
6904 | case MPT2_WARPDRIVE_LC_SSDT: | ||
6905 | printk(MPT2SAS_WARN_FMT "WarpDrive Warning: " | ||
6906 | "IO Throttling has occurred in the WarpDrive " | ||
6907 | "subsystem. Check WarpDrive documentation for " | ||
6908 | "additional details.\n", ioc->name); | ||
6909 | break; | ||
6910 | case MPT2_WARPDRIVE_LC_SSDLW: | ||
6911 | printk(MPT2SAS_WARN_FMT "WarpDrive Warning: " | ||
6912 | "Program/Erase Cycles for the WarpDrive subsystem " | ||
6913 | "in degraded range. Check WarpDrive documentation " | ||
6914 | "for additional details.\n", ioc->name); | ||
6915 | break; | ||
6916 | case MPT2_WARPDRIVE_LC_SSDLF: | ||
6917 | printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: " | ||
6918 | "There are no Program/Erase Cycles for the " | ||
6919 | "WarpDrive subsystem. The storage device will be " | ||
6920 | "in read-only mode. Check WarpDrive documentation " | ||
6921 | "for additional details.\n", ioc->name); | ||
6922 | break; | ||
6923 | case MPT2_WARPDRIVE_LC_BRMF: | ||
6924 | printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: " | ||
6925 | "The Backup Rail Monitor has failed on the " | ||
6926 | "WarpDrive subsystem. Check WarpDrive " | ||
6927 | "documentation for additional details.\n", | ||
6928 | ioc->name); | ||
6929 | break; | ||
6930 | } | ||
6931 | |||
6932 | break; | ||
6933 | } | ||
6411 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | 6934 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: |
6412 | case MPI2_EVENT_IR_OPERATION_STATUS: | 6935 | case MPI2_EVENT_IR_OPERATION_STATUS: |
6413 | case MPI2_EVENT_SAS_DISCOVERY: | 6936 | case MPI2_EVENT_SAS_DISCOVERY: |
6414 | case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: | 6937 | case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: |
6415 | case MPI2_EVENT_IR_PHYSICAL_DISK: | 6938 | case MPI2_EVENT_IR_PHYSICAL_DISK: |
6416 | case MPI2_EVENT_TASK_SET_FULL: | ||
6417 | break; | 6939 | break; |
6418 | 6940 | ||
6419 | default: /* ignore the rest */ | 6941 | default: /* ignore the rest */ |
@@ -6488,56 +7010,23 @@ static void | |||
6488 | _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | 7010 | _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, |
6489 | struct _sas_node *sas_expander) | 7011 | struct _sas_node *sas_expander) |
6490 | { | 7012 | { |
6491 | struct _sas_port *mpt2sas_port; | 7013 | struct _sas_port *mpt2sas_port, *next; |
6492 | struct _sas_device *sas_device; | ||
6493 | struct _sas_node *expander_sibling; | ||
6494 | unsigned long flags; | ||
6495 | |||
6496 | if (!sas_expander) | ||
6497 | return; | ||
6498 | 7014 | ||
6499 | /* remove sibling ports attached to this expander */ | 7015 | /* remove sibling ports attached to this expander */ |
6500 | retry_device_search: | 7016 | list_for_each_entry_safe(mpt2sas_port, next, |
6501 | list_for_each_entry(mpt2sas_port, | ||
6502 | &sas_expander->sas_port_list, port_list) { | ||
6503 | if (mpt2sas_port->remote_identify.device_type == | ||
6504 | SAS_END_DEVICE) { | ||
6505 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
6506 | sas_device = | ||
6507 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
6508 | mpt2sas_port->remote_identify.sas_address); | ||
6509 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
6510 | if (!sas_device) | ||
6511 | continue; | ||
6512 | _scsih_remove_device(ioc, sas_device); | ||
6513 | if (ioc->shost_recovery) | ||
6514 | return; | ||
6515 | goto retry_device_search; | ||
6516 | } | ||
6517 | } | ||
6518 | |||
6519 | retry_expander_search: | ||
6520 | list_for_each_entry(mpt2sas_port, | ||
6521 | &sas_expander->sas_port_list, port_list) { | 7017 | &sas_expander->sas_port_list, port_list) { |
6522 | 7018 | if (ioc->shost_recovery) | |
7019 | return; | ||
6523 | if (mpt2sas_port->remote_identify.device_type == | 7020 | if (mpt2sas_port->remote_identify.device_type == |
6524 | MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || | 7021 | SAS_END_DEVICE) |
7022 | mpt2sas_device_remove(ioc, | ||
7023 | mpt2sas_port->remote_identify.sas_address); | ||
7024 | else if (mpt2sas_port->remote_identify.device_type == | ||
7025 | SAS_EDGE_EXPANDER_DEVICE || | ||
6525 | mpt2sas_port->remote_identify.device_type == | 7026 | mpt2sas_port->remote_identify.device_type == |
6526 | MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) { | 7027 | SAS_FANOUT_EXPANDER_DEVICE) |
6527 | 7028 | mpt2sas_expander_remove(ioc, | |
6528 | spin_lock_irqsave(&ioc->sas_node_lock, flags); | 7029 | mpt2sas_port->remote_identify.sas_address); |
6529 | expander_sibling = | ||
6530 | mpt2sas_scsih_expander_find_by_sas_address( | ||
6531 | ioc, mpt2sas_port->remote_identify.sas_address); | ||
6532 | spin_unlock_irqrestore(&ioc->sas_node_lock, flags); | ||
6533 | if (!expander_sibling) | ||
6534 | continue; | ||
6535 | _scsih_expander_remove(ioc, | ||
6536 | expander_sibling->sas_address); | ||
6537 | if (ioc->shost_recovery) | ||
6538 | return; | ||
6539 | goto retry_expander_search; | ||
6540 | } | ||
6541 | } | 7030 | } |
6542 | 7031 | ||
6543 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, | 7032 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
@@ -6548,7 +7037,6 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, | |||
6548 | sas_expander->handle, (unsigned long long) | 7037 | sas_expander->handle, (unsigned long long) |
6549 | sas_expander->sas_address); | 7038 | sas_expander->sas_address); |
6550 | 7039 | ||
6551 | list_del(&sas_expander->list); | ||
6552 | kfree(sas_expander->phy); | 7040 | kfree(sas_expander->phy); |
6553 | kfree(sas_expander); | 7041 | kfree(sas_expander); |
6554 | } | 7042 | } |
@@ -6601,7 +7089,8 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc) | |||
6601 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; | 7089 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; |
6602 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; | 7090 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; |
6603 | 7091 | ||
6604 | printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name); | 7092 | if (!ioc->hide_ir_msg) |
7093 | printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name); | ||
6605 | init_completion(&ioc->scsih_cmds.done); | 7094 | init_completion(&ioc->scsih_cmds.done); |
6606 | mpt2sas_base_put_smid_default(ioc, smid); | 7095 | mpt2sas_base_put_smid_default(ioc, smid); |
6607 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | 7096 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); |
@@ -6615,10 +7104,11 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc) | |||
6615 | if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) { | 7104 | if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) { |
6616 | mpi_reply = ioc->scsih_cmds.reply; | 7105 | mpi_reply = ioc->scsih_cmds.reply; |
6617 | 7106 | ||
6618 | printk(MPT2SAS_INFO_FMT "IR shutdown (complete): " | 7107 | if (!ioc->hide_ir_msg) |
6619 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | 7108 | printk(MPT2SAS_INFO_FMT "IR shutdown (complete): " |
6620 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), | 7109 | "ioc_status(0x%04x), loginfo(0x%08x)\n", |
6621 | le32_to_cpu(mpi_reply->IOCLogInfo)); | 7110 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), |
7111 | le32_to_cpu(mpi_reply->IOCLogInfo)); | ||
6622 | } | 7112 | } |
6623 | 7113 | ||
6624 | out: | 7114 | out: |
@@ -6666,9 +7156,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
6666 | { | 7156 | { |
6667 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 7157 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
6668 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | 7158 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
6669 | struct _sas_port *mpt2sas_port; | 7159 | struct _sas_port *mpt2sas_port, *next_port; |
6670 | struct _sas_device *sas_device; | ||
6671 | struct _sas_node *expander_sibling; | ||
6672 | struct _raid_device *raid_device, *next; | 7160 | struct _raid_device *raid_device, *next; |
6673 | struct MPT2SAS_TARGET *sas_target_priv_data; | 7161 | struct MPT2SAS_TARGET *sas_target_priv_data; |
6674 | struct workqueue_struct *wq; | 7162 | struct workqueue_struct *wq; |
@@ -6685,6 +7173,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
6685 | destroy_workqueue(wq); | 7173 | destroy_workqueue(wq); |
6686 | 7174 | ||
6687 | /* release all the volumes */ | 7175 | /* release all the volumes */ |
7176 | _scsih_ir_shutdown(ioc); | ||
6688 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, | 7177 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, |
6689 | list) { | 7178 | list) { |
6690 | if (raid_device->starget) { | 7179 | if (raid_device->starget) { |
@@ -6700,28 +7189,18 @@ _scsih_remove(struct pci_dev *pdev) | |||
6700 | } | 7189 | } |
6701 | 7190 | ||
6702 | /* free ports attached to the sas_host */ | 7191 | /* free ports attached to the sas_host */ |
6703 | retry_again: | 7192 | list_for_each_entry_safe(mpt2sas_port, next_port, |
6704 | list_for_each_entry(mpt2sas_port, | ||
6705 | &ioc->sas_hba.sas_port_list, port_list) { | 7193 | &ioc->sas_hba.sas_port_list, port_list) { |
6706 | if (mpt2sas_port->remote_identify.device_type == | 7194 | if (mpt2sas_port->remote_identify.device_type == |
6707 | SAS_END_DEVICE) { | 7195 | SAS_END_DEVICE) |
6708 | sas_device = | 7196 | mpt2sas_device_remove(ioc, |
6709 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 7197 | mpt2sas_port->remote_identify.sas_address); |
6710 | mpt2sas_port->remote_identify.sas_address); | 7198 | else if (mpt2sas_port->remote_identify.device_type == |
6711 | if (sas_device) { | 7199 | SAS_EDGE_EXPANDER_DEVICE || |
6712 | _scsih_remove_device(ioc, sas_device); | 7200 | mpt2sas_port->remote_identify.device_type == |
6713 | goto retry_again; | 7201 | SAS_FANOUT_EXPANDER_DEVICE) |
6714 | } | 7202 | mpt2sas_expander_remove(ioc, |
6715 | } else { | ||
6716 | expander_sibling = | ||
6717 | mpt2sas_scsih_expander_find_by_sas_address(ioc, | ||
6718 | mpt2sas_port->remote_identify.sas_address); | 7203 | mpt2sas_port->remote_identify.sas_address); |
6719 | if (expander_sibling) { | ||
6720 | _scsih_expander_remove(ioc, | ||
6721 | expander_sibling->sas_address); | ||
6722 | goto retry_again; | ||
6723 | } | ||
6724 | } | ||
6725 | } | 7204 | } |
6726 | 7205 | ||
6727 | /* free phys attached to the sas_host */ | 7206 | /* free phys attached to the sas_host */ |
@@ -6788,6 +7267,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
6788 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 7267 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6789 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 7268 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
6790 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7269 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
7270 | |||
7271 | if (ioc->hide_drives) | ||
7272 | return; | ||
6791 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 7273 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
6792 | sas_device->sas_address_parent)) { | 7274 | sas_device->sas_address_parent)) { |
6793 | _scsih_sas_device_remove(ioc, sas_device); | 7275 | _scsih_sas_device_remove(ioc, sas_device); |
@@ -6841,6 +7323,9 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
6841 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 7323 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
6842 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7324 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
6843 | 7325 | ||
7326 | if (ioc->hide_drives) | ||
7327 | continue; | ||
7328 | |||
6844 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 7329 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
6845 | sas_device->sas_address_parent)) { | 7330 | sas_device->sas_address_parent)) { |
6846 | _scsih_sas_device_remove(ioc, sas_device); | 7331 | _scsih_sas_device_remove(ioc, sas_device); |
@@ -6911,6 +7396,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
6911 | ioc->id = mpt_ids++; | 7396 | ioc->id = mpt_ids++; |
6912 | sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); | 7397 | sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); |
6913 | ioc->pdev = pdev; | 7398 | ioc->pdev = pdev; |
7399 | if (id->device == MPI2_MFGPAGE_DEVID_SSS6200) { | ||
7400 | ioc->is_warpdrive = 1; | ||
7401 | ioc->hide_ir_msg = 1; | ||
7402 | } else | ||
7403 | ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; | ||
6914 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; | 7404 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; |
6915 | ioc->tm_cb_idx = tm_cb_idx; | 7405 | ioc->tm_cb_idx = tm_cb_idx; |
6916 | ioc->ctl_cb_idx = ctl_cb_idx; | 7406 | ioc->ctl_cb_idx = ctl_cb_idx; |
@@ -6976,6 +7466,20 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
6976 | } | 7466 | } |
6977 | 7467 | ||
6978 | ioc->wait_for_port_enable_to_complete = 0; | 7468 | ioc->wait_for_port_enable_to_complete = 0; |
7469 | if (ioc->is_warpdrive) { | ||
7470 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) | ||
7471 | ioc->hide_drives = 0; | ||
7472 | else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS) | ||
7473 | ioc->hide_drives = 1; | ||
7474 | else { | ||
7475 | if (_scsih_get_num_volumes(ioc)) | ||
7476 | ioc->hide_drives = 1; | ||
7477 | else | ||
7478 | ioc->hide_drives = 0; | ||
7479 | } | ||
7480 | } else | ||
7481 | ioc->hide_drives = 0; | ||
7482 | |||
6979 | _scsih_probe_devices(ioc); | 7483 | _scsih_probe_devices(ioc); |
6980 | return 0; | 7484 | return 0; |
6981 | 7485 | ||
@@ -7004,7 +7508,6 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) | |||
7004 | u32 device_state; | 7508 | u32 device_state; |
7005 | 7509 | ||
7006 | mpt2sas_base_stop_watchdog(ioc); | 7510 | mpt2sas_base_stop_watchdog(ioc); |
7007 | flush_scheduled_work(); | ||
7008 | scsi_block_requests(shost); | 7511 | scsi_block_requests(shost); |
7009 | device_state = pci_choose_state(pdev, state); | 7512 | device_state = pci_choose_state(pdev, state); |
7010 | printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering " | 7513 | printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering " |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index b55c6dc07470..cb1cdecbe0f8 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c | |||
@@ -465,62 +465,149 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, | |||
465 | return rc; | 465 | return rc; |
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 | */ | ||
475 | static 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 | } | ||
468 | 495 | ||
469 | /** | 496 | /** |
470 | * _transport_delete_duplicate_port - (see below description) | 497 | * _transport_delete_phy - helper function to removing single phy from port |
471 | * @ioc: per adapter object | 498 | * @ioc: per adapter object |
472 | * @sas_node: sas node object (either expander or sas host) | 499 | * @mpt2sas_port: mpt2sas per port object |
473 | * @sas_address: sas address of device being added | 500 | * @mpt2sas_phy: mpt2sas per phy object |
474 | * @phy_num: phy number | ||
475 | * | 501 | * |
476 | * This function is called when attempting to add a new port that is claiming | 502 | * Returns nothing. |
477 | * the same phy resources already in use by another port. If we don't release | 503 | */ |
478 | * the claimed phy resources, the sas transport layer will hang from the BUG | 504 | static void |
479 | * in sas_port_add_phy. | 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 | ||
480 | * | 525 | * |
481 | * The reason we would hit this issue is becuase someone is changing the | 526 | * Returns nothing. |
482 | * sas address of a device on the fly, meanwhile controller firmware sends | ||
483 | * EVENTs out of order when removing the previous instance of the device. | ||
484 | */ | 527 | */ |
485 | static void | 528 | static void |
486 | _transport_delete_duplicate_port(struct MPT2SAS_ADAPTER *ioc, | 529 | _transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port, |
487 | struct _sas_node *sas_node, u64 sas_address, int phy_num) | 530 | struct _sas_phy *mpt2sas_phy) |
488 | { | 531 | { |
489 | struct _sas_port *mpt2sas_port, *mpt2sas_port_duplicate; | 532 | u64 sas_address = mpt2sas_port->remote_identify.sas_address; |
490 | struct _sas_phy *mpt2sas_phy; | ||
491 | 533 | ||
492 | printk(MPT2SAS_ERR_FMT "new device located at sas_addr(0x%016llx), " | 534 | dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, |
493 | "phy_id(%d)\n", ioc->name, (unsigned long long)sas_address, | 535 | "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long) |
494 | phy_num); | 536 | sas_address, mpt2sas_phy->phy_id); |
495 | 537 | ||
496 | mpt2sas_port_duplicate = NULL; | 538 | list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list); |
497 | list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, port_list) { | 539 | mpt2sas_port->num_phys++; |
498 | dev_printk(KERN_ERR, &mpt2sas_port->port->dev, | 540 | sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy); |
499 | "existing device at sas_addr(0x%016llx), num_phys(%d)\n", | 541 | mpt2sas_phy->phy_belongs_to_port = 1; |
500 | (unsigned long long) | 542 | } |
501 | mpt2sas_port->remote_identify.sas_address, | 543 | |
502 | mpt2sas_port->num_phys); | 544 | /** |
503 | list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list, | 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 | */ | ||
553 | static void | ||
554 | _transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc, | ||
555 | struct _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, | ||
504 | port_siblings) { | 569 | port_siblings) { |
505 | dev_printk(KERN_ERR, &mpt2sas_phy->phy->dev, | 570 | if (phy_srch == mpt2sas_phy) |
506 | "phy_number(%d)\n", mpt2sas_phy->phy_id); | 571 | return; |
507 | if (mpt2sas_phy->phy_id == phy_num) | ||
508 | mpt2sas_port_duplicate = mpt2sas_port; | ||
509 | } | 572 | } |
573 | _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy); | ||
574 | return; | ||
510 | } | 575 | } |
511 | 576 | ||
512 | if (!mpt2sas_port_duplicate) | 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 | */ | ||
587 | static 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) | ||
513 | return; | 595 | return; |
514 | 596 | ||
515 | dev_printk(KERN_ERR, &mpt2sas_port_duplicate->port->dev, | 597 | list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, |
516 | "deleting duplicate device at sas_addr(0x%016llx), phy(%d)!!!!\n", | 598 | port_list) { |
517 | (unsigned long long) | 599 | list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, |
518 | mpt2sas_port_duplicate->remote_identify.sas_address, phy_num); | 600 | port_siblings) { |
519 | ioc->logging_level |= MPT_DEBUG_TRANSPORT; | 601 | if (phy_srch != mpt2sas_phy) |
520 | mpt2sas_transport_port_remove(ioc, | 602 | continue; |
521 | mpt2sas_port_duplicate->remote_identify.sas_address, | 603 | if (mpt2sas_port->num_phys == 1) |
522 | sas_node->sas_address); | 604 | _transport_delete_port(ioc, mpt2sas_port); |
523 | ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; | 605 | else |
606 | _transport_delete_phy(ioc, mpt2sas_port, | ||
607 | mpt2sas_phy); | ||
608 | return; | ||
609 | } | ||
610 | } | ||
524 | } | 611 | } |
525 | 612 | ||
526 | /** | 613 | /** |
@@ -537,11 +624,13 @@ _transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node, | |||
537 | { | 624 | { |
538 | int i; | 625 | int i; |
539 | 626 | ||
540 | for (i = 0; i < sas_node->num_phys; i++) | 627 | for (i = 0; i < sas_node->num_phys; i++) { |
541 | if (sas_node->phy[i].remote_identify.sas_address == sas_address) | 628 | if (sas_node->phy[i].remote_identify.sas_address != sas_address) |
542 | if (sas_node->phy[i].phy_belongs_to_port) | 629 | continue; |
543 | _transport_delete_duplicate_port(ioc, sas_node, | 630 | if (sas_node->phy[i].phy_belongs_to_port == 1) |
544 | sas_address, i); | 631 | _transport_del_phy_from_an_existing_port(ioc, sas_node, |
632 | &sas_node->phy[i]); | ||
633 | } | ||
545 | } | 634 | } |
546 | 635 | ||
547 | /** | 636 | /** |
@@ -905,10 +994,12 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, | |||
905 | 994 | ||
906 | mpt2sas_phy = &sas_node->phy[phy_number]; | 995 | mpt2sas_phy = &sas_node->phy[phy_number]; |
907 | mpt2sas_phy->attached_handle = handle; | 996 | mpt2sas_phy->attached_handle = handle; |
908 | if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) | 997 | if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { |
909 | _transport_set_identify(ioc, handle, | 998 | _transport_set_identify(ioc, handle, |
910 | &mpt2sas_phy->remote_identify); | 999 | &mpt2sas_phy->remote_identify); |
911 | else | 1000 | _transport_add_phy_to_an_existing_port(ioc, sas_node, |
1001 | mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address); | ||
1002 | } else | ||
912 | memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct | 1003 | memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct |
913 | sas_identify)); | 1004 | sas_identify)); |
914 | 1005 | ||