This source file includes following definitions.
- _mpt3sas_raise_sigio
- mpt3sas_process_trigger_data
- mpt3sas_trigger_master
- mpt3sas_trigger_event
- mpt3sas_trigger_scsi
- mpt3sas_trigger_mpi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 #include <linux/kernel.h>
47 #include <linux/module.h>
48 #include <linux/errno.h>
49 #include <linux/init.h>
50 #include <linux/slab.h>
51 #include <linux/types.h>
52 #include <linux/pci.h>
53 #include <linux/delay.h>
54 #include <linux/compat.h>
55 #include <linux/poll.h>
56
57 #include <linux/io.h>
58 #include <linux/uaccess.h>
59
60 #include "mpt3sas_base.h"
61
62
63
64
65
66
67 static void
68 _mpt3sas_raise_sigio(struct MPT3SAS_ADAPTER *ioc,
69 struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data)
70 {
71 Mpi2EventNotificationReply_t *mpi_reply;
72 u16 sz, event_data_sz;
73 unsigned long flags;
74
75 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: enter\n", __func__));
76
77 sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
78 sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4;
79 mpi_reply = kzalloc(sz, GFP_KERNEL);
80 if (!mpi_reply)
81 goto out;
82 mpi_reply->Event = cpu_to_le16(MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED);
83 event_data_sz = (sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4) / 4;
84 mpi_reply->EventDataLength = cpu_to_le16(event_data_sz);
85 memcpy(&mpi_reply->EventData, event_data,
86 sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
87 dTriggerDiagPrintk(ioc,
88 ioc_info(ioc, "%s: add to driver event log\n",
89 __func__));
90 mpt3sas_ctl_add_to_event_log(ioc, mpi_reply);
91 kfree(mpi_reply);
92 out:
93
94
95 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
96 dTriggerDiagPrintk(ioc,
97 ioc_info(ioc, "%s: clearing diag_trigger_active flag\n",
98 __func__));
99 ioc->diag_trigger_active = 0;
100 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
101
102 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
103 __func__));
104 }
105
106
107
108
109
110
111 void
112 mpt3sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc,
113 struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data)
114 {
115 u8 issue_reset = 0;
116
117 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: enter\n", __func__));
118
119
120 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
121 MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {
122 dTriggerDiagPrintk(ioc,
123 ioc_info(ioc, "%s: release trace diag buffer\n",
124 __func__));
125 mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,
126 &issue_reset);
127 }
128
129 _mpt3sas_raise_sigio(ioc, event_data);
130
131 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
132 __func__));
133 }
134
135
136
137
138
139
140
141 void
142 mpt3sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, u32 trigger_bitmask)
143 {
144 struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
145 unsigned long flags;
146 u8 found_match = 0;
147
148 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
149
150 if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
151 trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET)
152 goto by_pass_checks;
153
154
155 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
156 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
157 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
158 return;
159 }
160
161
162 if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
163 MPT3_DIAG_BUFFER_IS_RELEASED) {
164 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
165 return;
166 }
167
168 by_pass_checks:
169
170 dTriggerDiagPrintk(ioc,
171 ioc_info(ioc, "%s: enter - trigger_bitmask = 0x%08x\n",
172 __func__, trigger_bitmask));
173
174
175 if (ioc->diag_trigger_active) {
176 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
177 goto out;
178 }
179
180
181 if (ioc->diag_trigger_master.MasterData & trigger_bitmask) {
182 found_match = 1;
183 ioc->diag_trigger_active = 1;
184 dTriggerDiagPrintk(ioc,
185 ioc_info(ioc, "%s: setting diag_trigger_active flag\n",
186 __func__));
187 }
188 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
189
190 if (!found_match)
191 goto out;
192
193 memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
194 event_data.trigger_type = MPT3SAS_TRIGGER_MASTER;
195 event_data.u.master.MasterData = trigger_bitmask;
196
197 if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
198 trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET)
199 _mpt3sas_raise_sigio(ioc, &event_data);
200 else
201 mpt3sas_send_trigger_data_event(ioc, &event_data);
202
203 out:
204 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
205 __func__));
206 }
207
208
209
210
211
212
213
214
215 void
216 mpt3sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event,
217 u16 log_entry_qualifier)
218 {
219 struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
220 struct SL_WH_EVENT_TRIGGER_T *event_trigger;
221 int i;
222 unsigned long flags;
223 u8 found_match;
224
225 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
226
227
228 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
229 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
230 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
231 return;
232 }
233
234
235 if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
236 MPT3_DIAG_BUFFER_IS_RELEASED) {
237 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
238 return;
239 }
240
241 dTriggerDiagPrintk(ioc,
242 ioc_info(ioc, "%s: enter - event = 0x%04x, log_entry_qualifier = 0x%04x\n",
243 __func__, event, log_entry_qualifier));
244
245
246 if (ioc->diag_trigger_active) {
247 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
248 goto out;
249 }
250
251
252 event_trigger = ioc->diag_trigger_event.EventTriggerEntry;
253 for (i = 0 , found_match = 0; i < ioc->diag_trigger_event.ValidEntries
254 && !found_match; i++, event_trigger++) {
255 if (event_trigger->EventValue != event)
256 continue;
257 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
258 if (event_trigger->LogEntryQualifier ==
259 log_entry_qualifier)
260 found_match = 1;
261 continue;
262 }
263 found_match = 1;
264 ioc->diag_trigger_active = 1;
265 dTriggerDiagPrintk(ioc,
266 ioc_info(ioc, "%s: setting diag_trigger_active flag\n",
267 __func__));
268 }
269 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
270
271 if (!found_match)
272 goto out;
273
274 dTriggerDiagPrintk(ioc,
275 ioc_info(ioc, "%s: setting diag_trigger_active flag\n",
276 __func__));
277 memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
278 event_data.trigger_type = MPT3SAS_TRIGGER_EVENT;
279 event_data.u.event.EventValue = event;
280 event_data.u.event.LogEntryQualifier = log_entry_qualifier;
281 mpt3sas_send_trigger_data_event(ioc, &event_data);
282 out:
283 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
284 __func__));
285 }
286
287
288
289
290
291
292
293
294
295 void
296 mpt3sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, u8 asc,
297 u8 ascq)
298 {
299 struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
300 struct SL_WH_SCSI_TRIGGER_T *scsi_trigger;
301 int i;
302 unsigned long flags;
303 u8 found_match;
304
305 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
306
307
308 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
309 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
310 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
311 return;
312 }
313
314
315 if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
316 MPT3_DIAG_BUFFER_IS_RELEASED) {
317 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
318 return;
319 }
320
321 dTriggerDiagPrintk(ioc,
322 ioc_info(ioc, "%s: enter - sense_key = 0x%02x, asc = 0x%02x, ascq = 0x%02x\n",
323 __func__, sense_key, asc, ascq));
324
325
326 if (ioc->diag_trigger_active) {
327 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
328 goto out;
329 }
330
331
332 scsi_trigger = ioc->diag_trigger_scsi.SCSITriggerEntry;
333 for (i = 0 , found_match = 0; i < ioc->diag_trigger_scsi.ValidEntries
334 && !found_match; i++, scsi_trigger++) {
335 if (scsi_trigger->SenseKey != sense_key)
336 continue;
337 if (!(scsi_trigger->ASC == 0xFF || scsi_trigger->ASC == asc))
338 continue;
339 if (!(scsi_trigger->ASCQ == 0xFF || scsi_trigger->ASCQ == ascq))
340 continue;
341 found_match = 1;
342 ioc->diag_trigger_active = 1;
343 }
344 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
345
346 if (!found_match)
347 goto out;
348
349 dTriggerDiagPrintk(ioc,
350 ioc_info(ioc, "%s: setting diag_trigger_active flag\n",
351 __func__));
352 memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
353 event_data.trigger_type = MPT3SAS_TRIGGER_SCSI;
354 event_data.u.scsi.SenseKey = sense_key;
355 event_data.u.scsi.ASC = asc;
356 event_data.u.scsi.ASCQ = ascq;
357 mpt3sas_send_trigger_data_event(ioc, &event_data);
358 out:
359 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
360 __func__));
361 }
362
363
364
365
366
367
368
369
370 void
371 mpt3sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status, u32 loginfo)
372 {
373 struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
374 struct SL_WH_MPI_TRIGGER_T *mpi_trigger;
375 int i;
376 unsigned long flags;
377 u8 found_match;
378
379 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
380
381
382 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
383 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
384 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
385 return;
386 }
387
388
389 if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
390 MPT3_DIAG_BUFFER_IS_RELEASED) {
391 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
392 return;
393 }
394
395 dTriggerDiagPrintk(ioc,
396 ioc_info(ioc, "%s: enter - ioc_status = 0x%04x, loginfo = 0x%08x\n",
397 __func__, ioc_status, loginfo));
398
399
400 if (ioc->diag_trigger_active) {
401 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
402 goto out;
403 }
404
405
406 mpi_trigger = ioc->diag_trigger_mpi.MPITriggerEntry;
407 for (i = 0 , found_match = 0; i < ioc->diag_trigger_mpi.ValidEntries
408 && !found_match; i++, mpi_trigger++) {
409 if (mpi_trigger->IOCStatus != ioc_status)
410 continue;
411 if (!(mpi_trigger->IocLogInfo == 0xFFFFFFFF ||
412 mpi_trigger->IocLogInfo == loginfo))
413 continue;
414 found_match = 1;
415 ioc->diag_trigger_active = 1;
416 }
417 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
418
419 if (!found_match)
420 goto out;
421
422 dTriggerDiagPrintk(ioc,
423 ioc_info(ioc, "%s: setting diag_trigger_active flag\n",
424 __func__));
425 memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
426 event_data.trigger_type = MPT3SAS_TRIGGER_MPI;
427 event_data.u.mpi.IOCStatus = ioc_status;
428 event_data.u.mpi.IocLogInfo = loginfo;
429 mpt3sas_send_trigger_data_event(ioc, &event_data);
430 out:
431 dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: exit\n",
432 __func__));
433 }