diff options
author | Sreekanth Reddy <sreekanth.reddy@avagotech.com> | 2015-11-11 07:00:28 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2015-11-11 18:56:10 -0500 |
commit | 7786ab6aff9cea97eb0a8d67705c68e97a664bf3 (patch) | |
tree | 32a590d09b52e29d5f4a75162abb4aa12c4caff2 | |
parent | 16e179bda58f0931854a669c9a70fd9139015899 (diff) |
mpt3sas: Ported WarpDrive product SSS6200 support
Ported the following list of WarpDrive-specific patches:
1. commit 0bdccdb0a090ad8dc5f851cad5e843244c410ee8 ("mpt2sas: WarpDrive
New product SSS6200 support added")
2. commit 82a452581230b3ffc9d6475dffdb2568497b5fec ("mpt2sas: WarpDrive
Infinite command retries due to wrong scsi command entry in MPI
message")
3. commit ba96bd0b1d4a4e11f23671e1f375a5c8f46b0fe7 ("mpt2sas: Support
for greater than 2TB capacity WarpDrive")
4. commit 4da7af9494b2f98a1503a2634059300c3e4615e6 ("mpt2sas: Do not
retry a timed out direct IO for Warpdrive")
5. commit daeaa9df92bd742f4e6d4d6039d689277a8e31bd ("mpt2sas: Avoid type
casting for direct I/O commands").
Also set the mpt2_ioctl_iocinfo adapter_type to:
1. MPT3_IOCTL_INTERFACE_SAS3 for Gen3 HBAs
2. MPT2_IOCTL_INTERFACE_SAS2_SSS6200 for Warp Drive
3. MPT2_IOCTL_INTERFACE_SAS2 for other Gen2 HBAs
Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_warpdrive.c | 338 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.c | 68 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.h | 39 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_ctl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_scsih.c | 260 |
6 files changed, 665 insertions, 46 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_warpdrive.c b/drivers/scsi/mpt2sas/mpt2sas_warpdrive.c new file mode 100644 index 000000000000..c4fcbc227346 --- /dev/null +++ b/drivers/scsi/mpt2sas/mpt2sas_warpdrive.c | |||
@@ -0,0 +1,338 @@ | |||
1 | /* | ||
2 | * Scsi Host Layer for MPT (Message Passing Technology) based controllers | ||
3 | * | ||
4 | * Copyright (C) 2012-2014 LSI Corporation | ||
5 | * Copyright (C) 2013-2015 Avago Technologies | ||
6 | * (mailto: MPT-FusionLinux.pdl@avagotech.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * NO WARRANTY | ||
19 | * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
20 | * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT | ||
21 | * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, | ||
22 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is | ||
23 | * solely responsible for determining the appropriateness of using and | ||
24 | * distributing the Program and assumes all risks associated with its | ||
25 | * exercise of rights under this Agreement, including but not limited to | ||
26 | * the risks and costs of program errors, damage to or loss of data, | ||
27 | * programs or equipment, and unavailability or interruption of operations. | ||
28 | |||
29 | * DISCLAIMER OF LIABILITY | ||
30 | * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY | ||
31 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
32 | * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND | ||
33 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | ||
34 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
35 | * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED | ||
36 | * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES | ||
37 | |||
38 | * You should have received a copy of the GNU General Public License | ||
39 | * along with this program. | ||
40 | */ | ||
41 | |||
42 | /** | ||
43 | * _scsih_disable_ddio - Disable direct I/O for all the volumes | ||
44 | * @ioc: per adapter object | ||
45 | */ | ||
46 | static void | ||
47 | _scsih_disable_ddio(struct MPT3SAS_ADAPTER *ioc) | ||
48 | { | ||
49 | Mpi2RaidVolPage1_t vol_pg1; | ||
50 | Mpi2ConfigReply_t mpi_reply; | ||
51 | struct _raid_device *raid_device; | ||
52 | u16 handle; | ||
53 | u16 ioc_status; | ||
54 | unsigned long flags; | ||
55 | |||
56 | handle = 0xFFFF; | ||
57 | while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | ||
58 | &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { | ||
59 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
60 | MPI2_IOCSTATUS_MASK; | ||
61 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | ||
62 | break; | ||
63 | handle = le16_to_cpu(vol_pg1.DevHandle); | ||
64 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | ||
65 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | ||
66 | if (raid_device) | ||
67 | raid_device->direct_io_enabled = 0; | ||
68 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | ||
69 | } | ||
70 | return; | ||
71 | } | ||
72 | |||
73 | |||
74 | /** | ||
75 | * _scsih_get_num_volumes - Get number of volumes in the ioc | ||
76 | * @ioc: per adapter object | ||
77 | */ | ||
78 | static u8 | ||
79 | _scsih_get_num_volumes(struct MPT3SAS_ADAPTER *ioc) | ||
80 | { | ||
81 | Mpi2RaidVolPage1_t vol_pg1; | ||
82 | Mpi2ConfigReply_t mpi_reply; | ||
83 | u16 handle; | ||
84 | u8 vol_cnt = 0; | ||
85 | u16 ioc_status; | ||
86 | |||
87 | handle = 0xFFFF; | ||
88 | while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | ||
89 | &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { | ||
90 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
91 | MPI2_IOCSTATUS_MASK; | ||
92 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | ||
93 | break; | ||
94 | vol_cnt++; | ||
95 | handle = le16_to_cpu(vol_pg1.DevHandle); | ||
96 | } | ||
97 | return vol_cnt; | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O. | ||
103 | * @ioc: per adapter object | ||
104 | * @raid_device: the raid_device object | ||
105 | */ | ||
106 | static void | ||
107 | _scsih_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc, | ||
108 | struct _raid_device *raid_device) | ||
109 | { | ||
110 | Mpi2RaidVolPage0_t *vol_pg0; | ||
111 | Mpi2RaidPhysDiskPage0_t pd_pg0; | ||
112 | Mpi2ConfigReply_t mpi_reply; | ||
113 | u16 sz; | ||
114 | u8 num_pds, count; | ||
115 | unsigned long stripe_sz, block_sz; | ||
116 | u8 stripe_exp, block_exp; | ||
117 | u64 dev_max_lba; | ||
118 | |||
119 | if (!ioc->is_warpdrive) | ||
120 | return; | ||
121 | |||
122 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) { | ||
123 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
124 | "globally as drives are exposed\n", ioc->name); | ||
125 | return; | ||
126 | } | ||
127 | if (_scsih_get_num_volumes(ioc) > 1) { | ||
128 | _scsih_disable_ddio(ioc); | ||
129 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
130 | "globally as number of drives > 1\n", ioc->name); | ||
131 | return; | ||
132 | } | ||
133 | if ((mpt3sas_config_get_number_pds(ioc, raid_device->handle, | ||
134 | &num_pds)) || !num_pds) { | ||
135 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
136 | "Failure in computing number of drives\n", ioc->name); | ||
137 | return; | ||
138 | } | ||
139 | |||
140 | sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * | ||
141 | sizeof(Mpi2RaidVol0PhysDisk_t)); | ||
142 | vol_pg0 = kzalloc(sz, GFP_KERNEL); | ||
143 | if (!vol_pg0) { | ||
144 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
145 | "Memory allocation failure for RVPG0\n", ioc->name); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | if ((mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, | ||
150 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { | ||
151 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
152 | "Failure in retrieving RVPG0\n", ioc->name); | ||
153 | kfree(vol_pg0); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * WARPDRIVE:If number of physical disks in a volume exceeds the max pds | ||
159 | * assumed for WARPDRIVE, disable direct I/O | ||
160 | */ | ||
161 | if (num_pds > MPT_MAX_WARPDRIVE_PDS) { | ||
162 | pr_warn(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
163 | "for the drive with handle(0x%04x): num_mem=%d, " | ||
164 | "max_mem_allowed=%d\n", ioc->name, raid_device->handle, | ||
165 | num_pds, MPT_MAX_WARPDRIVE_PDS); | ||
166 | kfree(vol_pg0); | ||
167 | return; | ||
168 | } | ||
169 | for (count = 0; count < num_pds; count++) { | ||
170 | if (mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | ||
171 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, | ||
172 | vol_pg0->PhysDisk[count].PhysDiskNum) || | ||
173 | pd_pg0.DevHandle == MPT3SAS_INVALID_DEVICE_HANDLE) { | ||
174 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is " | ||
175 | "disabled for the drive with handle(0x%04x) member" | ||
176 | "handle retrieval failed for member number=%d\n", | ||
177 | ioc->name, raid_device->handle, | ||
178 | vol_pg0->PhysDisk[count].PhysDiskNum); | ||
179 | goto out_error; | ||
180 | } | ||
181 | /* Disable direct I/O if member drive lba exceeds 4 bytes */ | ||
182 | dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA); | ||
183 | if (dev_max_lba >> 32) { | ||
184 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is " | ||
185 | "disabled for the drive with handle(0x%04x) member" | ||
186 | " handle (0x%04x) unsupported max lba 0x%016llx\n", | ||
187 | ioc->name, raid_device->handle, | ||
188 | le16_to_cpu(pd_pg0.DevHandle), | ||
189 | (unsigned long long)dev_max_lba); | ||
190 | goto out_error; | ||
191 | } | ||
192 | |||
193 | raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle); | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * Assumption for WD: Direct I/O is not supported if the volume is | ||
198 | * not RAID0 | ||
199 | */ | ||
200 | if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) { | ||
201 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
202 | "for the drive with handle(0x%04x): type=%d, " | ||
203 | "s_sz=%uK, blk_size=%u\n", ioc->name, | ||
204 | raid_device->handle, raid_device->volume_type, | ||
205 | (le32_to_cpu(vol_pg0->StripeSize) * | ||
206 | le16_to_cpu(vol_pg0->BlockSize)) / 1024, | ||
207 | le16_to_cpu(vol_pg0->BlockSize)); | ||
208 | goto out_error; | ||
209 | } | ||
210 | |||
211 | stripe_sz = le32_to_cpu(vol_pg0->StripeSize); | ||
212 | stripe_exp = find_first_bit(&stripe_sz, 32); | ||
213 | if (stripe_exp == 32) { | ||
214 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
215 | "for the drive with handle(0x%04x) invalid stripe sz %uK\n", | ||
216 | ioc->name, raid_device->handle, | ||
217 | (le32_to_cpu(vol_pg0->StripeSize) * | ||
218 | le16_to_cpu(vol_pg0->BlockSize)) / 1024); | ||
219 | goto out_error; | ||
220 | } | ||
221 | raid_device->stripe_exponent = stripe_exp; | ||
222 | block_sz = le16_to_cpu(vol_pg0->BlockSize); | ||
223 | block_exp = find_first_bit(&block_sz, 16); | ||
224 | if (block_exp == 16) { | ||
225 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " | ||
226 | "for the drive with handle(0x%04x) invalid block sz %u\n", | ||
227 | ioc->name, raid_device->handle, | ||
228 | le16_to_cpu(vol_pg0->BlockSize)); | ||
229 | goto out_error; | ||
230 | } | ||
231 | raid_device->block_exponent = block_exp; | ||
232 | raid_device->direct_io_enabled = 1; | ||
233 | |||
234 | pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is Enabled for the drive" | ||
235 | " with handle(0x%04x)\n", ioc->name, raid_device->handle); | ||
236 | /* | ||
237 | * WARPDRIVE: Though the following fields are not used for direct IO, | ||
238 | * stored for future purpose: | ||
239 | */ | ||
240 | raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA); | ||
241 | raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize); | ||
242 | raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize); | ||
243 | |||
244 | |||
245 | kfree(vol_pg0); | ||
246 | return; | ||
247 | |||
248 | out_error: | ||
249 | raid_device->direct_io_enabled = 0; | ||
250 | for (count = 0; count < num_pds; count++) | ||
251 | raid_device->pd_handle[count] = 0; | ||
252 | kfree(vol_pg0); | ||
253 | return; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * _scsih_scsi_direct_io_get - returns direct io flag | ||
258 | * @ioc: per adapter object | ||
259 | * @smid: system request message index | ||
260 | * | ||
261 | * Returns the smid stored scmd pointer. | ||
262 | */ | ||
263 | static inline u8 | ||
264 | _scsih_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid) | ||
265 | { | ||
266 | return ioc->scsi_lookup[smid - 1].direct_io; | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * _scsih_scsi_direct_io_set - sets direct io flag | ||
271 | * @ioc: per adapter object | ||
272 | * @smid: system request message index | ||
273 | * @direct_io: Zero or non-zero value to set in the direct_io flag | ||
274 | * | ||
275 | * Returns Nothing. | ||
276 | */ | ||
277 | static inline void | ||
278 | _scsih_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io) | ||
279 | { | ||
280 | ioc->scsi_lookup[smid - 1].direct_io = direct_io; | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O | ||
285 | * @ioc: per adapter object | ||
286 | * @scmd: pointer to scsi command object | ||
287 | * @raid_device: pointer to raid device data structure | ||
288 | * @mpi_request: pointer to the SCSI_IO reqest message frame | ||
289 | * @smid: system request message index | ||
290 | * | ||
291 | * Returns nothing | ||
292 | */ | ||
293 | static void | ||
294 | _scsih_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | ||
295 | struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, | ||
296 | u16 smid) | ||
297 | { | ||
298 | sector_t v_lba, p_lba, stripe_off, stripe_unit, column, io_size; | ||
299 | u32 stripe_sz, stripe_exp; | ||
300 | u8 num_pds, cmd = scmd->cmnd[0]; | ||
301 | |||
302 | if (cmd != READ_10 && cmd != WRITE_10 && | ||
303 | cmd != READ_16 && cmd != WRITE_16) | ||
304 | return; | ||
305 | |||
306 | if (cmd == READ_10 || cmd == WRITE_10) | ||
307 | v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]); | ||
308 | else | ||
309 | v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]); | ||
310 | |||
311 | io_size = scsi_bufflen(scmd) >> raid_device->block_exponent; | ||
312 | |||
313 | if (v_lba + io_size - 1 > raid_device->max_lba) | ||
314 | return; | ||
315 | |||
316 | stripe_sz = raid_device->stripe_sz; | ||
317 | stripe_exp = raid_device->stripe_exponent; | ||
318 | stripe_off = v_lba & (stripe_sz - 1); | ||
319 | |||
320 | /* Return unless IO falls within a stripe */ | ||
321 | if (stripe_off + io_size > stripe_sz) | ||
322 | return; | ||
323 | |||
324 | num_pds = raid_device->num_pds; | ||
325 | p_lba = v_lba >> stripe_exp; | ||
326 | stripe_unit = p_lba / num_pds; | ||
327 | column = p_lba % num_pds; | ||
328 | p_lba = (stripe_unit << stripe_exp) + stripe_off; | ||
329 | mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]); | ||
330 | |||
331 | if (cmd == READ_10 || cmd == WRITE_10) | ||
332 | put_unaligned_be32(lower_32_bits(p_lba), | ||
333 | &mpi_request->CDB.CDB32[2]); | ||
334 | else | ||
335 | put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]); | ||
336 | |||
337 | _scsih_scsi_direct_io_set(ioc, smid, 1); | ||
338 | } | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index b5b1eb260750..f7f2ab5ecc4f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
@@ -593,7 +593,8 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc, | |||
593 | desc = "Device Status Change"; | 593 | desc = "Device Status Change"; |
594 | break; | 594 | break; |
595 | case MPI2_EVENT_IR_OPERATION_STATUS: | 595 | case MPI2_EVENT_IR_OPERATION_STATUS: |
596 | desc = "IR Operation Status"; | 596 | if (!ioc->hide_ir_msg) |
597 | desc = "IR Operation Status"; | ||
597 | break; | 598 | break; |
598 | case MPI2_EVENT_SAS_DISCOVERY: | 599 | case MPI2_EVENT_SAS_DISCOVERY: |
599 | { | 600 | { |
@@ -624,16 +625,20 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc, | |||
624 | desc = "SAS Enclosure Device Status Change"; | 625 | desc = "SAS Enclosure Device Status Change"; |
625 | break; | 626 | break; |
626 | case MPI2_EVENT_IR_VOLUME: | 627 | case MPI2_EVENT_IR_VOLUME: |
627 | desc = "IR Volume"; | 628 | if (!ioc->hide_ir_msg) |
629 | desc = "IR Volume"; | ||
628 | break; | 630 | break; |
629 | case MPI2_EVENT_IR_PHYSICAL_DISK: | 631 | case MPI2_EVENT_IR_PHYSICAL_DISK: |
630 | desc = "IR Physical Disk"; | 632 | if (!ioc->hide_ir_msg) |
633 | desc = "IR Physical Disk"; | ||
631 | break; | 634 | break; |
632 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: | 635 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: |
633 | desc = "IR Configuration Change List"; | 636 | if (!ioc->hide_ir_msg) |
637 | desc = "IR Configuration Change List"; | ||
634 | break; | 638 | break; |
635 | case MPI2_EVENT_LOG_ENTRY_ADDED: | 639 | case MPI2_EVENT_LOG_ENTRY_ADDED: |
636 | desc = "Log Entry Added"; | 640 | if (!ioc->hide_ir_msg) |
641 | desc = "Log Entry Added"; | ||
637 | break; | 642 | break; |
638 | case MPI2_EVENT_TEMP_THRESHOLD: | 643 | case MPI2_EVENT_TEMP_THRESHOLD: |
639 | desc = "Temperature Threshold"; | 644 | desc = "Temperature Threshold"; |
@@ -689,7 +694,10 @@ _base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info) | |||
689 | originator_str = "PL"; | 694 | originator_str = "PL"; |
690 | break; | 695 | break; |
691 | case 2: | 696 | case 2: |
692 | originator_str = "IR"; | 697 | if (!ioc->hide_ir_msg) |
698 | originator_str = "IR"; | ||
699 | else | ||
700 | originator_str = "WarpDrive"; | ||
693 | break; | 701 | break; |
694 | } | 702 | } |
695 | 703 | ||
@@ -1023,6 +1031,12 @@ _base_interrupt(int irq, void *bus_id) | |||
1023 | } | 1031 | } |
1024 | 1032 | ||
1025 | wmb(); | 1033 | wmb(); |
1034 | if (ioc->is_warpdrive) { | ||
1035 | writel(reply_q->reply_post_host_index, | ||
1036 | ioc->reply_post_host_index[msix_index]); | ||
1037 | atomic_dec(&reply_q->busy); | ||
1038 | return IRQ_HANDLED; | ||
1039 | } | ||
1026 | 1040 | ||
1027 | /* Update Reply Post Host Index. | 1041 | /* Update Reply Post Host Index. |
1028 | * For those HBA's which support combined reply queue feature | 1042 | * For those HBA's which support combined reply queue feature |
@@ -2333,6 +2347,7 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid) | |||
2333 | } | 2347 | } |
2334 | ioc->scsi_lookup[i].cb_idx = 0xFF; | 2348 | ioc->scsi_lookup[i].cb_idx = 0xFF; |
2335 | ioc->scsi_lookup[i].scmd = NULL; | 2349 | ioc->scsi_lookup[i].scmd = NULL; |
2350 | ioc->scsi_lookup[i].direct_io = 0; | ||
2336 | list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list); | 2351 | list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list); |
2337 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | 2352 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
2338 | 2353 | ||
@@ -2683,10 +2698,12 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) | |||
2683 | pr_info("), "); | 2698 | pr_info("), "); |
2684 | pr_info("Capabilities=("); | 2699 | pr_info("Capabilities=("); |
2685 | 2700 | ||
2686 | if (ioc->facts.IOCCapabilities & | 2701 | if (!ioc->hide_ir_msg) { |
2702 | if (ioc->facts.IOCCapabilities & | ||
2687 | MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { | 2703 | MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { |
2688 | pr_info("Raid"); | 2704 | pr_info("Raid"); |
2689 | i++; | 2705 | i++; |
2706 | } | ||
2690 | } | 2707 | } |
2691 | 2708 | ||
2692 | if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { | 2709 | if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { |
@@ -4834,6 +4851,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
4834 | u32 reply_address; | 4851 | u32 reply_address; |
4835 | u16 smid; | 4852 | u16 smid; |
4836 | struct _tr_list *delayed_tr, *delayed_tr_next; | 4853 | struct _tr_list *delayed_tr, *delayed_tr_next; |
4854 | u8 hide_flag; | ||
4837 | struct adapter_reply_queue *reply_q; | 4855 | struct adapter_reply_queue *reply_q; |
4838 | long reply_post_free; | 4856 | long reply_post_free; |
4839 | u32 reply_post_free_sz, index = 0; | 4857 | u32 reply_post_free_sz, index = 0; |
@@ -4864,6 +4882,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
4864 | ioc->scsi_lookup[i].cb_idx = 0xFF; | 4882 | ioc->scsi_lookup[i].cb_idx = 0xFF; |
4865 | ioc->scsi_lookup[i].smid = smid; | 4883 | ioc->scsi_lookup[i].smid = smid; |
4866 | ioc->scsi_lookup[i].scmd = NULL; | 4884 | ioc->scsi_lookup[i].scmd = NULL; |
4885 | ioc->scsi_lookup[i].direct_io = 0; | ||
4867 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, | 4886 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, |
4868 | &ioc->free_list); | 4887 | &ioc->free_list); |
4869 | } | 4888 | } |
@@ -4966,6 +4985,16 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
4966 | 4985 | ||
4967 | 4986 | ||
4968 | if (ioc->is_driver_loading) { | 4987 | if (ioc->is_driver_loading) { |
4988 | |||
4989 | if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier | ||
4990 | == 0x80) { | ||
4991 | hide_flag = (u8) ( | ||
4992 | le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) & | ||
4993 | MFG_PAGE10_HIDE_SSDS_MASK); | ||
4994 | if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) | ||
4995 | ioc->mfg_pg10_hide_flag = hide_flag; | ||
4996 | } | ||
4997 | |||
4969 | ioc->wait_for_discovery_to_complete = | 4998 | ioc->wait_for_discovery_to_complete = |
4970 | _base_determine_wait_on_discovery(ioc); | 4999 | _base_determine_wait_on_discovery(ioc); |
4971 | 5000 | ||
@@ -5032,12 +5061,33 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
5032 | goto out_free_resources; | 5061 | goto out_free_resources; |
5033 | } | 5062 | } |
5034 | 5063 | ||
5064 | if (ioc->is_warpdrive) { | ||
5065 | ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz, | ||
5066 | sizeof(resource_size_t *), GFP_KERNEL); | ||
5067 | if (!ioc->reply_post_host_index) { | ||
5068 | dfailprintk(ioc, pr_info(MPT3SAS_FMT "allocation " | ||
5069 | "for cpu_msix_table failed!!!\n", ioc->name)); | ||
5070 | r = -ENOMEM; | ||
5071 | goto out_free_resources; | ||
5072 | } | ||
5073 | } | ||
5074 | |||
5035 | ioc->rdpq_array_enable_assigned = 0; | 5075 | ioc->rdpq_array_enable_assigned = 0; |
5036 | ioc->dma_mask = 0; | 5076 | ioc->dma_mask = 0; |
5037 | r = mpt3sas_base_map_resources(ioc); | 5077 | r = mpt3sas_base_map_resources(ioc); |
5038 | if (r) | 5078 | if (r) |
5039 | goto out_free_resources; | 5079 | goto out_free_resources; |
5040 | 5080 | ||
5081 | if (ioc->is_warpdrive) { | ||
5082 | ioc->reply_post_host_index[0] = (resource_size_t __iomem *) | ||
5083 | &ioc->chip->ReplyPostHostIndex; | ||
5084 | |||
5085 | for (i = 1; i < ioc->cpu_msix_table_sz; i++) | ||
5086 | ioc->reply_post_host_index[i] = | ||
5087 | (resource_size_t __iomem *) | ||
5088 | ((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1) | ||
5089 | * 4))); | ||
5090 | } | ||
5041 | 5091 | ||
5042 | pci_set_drvdata(ioc->pdev, ioc->shost); | 5092 | pci_set_drvdata(ioc->pdev, ioc->shost); |
5043 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); | 5093 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); |
@@ -5189,6 +5239,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
5189 | _base_release_memory_pools(ioc); | 5239 | _base_release_memory_pools(ioc); |
5190 | pci_set_drvdata(ioc->pdev, NULL); | 5240 | pci_set_drvdata(ioc->pdev, NULL); |
5191 | kfree(ioc->cpu_msix_table); | 5241 | kfree(ioc->cpu_msix_table); |
5242 | if (ioc->is_warpdrive) | ||
5243 | kfree(ioc->reply_post_host_index); | ||
5192 | kfree(ioc->pd_handles); | 5244 | kfree(ioc->pd_handles); |
5193 | kfree(ioc->blocking_handles); | 5245 | kfree(ioc->blocking_handles); |
5194 | kfree(ioc->tm_cmds.reply); | 5246 | kfree(ioc->tm_cmds.reply); |
@@ -5228,6 +5280,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc) | |||
5228 | _base_release_memory_pools(ioc); | 5280 | _base_release_memory_pools(ioc); |
5229 | pci_set_drvdata(ioc->pdev, NULL); | 5281 | pci_set_drvdata(ioc->pdev, NULL); |
5230 | kfree(ioc->cpu_msix_table); | 5282 | kfree(ioc->cpu_msix_table); |
5283 | if (ioc->is_warpdrive) | ||
5284 | kfree(ioc->reply_post_host_index); | ||
5231 | kfree(ioc->pd_handles); | 5285 | kfree(ioc->pd_handles); |
5232 | kfree(ioc->blocking_handles); | 5286 | kfree(ioc->blocking_handles); |
5233 | kfree(ioc->pfacts); | 5287 | kfree(ioc->pfacts); |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index a0d1f1304b44..397f8a5e51b8 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -135,6 +135,16 @@ | |||
135 | #define MPT3SAS_FMT "%s: " | 135 | #define MPT3SAS_FMT "%s: " |
136 | 136 | ||
137 | /* | 137 | /* |
138 | * WarpDrive Specific Log codes | ||
139 | */ | ||
140 | |||
141 | #define MPT2_WARPDRIVE_LOGENTRY (0x8002) | ||
142 | #define MPT2_WARPDRIVE_LC_SSDT (0x41) | ||
143 | #define MPT2_WARPDRIVE_LC_SSDLW (0x43) | ||
144 | #define MPT2_WARPDRIVE_LC_SSDLF (0x44) | ||
145 | #define MPT2_WARPDRIVE_LC_BRMF (0x4D) | ||
146 | |||
147 | /* | ||
138 | * per target private data | 148 | * per target private data |
139 | */ | 149 | */ |
140 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 | 150 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 |
@@ -257,6 +267,7 @@ struct Mpi2ManufacturingPage11_t { | |||
257 | * struct MPT3SAS_TARGET - starget private hostdata | 267 | * struct MPT3SAS_TARGET - starget private hostdata |
258 | * @starget: starget object | 268 | * @starget: starget object |
259 | * @sas_address: target sas address | 269 | * @sas_address: target sas address |
270 | * @raid_device: raid_device pointer to access volume data | ||
260 | * @handle: device handle | 271 | * @handle: device handle |
261 | * @num_luns: number luns | 272 | * @num_luns: number luns |
262 | * @flags: MPT_TARGET_FLAGS_XXX flags | 273 | * @flags: MPT_TARGET_FLAGS_XXX flags |
@@ -266,6 +277,7 @@ struct Mpi2ManufacturingPage11_t { | |||
266 | struct MPT3SAS_TARGET { | 277 | struct MPT3SAS_TARGET { |
267 | struct scsi_target *starget; | 278 | struct scsi_target *starget; |
268 | u64 sas_address; | 279 | u64 sas_address; |
280 | struct _raid_device *raid_device; | ||
269 | u16 handle; | 281 | u16 handle; |
270 | int num_luns; | 282 | int num_luns; |
271 | u32 flags; | 283 | u32 flags; |
@@ -280,6 +292,11 @@ struct MPT3SAS_TARGET { | |||
280 | #define MPT_DEVICE_FLAGS_INIT 0x01 | 292 | #define MPT_DEVICE_FLAGS_INIT 0x01 |
281 | #define MPT_DEVICE_TLR_ON 0x02 | 293 | #define MPT_DEVICE_TLR_ON 0x02 |
282 | 294 | ||
295 | #define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003) | ||
296 | #define MFG_PAGE10_HIDE_ALL_DISKS (0x00) | ||
297 | #define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01) | ||
298 | #define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02) | ||
299 | |||
283 | /** | 300 | /** |
284 | * struct MPT3SAS_DEVICE - sdev private hostdata | 301 | * struct MPT3SAS_DEVICE - sdev private hostdata |
285 | * @sas_target: starget private hostdata | 302 | * @sas_target: starget private hostdata |
@@ -381,6 +398,7 @@ struct _sas_device { | |||
381 | * @sdev: scsi device struct (volumes are single lun) | 398 | * @sdev: scsi device struct (volumes are single lun) |
382 | * @wwid: unique identifier for the volume | 399 | * @wwid: unique identifier for the volume |
383 | * @handle: device handle | 400 | * @handle: device handle |
401 | * @block_size: Block size of the volume | ||
384 | * @id: target id | 402 | * @id: target id |
385 | * @channel: target channel | 403 | * @channel: target channel |
386 | * @volume_type: the raid level | 404 | * @volume_type: the raid level |
@@ -388,6 +406,13 @@ struct _sas_device { | |||
388 | * @num_pds: number of hidden raid components | 406 | * @num_pds: number of hidden raid components |
389 | * @responding: used in _scsih_raid_device_mark_responding | 407 | * @responding: used in _scsih_raid_device_mark_responding |
390 | * @percent_complete: resync percent complete | 408 | * @percent_complete: resync percent complete |
409 | * @direct_io_enabled: Whether direct io to PDs are allowed or not | ||
410 | * @stripe_exponent: X where 2powX is the stripe sz in blocks | ||
411 | * @block_exponent: X where 2powX is the block sz in bytes | ||
412 | * @max_lba: Maximum number of LBA in the volume | ||
413 | * @stripe_sz: Stripe Size of the volume | ||
414 | * @device_info: Device info of the volume member disk | ||
415 | * @pd_handle: Array of handles of the physical drives for direct I/O in le16 | ||
391 | */ | 416 | */ |
392 | #define MPT_MAX_WARPDRIVE_PDS 8 | 417 | #define MPT_MAX_WARPDRIVE_PDS 8 |
393 | struct _raid_device { | 418 | struct _raid_device { |
@@ -396,13 +421,20 @@ struct _raid_device { | |||
396 | struct scsi_device *sdev; | 421 | struct scsi_device *sdev; |
397 | u64 wwid; | 422 | u64 wwid; |
398 | u16 handle; | 423 | u16 handle; |
424 | u16 block_sz; | ||
399 | int id; | 425 | int id; |
400 | int channel; | 426 | int channel; |
401 | u8 volume_type; | 427 | u8 volume_type; |
402 | u8 num_pds; | 428 | u8 num_pds; |
403 | u8 responding; | 429 | u8 responding; |
404 | u8 percent_complete; | 430 | u8 percent_complete; |
431 | u8 direct_io_enabled; | ||
432 | u8 stripe_exponent; | ||
433 | u8 block_exponent; | ||
434 | u64 max_lba; | ||
435 | u32 stripe_sz; | ||
405 | u32 device_info; | 436 | u32 device_info; |
437 | u16 pd_handle[MPT_MAX_WARPDRIVE_PDS]; | ||
406 | }; | 438 | }; |
407 | 439 | ||
408 | /** | 440 | /** |
@@ -511,12 +543,14 @@ struct chain_tracker { | |||
511 | * @smid: system message id | 543 | * @smid: system message id |
512 | * @scmd: scsi request pointer | 544 | * @scmd: scsi request pointer |
513 | * @cb_idx: callback index | 545 | * @cb_idx: callback index |
546 | * @direct_io: To indicate whether I/O is direct (WARPDRIVE) | ||
514 | * @tracker_list: list of free request (ioc->free_list) | 547 | * @tracker_list: list of free request (ioc->free_list) |
515 | */ | 548 | */ |
516 | struct scsiio_tracker { | 549 | struct scsiio_tracker { |
517 | u16 smid; | 550 | u16 smid; |
518 | struct scsi_cmnd *scmd; | 551 | struct scsi_cmnd *scmd; |
519 | u8 cb_idx; | 552 | u8 cb_idx; |
553 | u8 direct_io; | ||
520 | struct list_head chain_list; | 554 | struct list_head chain_list; |
521 | struct list_head tracker_list; | 555 | struct list_head tracker_list; |
522 | }; | 556 | }; |
@@ -843,6 +877,7 @@ struct MPT3SAS_ADAPTER { | |||
843 | u16 msix_vector_count; | 877 | u16 msix_vector_count; |
844 | u8 *cpu_msix_table; | 878 | u8 *cpu_msix_table; |
845 | u16 cpu_msix_table_sz; | 879 | u16 cpu_msix_table_sz; |
880 | resource_size_t __iomem **reply_post_host_index; | ||
846 | u32 ioc_reset_count; | 881 | u32 ioc_reset_count; |
847 | MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; | 882 | MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; |
848 | u32 non_operational_loop; | 883 | u32 non_operational_loop; |
@@ -1014,6 +1049,10 @@ struct MPT3SAS_ADAPTER { | |||
1014 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; | 1049 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; |
1015 | u32 ring_buffer_offset; | 1050 | u32 ring_buffer_offset; |
1016 | u32 ring_buffer_sz; | 1051 | u32 ring_buffer_sz; |
1052 | u8 is_warpdrive; | ||
1053 | u8 hide_ir_msg; | ||
1054 | u8 mfg_pg10_hide_flag; | ||
1055 | u8 hide_drives; | ||
1017 | spinlock_t diag_trigger_lock; | 1056 | spinlock_t diag_trigger_lock; |
1018 | u8 diag_trigger_active; | 1057 | u8 diag_trigger_active; |
1019 | struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; | 1058 | struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 5c08d31f781f..3f22754adb4f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c | |||
@@ -1030,7 +1030,10 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) | |||
1030 | strcat(karg.driver_version, "-"); | 1030 | strcat(karg.driver_version, "-"); |
1031 | switch (ioc->hba_mpi_version_belonged) { | 1031 | switch (ioc->hba_mpi_version_belonged) { |
1032 | case MPI2_VERSION: | 1032 | case MPI2_VERSION: |
1033 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; | 1033 | if (ioc->is_warpdrive) |
1034 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200; | ||
1035 | else | ||
1036 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; | ||
1034 | strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); | 1037 | strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); |
1035 | break; | 1038 | break; |
1036 | case MPI25_VERSION: | 1039 | case MPI25_VERSION: |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h index f43e3c2c3353..89408356d252 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h | |||
@@ -141,6 +141,7 @@ struct mpt3_ioctl_pci_info { | |||
141 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) | 141 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) |
142 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) | 142 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) |
143 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) | 143 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) |
144 | #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) | ||
144 | #define MPT3_IOCTL_INTERFACE_SAS3 (0x06) | 145 | #define MPT3_IOCTL_INTERFACE_SAS3 (0x06) |
145 | #define MPT2_IOCTL_VERSION_LENGTH (32) | 146 | #define MPT2_IOCTL_VERSION_LENGTH (32) |
146 | 147 | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 2b51a414a380..dc6b0ba851a6 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
55 | #include <linux/aer.h> | 55 | #include <linux/aer.h> |
56 | #include <linux/raid_class.h> | 56 | #include <linux/raid_class.h> |
57 | #include <asm/unaligned.h> | ||
57 | 58 | ||
58 | #include "mpt3sas_base.h" | 59 | #include "mpt3sas_base.h" |
59 | 60 | ||
@@ -70,6 +71,21 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |||
70 | 71 | ||
71 | static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid); | 72 | static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid); |
72 | 73 | ||
74 | #ifdef SCSI_MPT2SAS | ||
75 | static void _scsih_disable_ddio(struct MPT3SAS_ADAPTER *ioc); | ||
76 | static u8 _scsih_get_num_volumes(struct MPT3SAS_ADAPTER *ioc); | ||
77 | static void | ||
78 | _scsih_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc, | ||
79 | struct _raid_device *raid_device); | ||
80 | static inline u8 | ||
81 | _scsih_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid); | ||
82 | static inline void | ||
83 | _scsih_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io); | ||
84 | static void | ||
85 | _scsih_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | ||
86 | struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, | ||
87 | u16 smid); | ||
88 | #endif | ||
73 | 89 | ||
74 | /* global parameters */ | 90 | /* global parameters */ |
75 | LIST_HEAD(mpt3sas_ioc_list); | 91 | LIST_HEAD(mpt3sas_ioc_list); |
@@ -1144,7 +1160,9 @@ scsih_target_alloc(struct scsi_target *starget) | |||
1144 | sas_target_priv_data->handle = raid_device->handle; | 1160 | sas_target_priv_data->handle = raid_device->handle; |
1145 | sas_target_priv_data->sas_address = raid_device->wwid; | 1161 | sas_target_priv_data->sas_address = raid_device->wwid; |
1146 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; | 1162 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; |
1147 | raid_device->starget = starget; | 1163 | sas_target_priv_data->raid_device = raid_device; |
1164 | if (ioc->is_warpdrive) | ||
1165 | raid_device->starget = starget; | ||
1148 | } | 1166 | } |
1149 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1167 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1150 | return 0; | 1168 | return 0; |
@@ -1386,7 +1404,10 @@ int | |||
1386 | scsih_is_raid(struct device *dev) | 1404 | scsih_is_raid(struct device *dev) |
1387 | { | 1405 | { |
1388 | struct scsi_device *sdev = to_scsi_device(dev); | 1406 | struct scsi_device *sdev = to_scsi_device(dev); |
1407 | struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
1389 | 1408 | ||
1409 | if (ioc->is_warpdrive) | ||
1410 | return 0; | ||
1390 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; | 1411 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; |
1391 | } | 1412 | } |
1392 | 1413 | ||
@@ -1409,6 +1430,9 @@ scsih_get_resync(struct device *dev) | |||
1409 | 1430 | ||
1410 | percent_complete = 0; | 1431 | percent_complete = 0; |
1411 | handle = 0; | 1432 | handle = 0; |
1433 | if (ioc->is_warpdrive) | ||
1434 | goto out; | ||
1435 | |||
1412 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 1436 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
1413 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, | 1437 | raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, |
1414 | sdev->channel); | 1438 | sdev->channel); |
@@ -1592,8 +1616,6 @@ _scsih_get_volume_capabilities(struct MPT3SAS_ADAPTER *ioc, | |||
1592 | return 0; | 1616 | return 0; |
1593 | } | 1617 | } |
1594 | 1618 | ||
1595 | |||
1596 | |||
1597 | /** | 1619 | /** |
1598 | * _scsih_enable_tlr - setting TLR flags | 1620 | * _scsih_enable_tlr - setting TLR flags |
1599 | * @ioc: per adapter object | 1621 | * @ioc: per adapter object |
@@ -1672,6 +1694,12 @@ scsih_slave_configure(struct scsi_device *sdev) | |||
1672 | return 1; | 1694 | return 1; |
1673 | } | 1695 | } |
1674 | 1696 | ||
1697 | #ifdef SCSI_MPT2SAS | ||
1698 | /* | ||
1699 | * WARPDRIVE: Initialize the required data for Direct IO | ||
1700 | */ | ||
1701 | _scsih_init_warpdrive_properties(ioc, raid_device); | ||
1702 | #endif | ||
1675 | 1703 | ||
1676 | /* RAID Queue Depth Support | 1704 | /* RAID Queue Depth Support |
1677 | * IS volume = underlying qdepth of drive type, either | 1705 | * IS volume = underlying qdepth of drive type, either |
@@ -1720,17 +1748,19 @@ scsih_slave_configure(struct scsi_device *sdev) | |||
1720 | break; | 1748 | break; |
1721 | } | 1749 | } |
1722 | 1750 | ||
1723 | sdev_printk(KERN_INFO, sdev, | 1751 | if (!ioc->hide_ir_msg) |
1724 | "%s: handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n", | 1752 | sdev_printk(KERN_INFO, sdev, |
1725 | r_level, raid_device->handle, | 1753 | "%s: handle(0x%04x), wwid(0x%016llx)," |
1726 | (unsigned long long)raid_device->wwid, | 1754 | " pd_count(%d), type(%s)\n", |
1727 | raid_device->num_pds, ds); | 1755 | r_level, raid_device->handle, |
1728 | 1756 | (unsigned long long)raid_device->wwid, | |
1757 | raid_device->num_pds, ds); | ||
1729 | 1758 | ||
1730 | scsih_change_queue_depth(sdev, qdepth); | 1759 | scsih_change_queue_depth(sdev, qdepth); |
1731 | 1760 | ||
1732 | /* raid transport support */ | 1761 | /* raid transport support */ |
1733 | _scsih_set_level(sdev, raid_device->volume_type); | 1762 | if (!ioc->is_warpdrive) |
1763 | _scsih_set_level(sdev, raid_device->volume_type); | ||
1734 | return 0; | 1764 | return 0; |
1735 | } | 1765 | } |
1736 | 1766 | ||
@@ -2179,7 +2209,10 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2179 | 2209 | ||
2180 | if (!priv_target) | 2210 | if (!priv_target) |
2181 | return; | 2211 | return; |
2182 | device_str = "volume"; | 2212 | if (ioc->hide_ir_msg) |
2213 | device_str = "WarpDrive"; | ||
2214 | else | ||
2215 | device_str = "volume"; | ||
2183 | 2216 | ||
2184 | scsi_print_command(scmd); | 2217 | scsi_print_command(scmd); |
2185 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { | 2218 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { |
@@ -3368,6 +3401,9 @@ _scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc, | |||
3368 | a = 0; | 3401 | a = 0; |
3369 | b = 0; | 3402 | b = 0; |
3370 | 3403 | ||
3404 | if (ioc->is_warpdrive) | ||
3405 | return; | ||
3406 | |||
3371 | /* Volume Resets for Deleted or Removed */ | 3407 | /* Volume Resets for Deleted or Removed */ |
3372 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 3408 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
3373 | for (i = 0; i < event_data->NumElements; i++, element++) { | 3409 | for (i = 0; i < event_data->NumElements; i++, element++) { |
@@ -3604,6 +3640,7 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) | |||
3604 | } | 3640 | } |
3605 | 3641 | ||
3606 | 3642 | ||
3643 | |||
3607 | /** | 3644 | /** |
3608 | * scsih_qcmd - main scsi request entry point | 3645 | * scsih_qcmd - main scsi request entry point |
3609 | * @scmd: pointer to scsi command object | 3646 | * @scmd: pointer to scsi command object |
@@ -3621,6 +3658,9 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
3621 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); | 3658 | struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); |
3622 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 3659 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
3623 | struct MPT3SAS_TARGET *sas_target_priv_data; | 3660 | struct MPT3SAS_TARGET *sas_target_priv_data; |
3661 | #ifdef SCSI_MPT2SAS | ||
3662 | struct _raid_device *raid_device; | ||
3663 | #endif | ||
3624 | Mpi2SCSIIORequest_t *mpi_request; | 3664 | Mpi2SCSIIORequest_t *mpi_request; |
3625 | u32 mpi_control; | 3665 | u32 mpi_control; |
3626 | u16 smid; | 3666 | u16 smid; |
@@ -3677,7 +3717,11 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
3677 | /* set tags */ | 3717 | /* set tags */ |
3678 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3718 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
3679 | 3719 | ||
3680 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | 3720 | /* Make sure Device is not raid volume. |
3721 | * We do not expose raid functionality to upper layer for warpdrive. | ||
3722 | */ | ||
3723 | if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev) | ||
3724 | && (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | ||
3681 | scmd->cmd_len != 32) | 3725 | scmd->cmd_len != 32) |
3682 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3726 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
3683 | 3727 | ||
@@ -3720,6 +3764,13 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
3720 | } else | 3764 | } else |
3721 | ioc->build_zero_len_sge(ioc, &mpi_request->SGL); | 3765 | ioc->build_zero_len_sge(ioc, &mpi_request->SGL); |
3722 | 3766 | ||
3767 | #ifdef SCSI_MPT2SAS | ||
3768 | raid_device = sas_target_priv_data->raid_device; | ||
3769 | if (raid_device && raid_device->direct_io_enabled) | ||
3770 | _scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request, | ||
3771 | smid); | ||
3772 | #endif | ||
3773 | |||
3723 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) { | 3774 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) { |
3724 | #ifndef SCSI_MPT2SAS | 3775 | #ifndef SCSI_MPT2SAS |
3725 | if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { | 3776 | if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { |
@@ -3728,7 +3779,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
3728 | mpt3sas_base_put_smid_fast_path(ioc, smid, handle); | 3779 | mpt3sas_base_put_smid_fast_path(ioc, smid, handle); |
3729 | } else | 3780 | } else |
3730 | #endif | 3781 | #endif |
3731 | mpt3sas_base_put_smid_scsi_io(ioc, smid, handle); | 3782 | mpt3sas_base_put_smid_scsi_io(ioc, smid, |
3783 | le16_to_cpu(mpi_request->DevHandle)); | ||
3732 | } else | 3784 | } else |
3733 | mpt3sas_base_put_smid_default(ioc, smid); | 3785 | mpt3sas_base_put_smid_default(ioc, smid); |
3734 | return 0; | 3786 | return 0; |
@@ -3794,7 +3846,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3794 | 3846 | ||
3795 | if (!priv_target) | 3847 | if (!priv_target) |
3796 | return; | 3848 | return; |
3797 | device_str = "volume"; | 3849 | if (ioc->hide_ir_msg) |
3850 | device_str = "WarpDrive"; | ||
3851 | else | ||
3852 | device_str = "volume"; | ||
3798 | 3853 | ||
3799 | if (log_info == 0x31170000) | 3854 | if (log_info == 0x31170000) |
3800 | return; | 3855 | return; |
@@ -4175,6 +4230,9 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4175 | u32 log_info; | 4230 | u32 log_info; |
4176 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 4231 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
4177 | u32 response_code = 0; | 4232 | u32 response_code = 0; |
4233 | #ifdef SCSI_MPT2SAS | ||
4234 | unsigned long flags; | ||
4235 | #endif | ||
4178 | 4236 | ||
4179 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); | 4237 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); |
4180 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); | 4238 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
@@ -4196,6 +4254,26 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4196 | } | 4254 | } |
4197 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus); | 4255 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus); |
4198 | 4256 | ||
4257 | #ifdef SCSI_MPT2SAS | ||
4258 | /* | ||
4259 | * WARPDRIVE: If direct_io is set then it is directIO, | ||
4260 | * the failed direct I/O should be redirected to volume | ||
4261 | */ | ||
4262 | if (_scsih_scsi_direct_io_get(ioc, smid) && | ||
4263 | ((ioc_status & MPI2_IOCSTATUS_MASK) | ||
4264 | != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) { | ||
4265 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
4266 | ioc->scsi_lookup[smid - 1].scmd = scmd; | ||
4267 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
4268 | _scsih_scsi_direct_io_set(ioc, smid, 0); | ||
4269 | memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); | ||
4270 | mpi_request->DevHandle = | ||
4271 | cpu_to_le16(sas_device_priv_data->sas_target->handle); | ||
4272 | mpt3sas_base_put_smid_scsi_io(ioc, smid, | ||
4273 | sas_device_priv_data->sas_target->handle); | ||
4274 | return 0; | ||
4275 | } | ||
4276 | #endif | ||
4199 | /* turning off TLR */ | 4277 | /* turning off TLR */ |
4200 | scsi_state = mpi_reply->SCSIState; | 4278 | scsi_state = mpi_reply->SCSIState; |
4201 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) | 4279 | if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) |
@@ -4203,7 +4281,9 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4203 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | 4281 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; |
4204 | if (!sas_device_priv_data->tlr_snoop_check) { | 4282 | if (!sas_device_priv_data->tlr_snoop_check) { |
4205 | sas_device_priv_data->tlr_snoop_check++; | 4283 | sas_device_priv_data->tlr_snoop_check++; |
4206 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | 4284 | if (!ioc->is_warpdrive && |
4285 | !scsih_is_raid(&scmd->device->sdev_gendev) && | ||
4286 | (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | ||
4207 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) | 4287 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) |
4208 | sas_device_priv_data->flags &= | 4288 | sas_device_priv_data->flags &= |
4209 | ~MPT_DEVICE_TLR_ON; | 4289 | ~MPT_DEVICE_TLR_ON; |
@@ -5110,7 +5190,9 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, | |||
5110 | sas_target_priv_data->handle = | 5190 | sas_target_priv_data->handle = |
5111 | MPT3SAS_INVALID_DEVICE_HANDLE; | 5191 | MPT3SAS_INVALID_DEVICE_HANDLE; |
5112 | } | 5192 | } |
5113 | mpt3sas_transport_port_remove(ioc, | 5193 | |
5194 | if (!ioc->hide_drives) | ||
5195 | mpt3sas_transport_port_remove(ioc, | ||
5114 | sas_device->sas_address, | 5196 | sas_device->sas_address, |
5115 | sas_device->sas_address_parent); | 5197 | sas_device->sas_address_parent); |
5116 | 5198 | ||
@@ -6208,7 +6290,8 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
6208 | (Mpi2EventDataIrConfigChangeList_t *) | 6290 | (Mpi2EventDataIrConfigChangeList_t *) |
6209 | fw_event->event_data; | 6291 | fw_event->event_data; |
6210 | 6292 | ||
6211 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 6293 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && |
6294 | (!ioc->hide_ir_msg)) | ||
6212 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); | 6295 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); |
6213 | 6296 | ||
6214 | foreign_config = (le32_to_cpu(event_data->Flags) & | 6297 | foreign_config = (le32_to_cpu(event_data->Flags) & |
@@ -6226,6 +6309,7 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
6226 | #endif | 6309 | #endif |
6227 | return; | 6310 | return; |
6228 | } | 6311 | } |
6312 | |||
6229 | for (i = 0; i < event_data->NumElements; i++, element++) { | 6313 | for (i = 0; i < event_data->NumElements; i++, element++) { |
6230 | 6314 | ||
6231 | switch (element->ReasonCode) { | 6315 | switch (element->ReasonCode) { |
@@ -6241,16 +6325,20 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, | |||
6241 | le16_to_cpu(element->VolDevHandle)); | 6325 | le16_to_cpu(element->VolDevHandle)); |
6242 | break; | 6326 | break; |
6243 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: | 6327 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: |
6244 | _scsih_sas_pd_hide(ioc, element); | 6328 | if (!ioc->is_warpdrive) |
6329 | _scsih_sas_pd_hide(ioc, element); | ||
6245 | break; | 6330 | break; |
6246 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: | 6331 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: |
6247 | _scsih_sas_pd_expose(ioc, element); | 6332 | if (!ioc->is_warpdrive) |
6333 | _scsih_sas_pd_expose(ioc, element); | ||
6248 | break; | 6334 | break; |
6249 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: | 6335 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: |
6250 | _scsih_sas_pd_add(ioc, element); | 6336 | if (!ioc->is_warpdrive) |
6337 | _scsih_sas_pd_add(ioc, element); | ||
6251 | break; | 6338 | break; |
6252 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: | 6339 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: |
6253 | _scsih_sas_pd_delete(ioc, element); | 6340 | if (!ioc->is_warpdrive) |
6341 | _scsih_sas_pd_delete(ioc, element); | ||
6254 | break; | 6342 | break; |
6255 | } | 6343 | } |
6256 | } | 6344 | } |
@@ -6285,10 +6373,11 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc, | |||
6285 | 6373 | ||
6286 | handle = le16_to_cpu(event_data->VolDevHandle); | 6374 | handle = le16_to_cpu(event_data->VolDevHandle); |
6287 | state = le32_to_cpu(event_data->NewValue); | 6375 | state = le32_to_cpu(event_data->NewValue); |
6288 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 6376 | if (!ioc->hide_ir_msg) |
6289 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", | 6377 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
6290 | ioc->name, __func__, handle, | 6378 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", |
6291 | le32_to_cpu(event_data->PreviousValue), state)); | 6379 | ioc->name, __func__, handle, |
6380 | le32_to_cpu(event_data->PreviousValue), state)); | ||
6292 | switch (state) { | 6381 | switch (state) { |
6293 | case MPI2_RAID_VOL_STATE_MISSING: | 6382 | case MPI2_RAID_VOL_STATE_MISSING: |
6294 | case MPI2_RAID_VOL_STATE_FAILED: | 6383 | case MPI2_RAID_VOL_STATE_FAILED: |
@@ -6371,10 +6460,12 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, | |||
6371 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); | 6460 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); |
6372 | state = le32_to_cpu(event_data->NewValue); | 6461 | state = le32_to_cpu(event_data->NewValue); |
6373 | 6462 | ||
6374 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 6463 | if (!ioc->hide_ir_msg) |
6375 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", | 6464 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
6376 | ioc->name, __func__, handle, | 6465 | "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", |
6466 | ioc->name, __func__, handle, | ||
6377 | le32_to_cpu(event_data->PreviousValue), state)); | 6467 | le32_to_cpu(event_data->PreviousValue), state)); |
6468 | |||
6378 | switch (state) { | 6469 | switch (state) { |
6379 | case MPI2_RAID_PD_STATE_ONLINE: | 6470 | case MPI2_RAID_PD_STATE_ONLINE: |
6380 | case MPI2_RAID_PD_STATE_DEGRADED: | 6471 | case MPI2_RAID_PD_STATE_DEGRADED: |
@@ -6382,7 +6473,8 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, | |||
6382 | case MPI2_RAID_PD_STATE_OPTIMAL: | 6473 | case MPI2_RAID_PD_STATE_OPTIMAL: |
6383 | case MPI2_RAID_PD_STATE_HOT_SPARE: | 6474 | case MPI2_RAID_PD_STATE_HOT_SPARE: |
6384 | 6475 | ||
6385 | set_bit(handle, ioc->pd_handles); | 6476 | if (!ioc->is_warpdrive) |
6477 | set_bit(handle, ioc->pd_handles); | ||
6386 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6478 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6387 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6479 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
6388 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 6480 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
@@ -6484,7 +6576,8 @@ _scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc, | |||
6484 | unsigned long flags; | 6576 | unsigned long flags; |
6485 | u16 handle; | 6577 | u16 handle; |
6486 | 6578 | ||
6487 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 6579 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && |
6580 | (!ioc->hide_ir_msg)) | ||
6488 | _scsih_sas_ir_operation_status_event_debug(ioc, | 6581 | _scsih_sas_ir_operation_status_event_debug(ioc, |
6489 | event_data); | 6582 | event_data); |
6490 | 6583 | ||
@@ -6655,7 +6748,7 @@ static void | |||
6655 | _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, | 6748 | _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, |
6656 | u16 handle) | 6749 | u16 handle) |
6657 | { | 6750 | { |
6658 | struct MPT3SAS_TARGET *sas_target_priv_data; | 6751 | struct MPT3SAS_TARGET *sas_target_priv_data = NULL; |
6659 | struct scsi_target *starget; | 6752 | struct scsi_target *starget; |
6660 | struct _raid_device *raid_device; | 6753 | struct _raid_device *raid_device; |
6661 | unsigned long flags; | 6754 | unsigned long flags; |
@@ -6674,6 +6767,15 @@ _scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, | |||
6674 | starget_printk(KERN_INFO, raid_device->starget, | 6767 | starget_printk(KERN_INFO, raid_device->starget, |
6675 | "handle(0x%04x), wwid(0x%016llx)\n", handle, | 6768 | "handle(0x%04x), wwid(0x%016llx)\n", handle, |
6676 | (unsigned long long)raid_device->wwid); | 6769 | (unsigned long long)raid_device->wwid); |
6770 | |||
6771 | #ifdef SCSI_MPT2SAS | ||
6772 | /* | ||
6773 | * WARPDRIVE: The handles of the PDs might have changed | ||
6774 | * across the host reset so re-initialize the | ||
6775 | * required data for Direct IO | ||
6776 | */ | ||
6777 | _scsih_init_warpdrive_properties(ioc, raid_device); | ||
6778 | #endif | ||
6677 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 6779 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
6678 | if (raid_device->handle == handle) { | 6780 | if (raid_device->handle == handle) { |
6679 | spin_unlock_irqrestore(&ioc->raid_device_lock, | 6781 | spin_unlock_irqrestore(&ioc->raid_device_lock, |
@@ -6743,6 +6845,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6743 | } | 6845 | } |
6744 | 6846 | ||
6745 | /* refresh the pd_handles */ | 6847 | /* refresh the pd_handles */ |
6848 | if (!ioc->is_warpdrive) { | ||
6746 | phys_disk_num = 0xFF; | 6849 | phys_disk_num = 0xFF; |
6747 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); | 6850 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); |
6748 | while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | 6851 | while (!(mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply, |
@@ -6756,6 +6859,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6756 | handle = le16_to_cpu(pd_pg0.DevHandle); | 6859 | handle = le16_to_cpu(pd_pg0.DevHandle); |
6757 | set_bit(handle, ioc->pd_handles); | 6860 | set_bit(handle, ioc->pd_handles); |
6758 | } | 6861 | } |
6862 | } | ||
6759 | out: | 6863 | out: |
6760 | pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n", | 6864 | pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n", |
6761 | ioc->name); | 6865 | ioc->name); |
@@ -7405,7 +7509,53 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, | |||
7405 | (Mpi2EventDataIrVolume_t *) | 7509 | (Mpi2EventDataIrVolume_t *) |
7406 | mpi_reply->EventData); | 7510 | mpi_reply->EventData); |
7407 | break; | 7511 | break; |
7512 | case MPI2_EVENT_LOG_ENTRY_ADDED: | ||
7513 | { | ||
7514 | Mpi2EventDataLogEntryAdded_t *log_entry; | ||
7515 | u32 *log_code; | ||
7516 | |||
7517 | if (!ioc->is_warpdrive) | ||
7518 | break; | ||
7519 | |||
7520 | log_entry = (Mpi2EventDataLogEntryAdded_t *) | ||
7521 | mpi_reply->EventData; | ||
7522 | log_code = (u32 *)log_entry->LogData; | ||
7408 | 7523 | ||
7524 | if (le16_to_cpu(log_entry->LogEntryQualifier) | ||
7525 | != MPT2_WARPDRIVE_LOGENTRY) | ||
7526 | break; | ||
7527 | |||
7528 | switch (le32_to_cpu(*log_code)) { | ||
7529 | case MPT2_WARPDRIVE_LC_SSDT: | ||
7530 | pr_warn(MPT3SAS_FMT "WarpDrive Warning: " | ||
7531 | "IO Throttling has occurred in the WarpDrive " | ||
7532 | "subsystem. Check WarpDrive documentation for " | ||
7533 | "additional details.\n", ioc->name); | ||
7534 | break; | ||
7535 | case MPT2_WARPDRIVE_LC_SSDLW: | ||
7536 | pr_warn(MPT3SAS_FMT "WarpDrive Warning: " | ||
7537 | "Program/Erase Cycles for the WarpDrive subsystem " | ||
7538 | "in degraded range. Check WarpDrive documentation " | ||
7539 | "for additional details.\n", ioc->name); | ||
7540 | break; | ||
7541 | case MPT2_WARPDRIVE_LC_SSDLF: | ||
7542 | pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " | ||
7543 | "There are no Program/Erase Cycles for the " | ||
7544 | "WarpDrive subsystem. The storage device will be " | ||
7545 | "in read-only mode. Check WarpDrive documentation " | ||
7546 | "for additional details.\n", ioc->name); | ||
7547 | break; | ||
7548 | case MPT2_WARPDRIVE_LC_BRMF: | ||
7549 | pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " | ||
7550 | "The Backup Rail Monitor has failed on the " | ||
7551 | "WarpDrive subsystem. Check WarpDrive " | ||
7552 | "documentation for additional details.\n", | ||
7553 | ioc->name); | ||
7554 | break; | ||
7555 | } | ||
7556 | |||
7557 | break; | ||
7558 | } | ||
7409 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | 7559 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: |
7410 | case MPI2_EVENT_IR_OPERATION_STATUS: | 7560 | case MPI2_EVENT_IR_OPERATION_STATUS: |
7411 | case MPI2_EVENT_SAS_DISCOVERY: | 7561 | case MPI2_EVENT_SAS_DISCOVERY: |
@@ -7535,7 +7685,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) | |||
7535 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; | 7685 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; |
7536 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; | 7686 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; |
7537 | 7687 | ||
7538 | pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); | 7688 | if (!ioc->hide_ir_msg) |
7689 | pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); | ||
7539 | init_completion(&ioc->scsih_cmds.done); | 7690 | init_completion(&ioc->scsih_cmds.done); |
7540 | mpt3sas_base_put_smid_default(ioc, smid); | 7691 | mpt3sas_base_put_smid_default(ioc, smid); |
7541 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | 7692 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); |
@@ -7548,10 +7699,11 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) | |||
7548 | 7699 | ||
7549 | if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { | 7700 | if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { |
7550 | mpi_reply = ioc->scsih_cmds.reply; | 7701 | mpi_reply = ioc->scsih_cmds.reply; |
7551 | pr_info(MPT3SAS_FMT | 7702 | if (!ioc->hide_ir_msg) |
7552 | "IR shutdown (complete): ioc_status(0x%04x), loginfo(0x%08x)\n", | 7703 | pr_info(MPT3SAS_FMT "IR shutdown " |
7553 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), | 7704 | "(complete): ioc_status(0x%04x), loginfo(0x%08x)\n", |
7554 | le32_to_cpu(mpi_reply->IOCLogInfo)); | 7705 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), |
7706 | le32_to_cpu(mpi_reply->IOCLogInfo)); | ||
7555 | } | 7707 | } |
7556 | 7708 | ||
7557 | out: | 7709 | out: |
@@ -7716,6 +7868,8 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) | |||
7716 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 7868 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
7717 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7869 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
7718 | 7870 | ||
7871 | if (ioc->hide_drives) | ||
7872 | return; | ||
7719 | if (!mpt3sas_transport_port_add(ioc, handle, | 7873 | if (!mpt3sas_transport_port_add(ioc, handle, |
7720 | sas_address_parent)) { | 7874 | sas_address_parent)) { |
7721 | _scsih_sas_device_remove(ioc, sas_device); | 7875 | _scsih_sas_device_remove(ioc, sas_device); |
@@ -7769,6 +7923,9 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) | |||
7769 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, | 7923 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, |
7770 | list) { | 7924 | list) { |
7771 | 7925 | ||
7926 | if (ioc->hide_drives) | ||
7927 | return; | ||
7928 | |||
7772 | if (!mpt3sas_transport_port_add(ioc, sas_device->handle, | 7929 | if (!mpt3sas_transport_port_add(ioc, sas_device->handle, |
7773 | sas_device->sas_address_parent)) { | 7930 | sas_device->sas_address_parent)) { |
7774 | list_del(&sas_device->list); | 7931 | list_del(&sas_device->list); |
@@ -7913,6 +8070,9 @@ void | |||
7913 | _scsih_determine_hba_mpi_version(struct MPT3SAS_ADAPTER *ioc) { | 8070 | _scsih_determine_hba_mpi_version(struct MPT3SAS_ADAPTER *ioc) { |
7914 | 8071 | ||
7915 | switch (ioc->pdev->device) { | 8072 | switch (ioc->pdev->device) { |
8073 | case MPI2_MFGPAGE_DEVID_SSS6200: | ||
8074 | ioc->is_warpdrive = 1; | ||
8075 | ioc->hide_ir_msg = 1; | ||
7916 | case MPI2_MFGPAGE_DEVID_SAS2004: | 8076 | case MPI2_MFGPAGE_DEVID_SAS2004: |
7917 | case MPI2_MFGPAGE_DEVID_SAS2008: | 8077 | case MPI2_MFGPAGE_DEVID_SAS2008: |
7918 | case MPI2_MFGPAGE_DEVID_SAS2108_1: | 8078 | case MPI2_MFGPAGE_DEVID_SAS2108_1: |
@@ -7947,6 +8107,10 @@ _scsih_determine_hba_mpi_version(struct MPT3SAS_ADAPTER *ioc) { | |||
7947 | ioc->msix96_vector = 1; | 8107 | ioc->msix96_vector = 1; |
7948 | break; | 8108 | break; |
7949 | } | 8109 | } |
8110 | |||
8111 | if ((ioc->pdev->device != MPI2_MFGPAGE_DEVID_SSS6200) && | ||
8112 | (ioc->hba_mpi_version_belonged == MPI2_VERSION)) | ||
8113 | ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; | ||
7950 | } | 8114 | } |
7951 | 8115 | ||
7952 | /** | 8116 | /** |
@@ -7969,7 +8133,6 @@ scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost) | |||
7969 | list_add_tail(&ioc->list, &mpt3sas_ioc_list); | 8133 | list_add_tail(&ioc->list, &mpt3sas_ioc_list); |
7970 | ioc->shost = shost; | 8134 | ioc->shost = shost; |
7971 | ioc->id = mpt_ids++; | 8135 | ioc->id = mpt_ids++; |
7972 | |||
7973 | ioc->pdev = pdev; | 8136 | ioc->pdev = pdev; |
7974 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; | 8137 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; |
7975 | ioc->tm_cb_idx = tm_cb_idx; | 8138 | ioc->tm_cb_idx = tm_cb_idx; |
@@ -8062,6 +8225,23 @@ scsih_probe(struct pci_dev *pdev, struct Scsi_Host *shost) | |||
8062 | rv = -ENODEV; | 8225 | rv = -ENODEV; |
8063 | goto out_attach_fail; | 8226 | goto out_attach_fail; |
8064 | } | 8227 | } |
8228 | |||
8229 | #ifdef SCSI_MPT2SAS | ||
8230 | if (ioc->is_warpdrive) { | ||
8231 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) | ||
8232 | ioc->hide_drives = 0; | ||
8233 | else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS) | ||
8234 | ioc->hide_drives = 1; | ||
8235 | else { | ||
8236 | if (_scsih_get_num_volumes(ioc)) | ||
8237 | ioc->hide_drives = 1; | ||
8238 | else | ||
8239 | ioc->hide_drives = 0; | ||
8240 | } | ||
8241 | } else | ||
8242 | ioc->hide_drives = 0; | ||
8243 | #endif | ||
8244 | |||
8065 | rv = scsi_add_host(shost, &pdev->dev); | 8245 | rv = scsi_add_host(shost, &pdev->dev); |
8066 | if (rv) { | 8246 | if (rv) { |
8067 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 8247 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
@@ -8334,3 +8514,7 @@ scsih_exit(void) | |||
8334 | raid_class_release(mpt3sas_raid_template); | 8514 | raid_class_release(mpt3sas_raid_template); |
8335 | sas_release_transport(mpt3sas_transport_template); | 8515 | sas_release_transport(mpt3sas_transport_template); |
8336 | } | 8516 | } |
8517 | |||
8518 | #ifdef SCSI_MPT2SAS | ||
8519 | #include "../mpt2sas/mpt2sas_warpdrive.c" | ||
8520 | #endif | ||