Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/message/fusion/mptscsih.c
15109 views
1
/*
2
* linux/drivers/message/fusion/mptscsih.c
3
* For use with LSI PCI chip/adapter(s)
4
* running LSI Fusion MPT (Message Passing Technology) firmware.
5
*
6
* Copyright (c) 1999-2008 LSI Corporation
7
* (mailto:[email protected])
8
*
9
*/
10
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11
/*
12
This program is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; version 2 of the License.
15
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
GNU General Public License for more details.
20
21
NO WARRANTY
22
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26
solely responsible for determining the appropriateness of using and
27
distributing the Program and assumes all risks associated with its
28
exercise of rights under this Agreement, including but not limited to
29
the risks and costs of program errors, damage to or loss of data,
30
programs or equipment, and unavailability or interruption of operations.
31
32
DISCLAIMER OF LIABILITY
33
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41
You should have received a copy of the GNU General Public License
42
along with this program; if not, write to the Free Software
43
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44
*/
45
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47
#include <linux/module.h>
48
#include <linux/kernel.h>
49
#include <linux/slab.h>
50
#include <linux/init.h>
51
#include <linux/errno.h>
52
#include <linux/kdev_t.h>
53
#include <linux/blkdev.h>
54
#include <linux/delay.h> /* for mdelay */
55
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
56
#include <linux/reboot.h> /* notifier code */
57
#include <linux/workqueue.h>
58
59
#include <scsi/scsi.h>
60
#include <scsi/scsi_cmnd.h>
61
#include <scsi/scsi_device.h>
62
#include <scsi/scsi_host.h>
63
#include <scsi/scsi_tcq.h>
64
#include <scsi/scsi_dbg.h>
65
66
#include "mptbase.h"
67
#include "mptscsih.h"
68
#include "lsi/mpi_log_sas.h"
69
70
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71
#define my_NAME "Fusion MPT SCSI Host driver"
72
#define my_VERSION MPT_LINUX_VERSION_COMMON
73
#define MYNAM "mptscsih"
74
75
MODULE_AUTHOR(MODULEAUTHOR);
76
MODULE_DESCRIPTION(my_NAME);
77
MODULE_LICENSE("GPL");
78
MODULE_VERSION(my_VERSION);
79
80
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
81
/*
82
* Other private/forward protos...
83
*/
84
struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
85
static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
86
static void mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
87
static int SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
88
int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
89
static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
90
int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
91
92
static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
93
SCSIIORequest_t *pReq, int req_idx);
94
static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
95
static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
96
97
int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
98
int lun, int ctx2abort, ulong timeout);
99
100
int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
101
int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
102
103
void
104
mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
105
static int mptscsih_get_completion_code(MPT_ADAPTER *ioc,
106
MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
107
int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
108
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
109
static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
110
111
static int
112
mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
113
SCSITaskMgmtReply_t *pScsiTmReply);
114
void mptscsih_remove(struct pci_dev *);
115
void mptscsih_shutdown(struct pci_dev *);
116
#ifdef CONFIG_PM
117
int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
118
int mptscsih_resume(struct pci_dev *pdev);
119
#endif
120
121
#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE
122
123
124
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125
/*
126
* mptscsih_getFreeChainBuffer - Function to get a free chain
127
* from the MPT_SCSI_HOST FreeChainQ.
128
* @ioc: Pointer to MPT_ADAPTER structure
129
* @req_idx: Index of the SCSI IO request frame. (output)
130
*
131
* return SUCCESS or FAILED
132
*/
133
static inline int
134
mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
135
{
136
MPT_FRAME_HDR *chainBuf;
137
unsigned long flags;
138
int rc;
139
int chain_idx;
140
141
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
142
ioc->name));
143
spin_lock_irqsave(&ioc->FreeQlock, flags);
144
if (!list_empty(&ioc->FreeChainQ)) {
145
int offset;
146
147
chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
148
u.frame.linkage.list);
149
list_del(&chainBuf->u.frame.linkage.list);
150
offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
151
chain_idx = offset / ioc->req_sz;
152
rc = SUCCESS;
153
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
154
"getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
155
ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
156
} else {
157
rc = FAILED;
158
chain_idx = MPT_HOST_NO_CHAIN;
159
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
160
ioc->name));
161
}
162
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
163
164
*retIndex = chain_idx;
165
return rc;
166
} /* mptscsih_getFreeChainBuffer() */
167
168
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
169
/*
170
* mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
171
* SCSIIORequest_t Message Frame.
172
* @ioc: Pointer to MPT_ADAPTER structure
173
* @SCpnt: Pointer to scsi_cmnd structure
174
* @pReq: Pointer to SCSIIORequest_t structure
175
*
176
* Returns ...
177
*/
178
static int
179
mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
180
SCSIIORequest_t *pReq, int req_idx)
181
{
182
char *psge;
183
char *chainSge;
184
struct scatterlist *sg;
185
int frm_sz;
186
int sges_left, sg_done;
187
int chain_idx = MPT_HOST_NO_CHAIN;
188
int sgeOffset;
189
int numSgeSlots, numSgeThisFrame;
190
u32 sgflags, sgdir, thisxfer = 0;
191
int chain_dma_off = 0;
192
int newIndex;
193
int ii;
194
dma_addr_t v2;
195
u32 RequestNB;
196
197
sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
198
if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
199
sgdir = MPT_TRANSFER_HOST_TO_IOC;
200
} else {
201
sgdir = MPT_TRANSFER_IOC_TO_HOST;
202
}
203
204
psge = (char *) &pReq->SGL;
205
frm_sz = ioc->req_sz;
206
207
/* Map the data portion, if any.
208
* sges_left = 0 if no data transfer.
209
*/
210
sges_left = scsi_dma_map(SCpnt);
211
if (sges_left < 0)
212
return FAILED;
213
214
/* Handle the SG case.
215
*/
216
sg = scsi_sglist(SCpnt);
217
sg_done = 0;
218
sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
219
chainSge = NULL;
220
221
/* Prior to entering this loop - the following must be set
222
* current MF: sgeOffset (bytes)
223
* chainSge (Null if original MF is not a chain buffer)
224
* sg_done (num SGE done for this MF)
225
*/
226
227
nextSGEset:
228
numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
229
numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
230
231
sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
232
233
/* Get first (num - 1) SG elements
234
* Skip any SG entries with a length of 0
235
* NOTE: at finish, sg and psge pointed to NEXT data/location positions
236
*/
237
for (ii=0; ii < (numSgeThisFrame-1); ii++) {
238
thisxfer = sg_dma_len(sg);
239
if (thisxfer == 0) {
240
/* Get next SG element from the OS */
241
sg = sg_next(sg);
242
sg_done++;
243
continue;
244
}
245
246
v2 = sg_dma_address(sg);
247
ioc->add_sge(psge, sgflags | thisxfer, v2);
248
249
/* Get next SG element from the OS */
250
sg = sg_next(sg);
251
psge += ioc->SGE_size;
252
sgeOffset += ioc->SGE_size;
253
sg_done++;
254
}
255
256
if (numSgeThisFrame == sges_left) {
257
/* Add last element, end of buffer and end of list flags.
258
*/
259
sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
260
MPT_SGE_FLAGS_END_OF_BUFFER |
261
MPT_SGE_FLAGS_END_OF_LIST;
262
263
/* Add last SGE and set termination flags.
264
* Note: Last SGE may have a length of 0 - which should be ok.
265
*/
266
thisxfer = sg_dma_len(sg);
267
268
v2 = sg_dma_address(sg);
269
ioc->add_sge(psge, sgflags | thisxfer, v2);
270
sgeOffset += ioc->SGE_size;
271
sg_done++;
272
273
if (chainSge) {
274
/* The current buffer is a chain buffer,
275
* but there is not another one.
276
* Update the chain element
277
* Offset and Length fields.
278
*/
279
ioc->add_chain((char *)chainSge, 0, sgeOffset,
280
ioc->ChainBufferDMA + chain_dma_off);
281
} else {
282
/* The current buffer is the original MF
283
* and there is no Chain buffer.
284
*/
285
pReq->ChainOffset = 0;
286
RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
287
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
288
"Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
289
ioc->RequestNB[req_idx] = RequestNB;
290
}
291
} else {
292
/* At least one chain buffer is needed.
293
* Complete the first MF
294
* - last SGE element, set the LastElement bit
295
* - set ChainOffset (words) for orig MF
296
* (OR finish previous MF chain buffer)
297
* - update MFStructPtr ChainIndex
298
* - Populate chain element
299
* Also
300
* Loop until done.
301
*/
302
303
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
304
ioc->name, sg_done));
305
306
/* Set LAST_ELEMENT flag for last non-chain element
307
* in the buffer. Since psge points at the NEXT
308
* SGE element, go back one SGE element, update the flags
309
* and reset the pointer. (Note: sgflags & thisxfer are already
310
* set properly).
311
*/
312
if (sg_done) {
313
u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
314
sgflags = le32_to_cpu(*ptmp);
315
sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
316
*ptmp = cpu_to_le32(sgflags);
317
}
318
319
if (chainSge) {
320
/* The current buffer is a chain buffer.
321
* chainSge points to the previous Chain Element.
322
* Update its chain element Offset and Length (must
323
* include chain element size) fields.
324
* Old chain element is now complete.
325
*/
326
u8 nextChain = (u8) (sgeOffset >> 2);
327
sgeOffset += ioc->SGE_size;
328
ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
329
ioc->ChainBufferDMA + chain_dma_off);
330
} else {
331
/* The original MF buffer requires a chain buffer -
332
* set the offset.
333
* Last element in this MF is a chain element.
334
*/
335
pReq->ChainOffset = (u8) (sgeOffset >> 2);
336
RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
337
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
338
ioc->RequestNB[req_idx] = RequestNB;
339
}
340
341
sges_left -= sg_done;
342
343
344
/* NOTE: psge points to the beginning of the chain element
345
* in current buffer. Get a chain buffer.
346
*/
347
if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
348
dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
349
"getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
350
ioc->name, pReq->CDB[0], SCpnt));
351
return FAILED;
352
}
353
354
/* Update the tracking arrays.
355
* If chainSge == NULL, update ReqToChain, else ChainToChain
356
*/
357
if (chainSge) {
358
ioc->ChainToChain[chain_idx] = newIndex;
359
} else {
360
ioc->ReqToChain[req_idx] = newIndex;
361
}
362
chain_idx = newIndex;
363
chain_dma_off = ioc->req_sz * chain_idx;
364
365
/* Populate the chainSGE for the current buffer.
366
* - Set chain buffer pointer to psge and fill
367
* out the Address and Flags fields.
368
*/
369
chainSge = (char *) psge;
370
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Current buff @ %p (index 0x%x)",
371
ioc->name, psge, req_idx));
372
373
/* Start the SGE for the next buffer
374
*/
375
psge = (char *) (ioc->ChainBuffer + chain_dma_off);
376
sgeOffset = 0;
377
sg_done = 0;
378
379
dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Chain buff @ %p (index 0x%x)\n",
380
ioc->name, psge, chain_idx));
381
382
/* Start the SGE for the next buffer
383
*/
384
385
goto nextSGEset;
386
}
387
388
return SUCCESS;
389
} /* mptscsih_AddSGE() */
390
391
static void
392
mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
393
U32 SlotStatus)
394
{
395
MPT_FRAME_HDR *mf;
396
SEPRequest_t *SEPMsg;
397
398
if (ioc->bus_type != SAS)
399
return;
400
401
/* Not supported for hidden raid components
402
*/
403
if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
404
return;
405
406
if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
407
dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
408
ioc->name,__func__));
409
return;
410
}
411
412
SEPMsg = (SEPRequest_t *)mf;
413
SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
414
SEPMsg->Bus = vtarget->channel;
415
SEPMsg->TargetID = vtarget->id;
416
SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
417
SEPMsg->SlotStatus = SlotStatus;
418
devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
419
"Sending SEP cmd=%x channel=%d id=%d\n",
420
ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
421
mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
422
}
423
424
#ifdef CONFIG_FUSION_LOGGING
425
/**
426
* mptscsih_info_scsiio - debug print info on reply frame
427
* @ioc: Pointer to MPT_ADAPTER structure
428
* @sc: original scsi cmnd pointer
429
* @pScsiReply: Pointer to MPT reply frame
430
*
431
* MPT_DEBUG_REPLY needs to be enabled to obtain this info
432
*
433
* Refer to lsi/mpi.h.
434
**/
435
static void
436
mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
437
{
438
char *desc = NULL;
439
char *desc1 = NULL;
440
u16 ioc_status;
441
u8 skey, asc, ascq;
442
443
ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
444
445
switch (ioc_status) {
446
447
case MPI_IOCSTATUS_SUCCESS:
448
desc = "success";
449
break;
450
case MPI_IOCSTATUS_SCSI_INVALID_BUS:
451
desc = "invalid bus";
452
break;
453
case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
454
desc = "invalid target_id";
455
break;
456
case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
457
desc = "device not there";
458
break;
459
case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
460
desc = "data overrun";
461
break;
462
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
463
desc = "data underrun";
464
break;
465
case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
466
desc = "I/O data error";
467
break;
468
case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
469
desc = "protocol error";
470
break;
471
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
472
desc = "task terminated";
473
break;
474
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
475
desc = "residual mismatch";
476
break;
477
case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
478
desc = "task management failed";
479
break;
480
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
481
desc = "IOC terminated";
482
break;
483
case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
484
desc = "ext terminated";
485
break;
486
default:
487
desc = "";
488
break;
489
}
490
491
switch (pScsiReply->SCSIStatus)
492
{
493
494
case MPI_SCSI_STATUS_SUCCESS:
495
desc1 = "success";
496
break;
497
case MPI_SCSI_STATUS_CHECK_CONDITION:
498
desc1 = "check condition";
499
break;
500
case MPI_SCSI_STATUS_CONDITION_MET:
501
desc1 = "condition met";
502
break;
503
case MPI_SCSI_STATUS_BUSY:
504
desc1 = "busy";
505
break;
506
case MPI_SCSI_STATUS_INTERMEDIATE:
507
desc1 = "intermediate";
508
break;
509
case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
510
desc1 = "intermediate condmet";
511
break;
512
case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
513
desc1 = "reservation conflict";
514
break;
515
case MPI_SCSI_STATUS_COMMAND_TERMINATED:
516
desc1 = "command terminated";
517
break;
518
case MPI_SCSI_STATUS_TASK_SET_FULL:
519
desc1 = "task set full";
520
break;
521
case MPI_SCSI_STATUS_ACA_ACTIVE:
522
desc1 = "aca active";
523
break;
524
case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
525
desc1 = "fcpext device logged out";
526
break;
527
case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
528
desc1 = "fcpext no link";
529
break;
530
case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
531
desc1 = "fcpext unassigned";
532
break;
533
default:
534
desc1 = "";
535
break;
536
}
537
538
scsi_print_command(sc);
539
printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %d\n",
540
ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
541
printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
542
"resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
543
scsi_get_resid(sc));
544
printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
545
"sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
546
le32_to_cpu(pScsiReply->TransferCount), sc->result);
547
548
printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
549
"scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
550
ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
551
pScsiReply->SCSIState);
552
553
if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
554
skey = sc->sense_buffer[2] & 0x0F;
555
asc = sc->sense_buffer[12];
556
ascq = sc->sense_buffer[13];
557
558
printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
559
"[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
560
}
561
562
/*
563
* Look for + dump FCP ResponseInfo[]!
564
*/
565
if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
566
pScsiReply->ResponseInfo)
567
printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
568
ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
569
}
570
#endif
571
572
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
573
/*
574
* mptscsih_io_done - Main SCSI IO callback routine registered to
575
* Fusion MPT (base) driver
576
* @ioc: Pointer to MPT_ADAPTER structure
577
* @mf: Pointer to original MPT request frame
578
* @r: Pointer to MPT reply frame (NULL if TurboReply)
579
*
580
* This routine is called from mpt.c::mpt_interrupt() at the completion
581
* of any SCSI IO request.
582
* This routine is registered with the Fusion MPT (base) driver at driver
583
* load/init time via the mpt_register() API call.
584
*
585
* Returns 1 indicating alloc'd request frame ptr should be freed.
586
*/
587
int
588
mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
589
{
590
struct scsi_cmnd *sc;
591
MPT_SCSI_HOST *hd;
592
SCSIIORequest_t *pScsiReq;
593
SCSIIOReply_t *pScsiReply;
594
u16 req_idx, req_idx_MR;
595
VirtDevice *vdevice;
596
VirtTarget *vtarget;
597
598
hd = shost_priv(ioc->sh);
599
req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
600
req_idx_MR = (mr != NULL) ?
601
le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
602
603
/* Special case, where already freed message frame is received from
604
* Firmware. It happens with Resetting IOC.
605
* Return immediately. Do not care
606
*/
607
if ((req_idx != req_idx_MR) ||
608
(le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
609
return 0;
610
611
sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
612
if (sc == NULL) {
613
MPIHeader_t *hdr = (MPIHeader_t *)mf;
614
615
/* Remark: writeSDP1 will use the ScsiDoneCtx
616
* If a SCSI I/O cmd, device disabled by OS and
617
* completion done. Cannot touch sc struct. Just free mem.
618
*/
619
if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
620
printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
621
ioc->name);
622
623
mptscsih_freeChainBuffers(ioc, req_idx);
624
return 1;
625
}
626
627
if ((unsigned char *)mf != sc->host_scribble) {
628
mptscsih_freeChainBuffers(ioc, req_idx);
629
return 1;
630
}
631
632
if (ioc->bus_type == SAS) {
633
VirtDevice *vdevice = sc->device->hostdata;
634
635
if (!vdevice || !vdevice->vtarget ||
636
vdevice->vtarget->deleted) {
637
sc->result = DID_NO_CONNECT << 16;
638
goto out;
639
}
640
}
641
642
sc->host_scribble = NULL;
643
sc->result = DID_OK << 16; /* Set default reply as OK */
644
pScsiReq = (SCSIIORequest_t *) mf;
645
pScsiReply = (SCSIIOReply_t *) mr;
646
647
if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
648
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
649
"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
650
ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
651
}else{
652
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
653
"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
654
ioc->name, mf, mr, sc, req_idx));
655
}
656
657
if (pScsiReply == NULL) {
658
/* special context reply handling */
659
;
660
} else {
661
u32 xfer_cnt;
662
u16 status;
663
u8 scsi_state, scsi_status;
664
u32 log_info;
665
666
status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
667
668
scsi_state = pScsiReply->SCSIState;
669
scsi_status = pScsiReply->SCSIStatus;
670
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
671
scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
672
log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
673
674
/*
675
* if we get a data underrun indication, yet no data was
676
* transferred and the SCSI status indicates that the
677
* command was never started, change the data underrun
678
* to success
679
*/
680
if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
681
(scsi_status == MPI_SCSI_STATUS_BUSY ||
682
scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
683
scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
684
status = MPI_IOCSTATUS_SUCCESS;
685
}
686
687
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
688
mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
689
690
/*
691
* Look for + dump FCP ResponseInfo[]!
692
*/
693
if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
694
pScsiReply->ResponseInfo) {
695
printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] "
696
"FCP_ResponseInfo=%08xh\n", ioc->name,
697
sc->device->host->host_no, sc->device->channel,
698
sc->device->id, sc->device->lun,
699
le32_to_cpu(pScsiReply->ResponseInfo));
700
}
701
702
switch(status) {
703
case MPI_IOCSTATUS_BUSY: /* 0x0002 */
704
case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
705
/* CHECKME!
706
* Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
707
* But not: DID_BUS_BUSY lest one risk
708
* killing interrupt handler:-(
709
*/
710
sc->result = SAM_STAT_BUSY;
711
break;
712
713
case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
714
case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
715
sc->result = DID_BAD_TARGET << 16;
716
break;
717
718
case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
719
/* Spoof to SCSI Selection Timeout! */
720
if (ioc->bus_type != FC)
721
sc->result = DID_NO_CONNECT << 16;
722
/* else fibre, just stall until rescan event */
723
else
724
sc->result = DID_REQUEUE << 16;
725
726
if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
727
hd->sel_timeout[pScsiReq->TargetID]++;
728
729
vdevice = sc->device->hostdata;
730
if (!vdevice)
731
break;
732
vtarget = vdevice->vtarget;
733
if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
734
mptscsih_issue_sep_command(ioc, vtarget,
735
MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
736
vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
737
}
738
break;
739
740
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
741
if ( ioc->bus_type == SAS ) {
742
u16 ioc_status =
743
le16_to_cpu(pScsiReply->IOCStatus);
744
if ((ioc_status &
745
MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
746
&&
747
((log_info & SAS_LOGINFO_MASK) ==
748
SAS_LOGINFO_NEXUS_LOSS)) {
749
VirtDevice *vdevice =
750
sc->device->hostdata;
751
752
/* flag the device as being in
753
* device removal delay so we can
754
* notify the midlayer to hold off
755
* on timeout eh */
756
if (vdevice && vdevice->
757
vtarget &&
758
vdevice->vtarget->
759
raidVolume)
760
printk(KERN_INFO
761
"Skipping Raid Volume"
762
"for inDMD\n");
763
else if (vdevice &&
764
vdevice->vtarget)
765
vdevice->vtarget->
766
inDMD = 1;
767
768
sc->result =
769
(DID_TRANSPORT_DISRUPTED
770
<< 16);
771
break;
772
}
773
} else if (ioc->bus_type == FC) {
774
/*
775
* The FC IOC may kill a request for variety of
776
* reasons, some of which may be recovered by a
777
* retry, some which are unlikely to be
778
* recovered. Return DID_ERROR instead of
779
* DID_RESET to permit retry of the command,
780
* just not an infinite number of them
781
*/
782
sc->result = DID_ERROR << 16;
783
break;
784
}
785
786
/*
787
* Allow non-SAS & non-NEXUS_LOSS to drop into below code
788
*/
789
790
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
791
/* Linux handles an unsolicited DID_RESET better
792
* than an unsolicited DID_ABORT.
793
*/
794
sc->result = DID_RESET << 16;
795
796
case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
797
if (ioc->bus_type == FC)
798
sc->result = DID_ERROR << 16;
799
else
800
sc->result = DID_RESET << 16;
801
break;
802
803
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
804
scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
805
if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
806
sc->result=DID_SOFT_ERROR << 16;
807
else /* Sufficient data transfer occurred */
808
sc->result = (DID_OK << 16) | scsi_status;
809
dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
810
"RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
811
ioc->name, sc->result, sc->device->channel, sc->device->id));
812
break;
813
814
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
815
/*
816
* Do upfront check for valid SenseData and give it
817
* precedence!
818
*/
819
sc->result = (DID_OK << 16) | scsi_status;
820
if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
821
822
/*
823
* For an Errata on LSI53C1030
824
* When the length of request data
825
* and transfer data are different
826
* with result of command (READ or VERIFY),
827
* DID_SOFT_ERROR is set.
828
*/
829
if (ioc->bus_type == SPI) {
830
if (pScsiReq->CDB[0] == READ_6 ||
831
pScsiReq->CDB[0] == READ_10 ||
832
pScsiReq->CDB[0] == READ_12 ||
833
pScsiReq->CDB[0] == READ_16 ||
834
pScsiReq->CDB[0] == VERIFY ||
835
pScsiReq->CDB[0] == VERIFY_16) {
836
if (scsi_bufflen(sc) !=
837
xfer_cnt) {
838
sc->result =
839
DID_SOFT_ERROR << 16;
840
printk(KERN_WARNING "Errata"
841
"on LSI53C1030 occurred."
842
"sc->req_bufflen=0x%02x,"
843
"xfer_cnt=0x%02x\n",
844
scsi_bufflen(sc),
845
xfer_cnt);
846
}
847
}
848
}
849
850
if (xfer_cnt < sc->underflow) {
851
if (scsi_status == SAM_STAT_BUSY)
852
sc->result = SAM_STAT_BUSY;
853
else
854
sc->result = DID_SOFT_ERROR << 16;
855
}
856
if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
857
/* What to do?
858
*/
859
sc->result = DID_SOFT_ERROR << 16;
860
}
861
else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
862
/* Not real sure here either... */
863
sc->result = DID_RESET << 16;
864
}
865
}
866
867
868
dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
869
" sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
870
ioc->name, sc->underflow));
871
dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
872
" ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
873
874
/* Report Queue Full
875
*/
876
if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
877
mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
878
879
break;
880
881
case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
882
scsi_set_resid(sc, 0);
883
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
884
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
885
sc->result = (DID_OK << 16) | scsi_status;
886
if (scsi_state == 0) {
887
;
888
} else if (scsi_state &
889
MPI_SCSI_STATE_AUTOSENSE_VALID) {
890
891
/*
892
* For potential trouble on LSI53C1030.
893
* (date:2007.xx.)
894
* It is checked whether the length of
895
* request data is equal to
896
* the length of transfer and residual.
897
* MEDIUM_ERROR is set by incorrect data.
898
*/
899
if ((ioc->bus_type == SPI) &&
900
(sc->sense_buffer[2] & 0x20)) {
901
u32 difftransfer;
902
difftransfer =
903
sc->sense_buffer[3] << 24 |
904
sc->sense_buffer[4] << 16 |
905
sc->sense_buffer[5] << 8 |
906
sc->sense_buffer[6];
907
if (((sc->sense_buffer[3] & 0x80) ==
908
0x80) && (scsi_bufflen(sc)
909
!= xfer_cnt)) {
910
sc->sense_buffer[2] =
911
MEDIUM_ERROR;
912
sc->sense_buffer[12] = 0xff;
913
sc->sense_buffer[13] = 0xff;
914
printk(KERN_WARNING"Errata"
915
"on LSI53C1030 occurred."
916
"sc->req_bufflen=0x%02x,"
917
"xfer_cnt=0x%02x\n" ,
918
scsi_bufflen(sc),
919
xfer_cnt);
920
}
921
if (((sc->sense_buffer[3] & 0x80)
922
!= 0x80) &&
923
(scsi_bufflen(sc) !=
924
xfer_cnt + difftransfer)) {
925
sc->sense_buffer[2] =
926
MEDIUM_ERROR;
927
sc->sense_buffer[12] = 0xff;
928
sc->sense_buffer[13] = 0xff;
929
printk(KERN_WARNING
930
"Errata on LSI53C1030 occurred"
931
"sc->req_bufflen=0x%02x,"
932
" xfer_cnt=0x%02x,"
933
"difftransfer=0x%02x\n",
934
scsi_bufflen(sc),
935
xfer_cnt,
936
difftransfer);
937
}
938
}
939
940
/*
941
* If running against circa 200003dd 909 MPT f/w,
942
* may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
943
* (QUEUE_FULL) returned from device! --> get 0x0000?128
944
* and with SenseBytes set to 0.
945
*/
946
if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
947
mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
948
949
}
950
else if (scsi_state &
951
(MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
952
) {
953
/*
954
* What to do?
955
*/
956
sc->result = DID_SOFT_ERROR << 16;
957
}
958
else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
959
/* Not real sure here either... */
960
sc->result = DID_RESET << 16;
961
}
962
else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
963
/* Device Inq. data indicates that it supports
964
* QTags, but rejects QTag messages.
965
* This command completed OK.
966
*
967
* Not real sure here either so do nothing... */
968
}
969
970
if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
971
mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
972
973
/* Add handling of:
974
* Reservation Conflict, Busy,
975
* Command Terminated, CHECK
976
*/
977
break;
978
979
case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
980
sc->result = DID_SOFT_ERROR << 16;
981
break;
982
983
case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
984
case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
985
case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
986
case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
987
case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
988
case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
989
case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
990
case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
991
default:
992
/*
993
* What to do?
994
*/
995
sc->result = DID_SOFT_ERROR << 16;
996
break;
997
998
} /* switch(status) */
999
1000
#ifdef CONFIG_FUSION_LOGGING
1001
if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
1002
mptscsih_info_scsiio(ioc, sc, pScsiReply);
1003
#endif
1004
1005
} /* end of address reply case */
1006
out:
1007
/* Unmap the DMA buffers, if any. */
1008
scsi_dma_unmap(sc);
1009
1010
sc->scsi_done(sc); /* Issue the command callback */
1011
1012
/* Free Chain buffers */
1013
mptscsih_freeChainBuffers(ioc, req_idx);
1014
return 1;
1015
}
1016
1017
/*
1018
* mptscsih_flush_running_cmds - For each command found, search
1019
* Scsi_Host instance taskQ and reply to OS.
1020
* Called only if recovering from a FW reload.
1021
* @hd: Pointer to a SCSI HOST structure
1022
*
1023
* Returns: None.
1024
*
1025
* Must be called while new I/Os are being queued.
1026
*/
1027
static void
1028
mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
1029
{
1030
MPT_ADAPTER *ioc = hd->ioc;
1031
struct scsi_cmnd *sc;
1032
SCSIIORequest_t *mf = NULL;
1033
int ii;
1034
int channel, id;
1035
1036
for (ii= 0; ii < ioc->req_depth; ii++) {
1037
sc = mptscsih_getclear_scsi_lookup(ioc, ii);
1038
if (!sc)
1039
continue;
1040
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1041
if (!mf)
1042
continue;
1043
channel = mf->Bus;
1044
id = mf->TargetID;
1045
mptscsih_freeChainBuffers(ioc, ii);
1046
mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1047
if ((unsigned char *)mf != sc->host_scribble)
1048
continue;
1049
scsi_dma_unmap(sc);
1050
sc->result = DID_RESET << 16;
1051
sc->host_scribble = NULL;
1052
dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
1053
"completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
1054
"idx=%x\n", ioc->name, channel, id, sc, mf, ii));
1055
sc->scsi_done(sc);
1056
}
1057
}
1058
1059
/*
1060
* mptscsih_search_running_cmds - Delete any commands associated
1061
* with the specified target and lun. Function called only
1062
* when a lun is disable by mid-layer.
1063
* Do NOT access the referenced scsi_cmnd structure or
1064
* members. Will cause either a paging or NULL ptr error.
1065
* (BUT, BUT, BUT, the code does reference it! - mdr)
1066
* @hd: Pointer to a SCSI HOST structure
1067
* @vdevice: per device private data
1068
*
1069
* Returns: None.
1070
*
1071
* Called from slave_destroy.
1072
*/
1073
static void
1074
mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1075
{
1076
SCSIIORequest_t *mf = NULL;
1077
int ii;
1078
struct scsi_cmnd *sc;
1079
struct scsi_lun lun;
1080
MPT_ADAPTER *ioc = hd->ioc;
1081
unsigned long flags;
1082
1083
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1084
for (ii = 0; ii < ioc->req_depth; ii++) {
1085
if ((sc = ioc->ScsiLookup[ii]) != NULL) {
1086
1087
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1088
if (mf == NULL)
1089
continue;
1090
/* If the device is a hidden raid component, then its
1091
* expected that the mf->function will be RAID_SCSI_IO
1092
*/
1093
if (vdevice->vtarget->tflags &
1094
MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1095
MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1096
continue;
1097
1098
int_to_scsilun(vdevice->lun, &lun);
1099
if ((mf->Bus != vdevice->vtarget->channel) ||
1100
(mf->TargetID != vdevice->vtarget->id) ||
1101
memcmp(lun.scsi_lun, mf->LUN, 8))
1102
continue;
1103
1104
if ((unsigned char *)mf != sc->host_scribble)
1105
continue;
1106
ioc->ScsiLookup[ii] = NULL;
1107
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1108
mptscsih_freeChainBuffers(ioc, ii);
1109
mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1110
scsi_dma_unmap(sc);
1111
sc->host_scribble = NULL;
1112
sc->result = DID_NO_CONNECT << 16;
1113
dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
1114
MYIOC_s_FMT "completing cmds: fw_channel %d, "
1115
"fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
1116
vdevice->vtarget->channel, vdevice->vtarget->id,
1117
sc, mf, ii));
1118
sc->scsi_done(sc);
1119
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1120
}
1121
}
1122
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1123
return;
1124
}
1125
1126
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1127
1128
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1129
/*
1130
* mptscsih_report_queue_full - Report QUEUE_FULL status returned
1131
* from a SCSI target device.
1132
* @sc: Pointer to scsi_cmnd structure
1133
* @pScsiReply: Pointer to SCSIIOReply_t
1134
* @pScsiReq: Pointer to original SCSI request
1135
*
1136
* This routine periodically reports QUEUE_FULL status returned from a
1137
* SCSI target device. It reports this to the console via kernel
1138
* printk() API call, not more than once every 10 seconds.
1139
*/
1140
static void
1141
mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1142
{
1143
long time = jiffies;
1144
MPT_SCSI_HOST *hd;
1145
MPT_ADAPTER *ioc;
1146
1147
if (sc->device == NULL)
1148
return;
1149
if (sc->device->host == NULL)
1150
return;
1151
if ((hd = shost_priv(sc->device->host)) == NULL)
1152
return;
1153
ioc = hd->ioc;
1154
if (time - hd->last_queue_full > 10 * HZ) {
1155
dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1156
ioc->name, 0, sc->device->id, sc->device->lun));
1157
hd->last_queue_full = time;
1158
}
1159
}
1160
1161
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1162
/*
1163
* mptscsih_remove - Removed scsi devices
1164
* @pdev: Pointer to pci_dev structure
1165
*
1166
*
1167
*/
1168
void
1169
mptscsih_remove(struct pci_dev *pdev)
1170
{
1171
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1172
struct Scsi_Host *host = ioc->sh;
1173
MPT_SCSI_HOST *hd;
1174
int sz1;
1175
1176
scsi_remove_host(host);
1177
1178
if((hd = shost_priv(host)) == NULL)
1179
return;
1180
1181
mptscsih_shutdown(pdev);
1182
1183
sz1=0;
1184
1185
if (ioc->ScsiLookup != NULL) {
1186
sz1 = ioc->req_depth * sizeof(void *);
1187
kfree(ioc->ScsiLookup);
1188
ioc->ScsiLookup = NULL;
1189
}
1190
1191
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1192
"Free'd ScsiLookup (%d) memory\n",
1193
ioc->name, sz1));
1194
1195
kfree(hd->info_kbuf);
1196
1197
/* NULL the Scsi_Host pointer
1198
*/
1199
ioc->sh = NULL;
1200
1201
scsi_host_put(host);
1202
1203
mpt_detach(pdev);
1204
1205
}
1206
1207
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1208
/*
1209
* mptscsih_shutdown - reboot notifier
1210
*
1211
*/
1212
void
1213
mptscsih_shutdown(struct pci_dev *pdev)
1214
{
1215
}
1216
1217
#ifdef CONFIG_PM
1218
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1219
/*
1220
* mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1221
*
1222
*
1223
*/
1224
int
1225
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1226
{
1227
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1228
1229
scsi_block_requests(ioc->sh);
1230
flush_scheduled_work();
1231
mptscsih_shutdown(pdev);
1232
return mpt_suspend(pdev,state);
1233
}
1234
1235
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1236
/*
1237
* mptscsih_resume - Fusion MPT scsi driver resume routine.
1238
*
1239
*
1240
*/
1241
int
1242
mptscsih_resume(struct pci_dev *pdev)
1243
{
1244
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1245
int rc;
1246
1247
rc = mpt_resume(pdev);
1248
scsi_unblock_requests(ioc->sh);
1249
return rc;
1250
}
1251
1252
#endif
1253
1254
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1255
/**
1256
* mptscsih_info - Return information about MPT adapter
1257
* @SChost: Pointer to Scsi_Host structure
1258
*
1259
* (linux scsi_host_template.info routine)
1260
*
1261
* Returns pointer to buffer where information was written.
1262
*/
1263
const char *
1264
mptscsih_info(struct Scsi_Host *SChost)
1265
{
1266
MPT_SCSI_HOST *h;
1267
int size = 0;
1268
1269
h = shost_priv(SChost);
1270
1271
if (h) {
1272
if (h->info_kbuf == NULL)
1273
if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1274
return h->info_kbuf;
1275
h->info_kbuf[0] = '\0';
1276
1277
mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1278
h->info_kbuf[size-1] = '\0';
1279
}
1280
1281
return h->info_kbuf;
1282
}
1283
1284
struct info_str {
1285
char *buffer;
1286
int length;
1287
int offset;
1288
int pos;
1289
};
1290
1291
static void
1292
mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1293
{
1294
if (info->pos + len > info->length)
1295
len = info->length - info->pos;
1296
1297
if (info->pos + len < info->offset) {
1298
info->pos += len;
1299
return;
1300
}
1301
1302
if (info->pos < info->offset) {
1303
data += (info->offset - info->pos);
1304
len -= (info->offset - info->pos);
1305
}
1306
1307
if (len > 0) {
1308
memcpy(info->buffer + info->pos, data, len);
1309
info->pos += len;
1310
}
1311
}
1312
1313
static int
1314
mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1315
{
1316
va_list args;
1317
char buf[81];
1318
int len;
1319
1320
va_start(args, fmt);
1321
len = vsprintf(buf, fmt, args);
1322
va_end(args);
1323
1324
mptscsih_copy_mem_info(info, buf, len);
1325
return len;
1326
}
1327
1328
static int
1329
mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1330
{
1331
struct info_str info;
1332
1333
info.buffer = pbuf;
1334
info.length = len;
1335
info.offset = offset;
1336
info.pos = 0;
1337
1338
mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1339
mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1340
mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1341
mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1342
1343
return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1344
}
1345
1346
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1347
/**
1348
* mptscsih_proc_info - Return information about MPT adapter
1349
* @host: scsi host struct
1350
* @buffer: if write, user data; if read, buffer for user
1351
* @start: returns the buffer address
1352
* @offset: if write, 0; if read, the current offset into the buffer from
1353
* the previous read.
1354
* @length: if write, return length;
1355
* @func: write = 1; read = 0
1356
*
1357
* (linux scsi_host_template.info routine)
1358
*/
1359
int
1360
mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1361
int length, int func)
1362
{
1363
MPT_SCSI_HOST *hd = shost_priv(host);
1364
MPT_ADAPTER *ioc = hd->ioc;
1365
int size = 0;
1366
1367
if (func) {
1368
/*
1369
* write is not supported
1370
*/
1371
} else {
1372
if (start)
1373
*start = buffer;
1374
1375
size = mptscsih_host_info(ioc, buffer, offset, length);
1376
}
1377
1378
return size;
1379
}
1380
1381
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1382
#define ADD_INDEX_LOG(req_ent) do { } while(0)
1383
1384
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1385
/**
1386
* mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1387
* @SCpnt: Pointer to scsi_cmnd structure
1388
* @done: Pointer SCSI mid-layer IO completion function
1389
*
1390
* (linux scsi_host_template.queuecommand routine)
1391
* This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1392
* from a linux scsi_cmnd request and send it to the IOC.
1393
*
1394
* Returns 0. (rtn value discarded by linux scsi mid-layer)
1395
*/
1396
int
1397
mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1398
{
1399
MPT_SCSI_HOST *hd;
1400
MPT_FRAME_HDR *mf;
1401
SCSIIORequest_t *pScsiReq;
1402
VirtDevice *vdevice = SCpnt->device->hostdata;
1403
u32 datalen;
1404
u32 scsictl;
1405
u32 scsidir;
1406
u32 cmd_len;
1407
int my_idx;
1408
int ii;
1409
MPT_ADAPTER *ioc;
1410
1411
hd = shost_priv(SCpnt->device->host);
1412
ioc = hd->ioc;
1413
SCpnt->scsi_done = done;
1414
1415
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
1416
ioc->name, SCpnt, done));
1417
1418
if (ioc->taskmgmt_quiesce_io)
1419
return SCSI_MLQUEUE_HOST_BUSY;
1420
1421
/*
1422
* Put together a MPT SCSI request...
1423
*/
1424
if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1425
dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1426
ioc->name));
1427
return SCSI_MLQUEUE_HOST_BUSY;
1428
}
1429
1430
pScsiReq = (SCSIIORequest_t *) mf;
1431
1432
my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1433
1434
ADD_INDEX_LOG(my_idx);
1435
1436
/* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1437
* Seems we may receive a buffer (datalen>0) even when there
1438
* will be no data transfer! GRRRRR...
1439
*/
1440
if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1441
datalen = scsi_bufflen(SCpnt);
1442
scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1443
} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1444
datalen = scsi_bufflen(SCpnt);
1445
scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1446
} else {
1447
datalen = 0;
1448
scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1449
}
1450
1451
/* Default to untagged. Once a target structure has been allocated,
1452
* use the Inquiry data to determine if device supports tagged.
1453
*/
1454
if (vdevice
1455
&& (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1456
&& (SCpnt->device->tagged_supported)) {
1457
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1458
if (SCpnt->request && SCpnt->request->ioprio) {
1459
if (((SCpnt->request->ioprio & 0x7) == 1) ||
1460
!(SCpnt->request->ioprio & 0x7))
1461
scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
1462
}
1463
} else
1464
scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1465
1466
1467
/* Use the above information to set up the message frame
1468
*/
1469
pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1470
pScsiReq->Bus = vdevice->vtarget->channel;
1471
pScsiReq->ChainOffset = 0;
1472
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1473
pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1474
else
1475
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1476
pScsiReq->CDBLength = SCpnt->cmd_len;
1477
pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1478
pScsiReq->Reserved = 0;
1479
pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1480
int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1481
pScsiReq->Control = cpu_to_le32(scsictl);
1482
1483
/*
1484
* Write SCSI CDB into the message
1485
*/
1486
cmd_len = SCpnt->cmd_len;
1487
for (ii=0; ii < cmd_len; ii++)
1488
pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1489
1490
for (ii=cmd_len; ii < 16; ii++)
1491
pScsiReq->CDB[ii] = 0;
1492
1493
/* DataLength */
1494
pScsiReq->DataLength = cpu_to_le32(datalen);
1495
1496
/* SenseBuffer low address */
1497
pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1498
+ (my_idx * MPT_SENSE_BUFFER_ALLOC));
1499
1500
/* Now add the SG list
1501
* Always have a SGE even if null length.
1502
*/
1503
if (datalen == 0) {
1504
/* Add a NULL SGE */
1505
ioc->add_sge((char *)&pScsiReq->SGL,
1506
MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1507
(dma_addr_t) -1);
1508
} else {
1509
/* Add a 32 or 64 bit SGE */
1510
if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1511
goto fail;
1512
}
1513
1514
SCpnt->host_scribble = (unsigned char *)mf;
1515
mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1516
1517
mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1518
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1519
ioc->name, SCpnt, mf, my_idx));
1520
DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1521
return 0;
1522
1523
fail:
1524
mptscsih_freeChainBuffers(ioc, my_idx);
1525
mpt_free_msg_frame(ioc, mf);
1526
return SCSI_MLQUEUE_HOST_BUSY;
1527
}
1528
1529
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1530
/*
1531
* mptscsih_freeChainBuffers - Function to free chain buffers associated
1532
* with a SCSI IO request
1533
* @hd: Pointer to the MPT_SCSI_HOST instance
1534
* @req_idx: Index of the SCSI IO request frame.
1535
*
1536
* Called if SG chain buffer allocation fails and mptscsih callbacks.
1537
* No return.
1538
*/
1539
static void
1540
mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1541
{
1542
MPT_FRAME_HDR *chain;
1543
unsigned long flags;
1544
int chain_idx;
1545
int next;
1546
1547
/* Get the first chain index and reset
1548
* tracker state.
1549
*/
1550
chain_idx = ioc->ReqToChain[req_idx];
1551
ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1552
1553
while (chain_idx != MPT_HOST_NO_CHAIN) {
1554
1555
/* Save the next chain buffer index */
1556
next = ioc->ChainToChain[chain_idx];
1557
1558
/* Free this chain buffer and reset
1559
* tracker
1560
*/
1561
ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1562
1563
chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1564
+ (chain_idx * ioc->req_sz));
1565
1566
spin_lock_irqsave(&ioc->FreeQlock, flags);
1567
list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1568
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1569
1570
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1571
ioc->name, chain_idx));
1572
1573
/* handle next */
1574
chain_idx = next;
1575
}
1576
return;
1577
}
1578
1579
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1580
/*
1581
* Reset Handling
1582
*/
1583
1584
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1585
/**
1586
* mptscsih_IssueTaskMgmt - Generic send Task Management function.
1587
* @hd: Pointer to MPT_SCSI_HOST structure
1588
* @type: Task Management type
1589
* @channel: channel number for task management
1590
* @id: Logical Target ID for reset (if appropriate)
1591
* @lun: Logical Unit for reset (if appropriate)
1592
* @ctx2abort: Context for the task to be aborted (if appropriate)
1593
* @timeout: timeout for task management control
1594
*
1595
* Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1596
* or a non-interrupt thread. In the former, must not call schedule().
1597
*
1598
* Not all fields are meaningfull for all task types.
1599
*
1600
* Returns 0 for SUCCESS, or FAILED.
1601
*
1602
**/
1603
int
1604
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1605
int ctx2abort, ulong timeout)
1606
{
1607
MPT_FRAME_HDR *mf;
1608
SCSITaskMgmt_t *pScsiTm;
1609
int ii;
1610
int retval;
1611
MPT_ADAPTER *ioc = hd->ioc;
1612
unsigned long timeleft;
1613
u8 issue_hard_reset;
1614
u32 ioc_raw_state;
1615
unsigned long time_count;
1616
1617
issue_hard_reset = 0;
1618
ioc_raw_state = mpt_GetIocState(ioc, 0);
1619
1620
if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1621
printk(MYIOC_s_WARN_FMT
1622
"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1623
ioc->name, type, ioc_raw_state);
1624
printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1625
ioc->name, __func__);
1626
if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1627
printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1628
"FAILED!!\n", ioc->name);
1629
return 0;
1630
}
1631
1632
if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1633
printk(MYIOC_s_WARN_FMT
1634
"TaskMgmt type=%x: ioc_state: "
1635
"DOORBELL_ACTIVE (0x%x)!\n",
1636
ioc->name, type, ioc_raw_state);
1637
return FAILED;
1638
}
1639
1640
mutex_lock(&ioc->taskmgmt_cmds.mutex);
1641
if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1642
mf = NULL;
1643
retval = FAILED;
1644
goto out;
1645
}
1646
1647
/* Return Fail to calling function if no message frames available.
1648
*/
1649
if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1650
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1651
"TaskMgmt no msg frames!!\n", ioc->name));
1652
retval = FAILED;
1653
mpt_clear_taskmgmt_in_progress_flag(ioc);
1654
goto out;
1655
}
1656
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1657
ioc->name, mf));
1658
1659
/* Format the Request
1660
*/
1661
pScsiTm = (SCSITaskMgmt_t *) mf;
1662
pScsiTm->TargetID = id;
1663
pScsiTm->Bus = channel;
1664
pScsiTm->ChainOffset = 0;
1665
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1666
1667
pScsiTm->Reserved = 0;
1668
pScsiTm->TaskType = type;
1669
pScsiTm->Reserved1 = 0;
1670
pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1671
? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1672
1673
int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1674
1675
for (ii=0; ii < 7; ii++)
1676
pScsiTm->Reserved2[ii] = 0;
1677
1678
pScsiTm->TaskMsgContext = ctx2abort;
1679
1680
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1681
"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1682
type, timeout));
1683
1684
DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1685
1686
INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1687
time_count = jiffies;
1688
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1689
(ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1690
mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1691
else {
1692
retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1693
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1694
if (retval) {
1695
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1696
"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1697
ioc->name, mf, retval));
1698
mpt_free_msg_frame(ioc, mf);
1699
mpt_clear_taskmgmt_in_progress_flag(ioc);
1700
goto out;
1701
}
1702
}
1703
1704
timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1705
timeout*HZ);
1706
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1707
retval = FAILED;
1708
dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1709
"TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1710
mpt_clear_taskmgmt_in_progress_flag(ioc);
1711
if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1712
goto out;
1713
issue_hard_reset = 1;
1714
goto out;
1715
}
1716
1717
retval = mptscsih_taskmgmt_reply(ioc, type,
1718
(SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1719
1720
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1721
"TaskMgmt completed (%d seconds)\n",
1722
ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1723
1724
out:
1725
1726
CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1727
if (issue_hard_reset) {
1728
printk(MYIOC_s_WARN_FMT
1729
"Issuing Reset from %s!! doorbell=0x%08x\n",
1730
ioc->name, __func__, mpt_GetIocState(ioc, 0));
1731
retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1732
mpt_free_msg_frame(ioc, mf);
1733
}
1734
1735
retval = (retval == 0) ? 0 : FAILED;
1736
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1737
return retval;
1738
}
1739
EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1740
1741
static int
1742
mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1743
{
1744
switch (ioc->bus_type) {
1745
case FC:
1746
return 40;
1747
case SAS:
1748
return 30;
1749
case SPI:
1750
default:
1751
return 10;
1752
}
1753
}
1754
1755
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1756
/**
1757
* mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1758
* @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1759
*
1760
* (linux scsi_host_template.eh_abort_handler routine)
1761
*
1762
* Returns SUCCESS or FAILED.
1763
**/
1764
int
1765
mptscsih_abort(struct scsi_cmnd * SCpnt)
1766
{
1767
MPT_SCSI_HOST *hd;
1768
MPT_FRAME_HDR *mf;
1769
u32 ctx2abort;
1770
int scpnt_idx;
1771
int retval;
1772
VirtDevice *vdevice;
1773
MPT_ADAPTER *ioc;
1774
1775
/* If we can't locate our host adapter structure, return FAILED status.
1776
*/
1777
if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1778
SCpnt->result = DID_RESET << 16;
1779
SCpnt->scsi_done(SCpnt);
1780
printk(KERN_ERR MYNAM ": task abort: "
1781
"can't locate host! (sc=%p)\n", SCpnt);
1782
return FAILED;
1783
}
1784
1785
ioc = hd->ioc;
1786
printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1787
ioc->name, SCpnt);
1788
scsi_print_command(SCpnt);
1789
1790
vdevice = SCpnt->device->hostdata;
1791
if (!vdevice || !vdevice->vtarget) {
1792
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1793
"task abort: device has been deleted (sc=%p)\n",
1794
ioc->name, SCpnt));
1795
SCpnt->result = DID_NO_CONNECT << 16;
1796
SCpnt->scsi_done(SCpnt);
1797
retval = SUCCESS;
1798
goto out;
1799
}
1800
1801
/* Task aborts are not supported for hidden raid components.
1802
*/
1803
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1804
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1805
"task abort: hidden raid component (sc=%p)\n",
1806
ioc->name, SCpnt));
1807
SCpnt->result = DID_RESET << 16;
1808
retval = FAILED;
1809
goto out;
1810
}
1811
1812
/* Task aborts are not supported for volumes.
1813
*/
1814
if (vdevice->vtarget->raidVolume) {
1815
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1816
"task abort: raid volume (sc=%p)\n",
1817
ioc->name, SCpnt));
1818
SCpnt->result = DID_RESET << 16;
1819
retval = FAILED;
1820
goto out;
1821
}
1822
1823
/* Find this command
1824
*/
1825
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1826
/* Cmd not found in ScsiLookup.
1827
* Do OS callback.
1828
*/
1829
SCpnt->result = DID_RESET << 16;
1830
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1831
"Command not in the active list! (sc=%p)\n", ioc->name,
1832
SCpnt));
1833
retval = SUCCESS;
1834
goto out;
1835
}
1836
1837
if (ioc->timeouts < -1)
1838
ioc->timeouts++;
1839
1840
if (mpt_fwfault_debug)
1841
mpt_halt_firmware(ioc);
1842
1843
/* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1844
* (the IO to be ABORT'd)
1845
*
1846
* NOTE: Since we do not byteswap MsgContext, we do not
1847
* swap it here either. It is an opaque cookie to
1848
* the controller, so it does not matter. -DaveM
1849
*/
1850
mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1851
ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1852
retval = mptscsih_IssueTaskMgmt(hd,
1853
MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1854
vdevice->vtarget->channel,
1855
vdevice->vtarget->id, vdevice->lun,
1856
ctx2abort, mptscsih_get_tm_timeout(ioc));
1857
1858
if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1859
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1860
"task abort: command still in active list! (sc=%p)\n",
1861
ioc->name, SCpnt));
1862
retval = FAILED;
1863
} else {
1864
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1865
"task abort: command cleared from active list! (sc=%p)\n",
1866
ioc->name, SCpnt));
1867
retval = SUCCESS;
1868
}
1869
1870
out:
1871
printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1872
ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1873
SCpnt);
1874
1875
return retval;
1876
}
1877
1878
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1879
/**
1880
* mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1881
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1882
*
1883
* (linux scsi_host_template.eh_dev_reset_handler routine)
1884
*
1885
* Returns SUCCESS or FAILED.
1886
**/
1887
int
1888
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1889
{
1890
MPT_SCSI_HOST *hd;
1891
int retval;
1892
VirtDevice *vdevice;
1893
MPT_ADAPTER *ioc;
1894
1895
/* If we can't locate our host adapter structure, return FAILED status.
1896
*/
1897
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1898
printk(KERN_ERR MYNAM ": target reset: "
1899
"Can't locate host! (sc=%p)\n", SCpnt);
1900
return FAILED;
1901
}
1902
1903
ioc = hd->ioc;
1904
printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1905
ioc->name, SCpnt);
1906
scsi_print_command(SCpnt);
1907
1908
vdevice = SCpnt->device->hostdata;
1909
if (!vdevice || !vdevice->vtarget) {
1910
retval = 0;
1911
goto out;
1912
}
1913
1914
/* Target reset to hidden raid component is not supported
1915
*/
1916
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1917
retval = FAILED;
1918
goto out;
1919
}
1920
1921
retval = mptscsih_IssueTaskMgmt(hd,
1922
MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1923
vdevice->vtarget->channel,
1924
vdevice->vtarget->id, 0, 0,
1925
mptscsih_get_tm_timeout(ioc));
1926
1927
out:
1928
printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1929
ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1930
1931
if (retval == 0)
1932
return SUCCESS;
1933
else
1934
return FAILED;
1935
}
1936
1937
1938
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1939
/**
1940
* mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1941
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1942
*
1943
* (linux scsi_host_template.eh_bus_reset_handler routine)
1944
*
1945
* Returns SUCCESS or FAILED.
1946
**/
1947
int
1948
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1949
{
1950
MPT_SCSI_HOST *hd;
1951
int retval;
1952
VirtDevice *vdevice;
1953
MPT_ADAPTER *ioc;
1954
1955
/* If we can't locate our host adapter structure, return FAILED status.
1956
*/
1957
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1958
printk(KERN_ERR MYNAM ": bus reset: "
1959
"Can't locate host! (sc=%p)\n", SCpnt);
1960
return FAILED;
1961
}
1962
1963
ioc = hd->ioc;
1964
printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1965
ioc->name, SCpnt);
1966
scsi_print_command(SCpnt);
1967
1968
if (ioc->timeouts < -1)
1969
ioc->timeouts++;
1970
1971
vdevice = SCpnt->device->hostdata;
1972
if (!vdevice || !vdevice->vtarget)
1973
return SUCCESS;
1974
retval = mptscsih_IssueTaskMgmt(hd,
1975
MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1976
vdevice->vtarget->channel, 0, 0, 0,
1977
mptscsih_get_tm_timeout(ioc));
1978
1979
printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1980
ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1981
1982
if (retval == 0)
1983
return SUCCESS;
1984
else
1985
return FAILED;
1986
}
1987
1988
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1989
/**
1990
* mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1991
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1992
*
1993
* (linux scsi_host_template.eh_host_reset_handler routine)
1994
*
1995
* Returns SUCCESS or FAILED.
1996
*/
1997
int
1998
mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1999
{
2000
MPT_SCSI_HOST * hd;
2001
int status = SUCCESS;
2002
MPT_ADAPTER *ioc;
2003
int retval;
2004
2005
/* If we can't locate the host to reset, then we failed. */
2006
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
2007
printk(KERN_ERR MYNAM ": host reset: "
2008
"Can't locate host! (sc=%p)\n", SCpnt);
2009
return FAILED;
2010
}
2011
2012
/* make sure we have no outstanding commands at this stage */
2013
mptscsih_flush_running_cmds(hd);
2014
2015
ioc = hd->ioc;
2016
printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
2017
ioc->name, SCpnt);
2018
2019
/* If our attempts to reset the host failed, then return a failed
2020
* status. The host will be taken off line by the SCSI mid-layer.
2021
*/
2022
retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2023
if (retval < 0)
2024
status = FAILED;
2025
else
2026
status = SUCCESS;
2027
2028
printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
2029
ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
2030
2031
return status;
2032
}
2033
2034
static int
2035
mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
2036
SCSITaskMgmtReply_t *pScsiTmReply)
2037
{
2038
u16 iocstatus;
2039
u32 termination_count;
2040
int retval;
2041
2042
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
2043
retval = FAILED;
2044
goto out;
2045
}
2046
2047
DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2048
2049
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2050
termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2051
2052
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2053
"TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
2054
"\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
2055
"\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
2056
pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
2057
le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
2058
termination_count));
2059
2060
if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2061
pScsiTmReply->ResponseCode)
2062
mptscsih_taskmgmt_response_code(ioc,
2063
pScsiTmReply->ResponseCode);
2064
2065
if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
2066
retval = 0;
2067
goto out;
2068
}
2069
2070
retval = FAILED;
2071
if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
2072
if (termination_count == 1)
2073
retval = 0;
2074
goto out;
2075
}
2076
2077
if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
2078
iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
2079
retval = 0;
2080
2081
out:
2082
return retval;
2083
}
2084
2085
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2086
void
2087
mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2088
{
2089
char *desc;
2090
2091
switch (response_code) {
2092
case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2093
desc = "The task completed.";
2094
break;
2095
case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2096
desc = "The IOC received an invalid frame status.";
2097
break;
2098
case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2099
desc = "The task type is not supported.";
2100
break;
2101
case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2102
desc = "The requested task failed.";
2103
break;
2104
case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2105
desc = "The task completed successfully.";
2106
break;
2107
case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2108
desc = "The LUN request is invalid.";
2109
break;
2110
case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2111
desc = "The task is in the IOC queue and has not been sent to target.";
2112
break;
2113
default:
2114
desc = "unknown";
2115
break;
2116
}
2117
printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2118
ioc->name, response_code, desc);
2119
}
2120
EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2121
2122
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2123
/**
2124
* mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2125
* @ioc: Pointer to MPT_ADAPTER structure
2126
* @mf: Pointer to SCSI task mgmt request frame
2127
* @mr: Pointer to SCSI task mgmt reply frame
2128
*
2129
* This routine is called from mptbase.c::mpt_interrupt() at the completion
2130
* of any SCSI task management request.
2131
* This routine is registered with the MPT (base) driver at driver
2132
* load/init time via the mpt_register() API call.
2133
*
2134
* Returns 1 indicating alloc'd request frame ptr should be freed.
2135
**/
2136
int
2137
mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2138
MPT_FRAME_HDR *mr)
2139
{
2140
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2141
"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2142
2143
ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2144
2145
if (!mr)
2146
goto out;
2147
2148
ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2149
memcpy(ioc->taskmgmt_cmds.reply, mr,
2150
min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2151
out:
2152
if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2153
mpt_clear_taskmgmt_in_progress_flag(ioc);
2154
ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2155
complete(&ioc->taskmgmt_cmds.done);
2156
if (ioc->bus_type == SAS)
2157
ioc->schedule_target_reset(ioc);
2158
return 1;
2159
}
2160
return 0;
2161
}
2162
2163
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2164
/*
2165
* This is anyones guess quite frankly.
2166
*/
2167
int
2168
mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2169
sector_t capacity, int geom[])
2170
{
2171
int heads;
2172
int sectors;
2173
sector_t cylinders;
2174
ulong dummy;
2175
2176
heads = 64;
2177
sectors = 32;
2178
2179
dummy = heads * sectors;
2180
cylinders = capacity;
2181
sector_div(cylinders,dummy);
2182
2183
/*
2184
* Handle extended translation size for logical drives
2185
* > 1Gb
2186
*/
2187
if ((ulong)capacity >= 0x200000) {
2188
heads = 255;
2189
sectors = 63;
2190
dummy = heads * sectors;
2191
cylinders = capacity;
2192
sector_div(cylinders,dummy);
2193
}
2194
2195
/* return result */
2196
geom[0] = heads;
2197
geom[1] = sectors;
2198
geom[2] = cylinders;
2199
2200
return 0;
2201
}
2202
2203
/* Search IOC page 3 to determine if this is hidden physical disk
2204
*
2205
*/
2206
int
2207
mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2208
{
2209
struct inactive_raid_component_info *component_info;
2210
int i, j;
2211
RaidPhysDiskPage1_t *phys_disk;
2212
int rc = 0;
2213
int num_paths;
2214
2215
if (!ioc->raid_data.pIocPg3)
2216
goto out;
2217
for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2218
if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2219
(channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2220
rc = 1;
2221
goto out;
2222
}
2223
}
2224
2225
if (ioc->bus_type != SAS)
2226
goto out;
2227
2228
/*
2229
* Check if dual path
2230
*/
2231
for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2232
num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2233
ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2234
if (num_paths < 2)
2235
continue;
2236
phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2237
(num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2238
if (!phys_disk)
2239
continue;
2240
if ((mpt_raid_phys_disk_pg1(ioc,
2241
ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2242
phys_disk))) {
2243
kfree(phys_disk);
2244
continue;
2245
}
2246
for (j = 0; j < num_paths; j++) {
2247
if ((phys_disk->Path[j].Flags &
2248
MPI_RAID_PHYSDISK1_FLAG_INVALID))
2249
continue;
2250
if ((phys_disk->Path[j].Flags &
2251
MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2252
continue;
2253
if ((id == phys_disk->Path[j].PhysDiskID) &&
2254
(channel == phys_disk->Path[j].PhysDiskBus)) {
2255
rc = 1;
2256
kfree(phys_disk);
2257
goto out;
2258
}
2259
}
2260
kfree(phys_disk);
2261
}
2262
2263
2264
/*
2265
* Check inactive list for matching phys disks
2266
*/
2267
if (list_empty(&ioc->raid_data.inactive_list))
2268
goto out;
2269
2270
mutex_lock(&ioc->raid_data.inactive_list_mutex);
2271
list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2272
list) {
2273
if ((component_info->d.PhysDiskID == id) &&
2274
(component_info->d.PhysDiskBus == channel))
2275
rc = 1;
2276
}
2277
mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2278
2279
out:
2280
return rc;
2281
}
2282
EXPORT_SYMBOL(mptscsih_is_phys_disk);
2283
2284
u8
2285
mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2286
{
2287
struct inactive_raid_component_info *component_info;
2288
int i, j;
2289
RaidPhysDiskPage1_t *phys_disk;
2290
int rc = -ENXIO;
2291
int num_paths;
2292
2293
if (!ioc->raid_data.pIocPg3)
2294
goto out;
2295
for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2296
if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2297
(channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2298
rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2299
goto out;
2300
}
2301
}
2302
2303
if (ioc->bus_type != SAS)
2304
goto out;
2305
2306
/*
2307
* Check if dual path
2308
*/
2309
for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2310
num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2311
ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2312
if (num_paths < 2)
2313
continue;
2314
phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2315
(num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2316
if (!phys_disk)
2317
continue;
2318
if ((mpt_raid_phys_disk_pg1(ioc,
2319
ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2320
phys_disk))) {
2321
kfree(phys_disk);
2322
continue;
2323
}
2324
for (j = 0; j < num_paths; j++) {
2325
if ((phys_disk->Path[j].Flags &
2326
MPI_RAID_PHYSDISK1_FLAG_INVALID))
2327
continue;
2328
if ((phys_disk->Path[j].Flags &
2329
MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2330
continue;
2331
if ((id == phys_disk->Path[j].PhysDiskID) &&
2332
(channel == phys_disk->Path[j].PhysDiskBus)) {
2333
rc = phys_disk->PhysDiskNum;
2334
kfree(phys_disk);
2335
goto out;
2336
}
2337
}
2338
kfree(phys_disk);
2339
}
2340
2341
/*
2342
* Check inactive list for matching phys disks
2343
*/
2344
if (list_empty(&ioc->raid_data.inactive_list))
2345
goto out;
2346
2347
mutex_lock(&ioc->raid_data.inactive_list_mutex);
2348
list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2349
list) {
2350
if ((component_info->d.PhysDiskID == id) &&
2351
(component_info->d.PhysDiskBus == channel))
2352
rc = component_info->d.PhysDiskNum;
2353
}
2354
mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2355
2356
out:
2357
return rc;
2358
}
2359
EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2360
2361
/*
2362
* OS entry point to allow for host driver to free allocated memory
2363
* Called if no device present or device being unloaded
2364
*/
2365
void
2366
mptscsih_slave_destroy(struct scsi_device *sdev)
2367
{
2368
struct Scsi_Host *host = sdev->host;
2369
MPT_SCSI_HOST *hd = shost_priv(host);
2370
VirtTarget *vtarget;
2371
VirtDevice *vdevice;
2372
struct scsi_target *starget;
2373
2374
starget = scsi_target(sdev);
2375
vtarget = starget->hostdata;
2376
vdevice = sdev->hostdata;
2377
if (!vdevice)
2378
return;
2379
2380
mptscsih_search_running_cmds(hd, vdevice);
2381
vtarget->num_luns--;
2382
mptscsih_synchronize_cache(hd, vdevice);
2383
kfree(vdevice);
2384
sdev->hostdata = NULL;
2385
}
2386
2387
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2388
/*
2389
* mptscsih_change_queue_depth - This function will set a devices queue depth
2390
* @sdev: per scsi_device pointer
2391
* @qdepth: requested queue depth
2392
* @reason: calling context
2393
*
2394
* Adding support for new 'change_queue_depth' api.
2395
*/
2396
int
2397
mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
2398
{
2399
MPT_SCSI_HOST *hd = shost_priv(sdev->host);
2400
VirtTarget *vtarget;
2401
struct scsi_target *starget;
2402
int max_depth;
2403
int tagged;
2404
MPT_ADAPTER *ioc = hd->ioc;
2405
2406
starget = scsi_target(sdev);
2407
vtarget = starget->hostdata;
2408
2409
if (reason != SCSI_QDEPTH_DEFAULT)
2410
return -EOPNOTSUPP;
2411
2412
if (ioc->bus_type == SPI) {
2413
if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2414
max_depth = 1;
2415
else if (sdev->type == TYPE_DISK &&
2416
vtarget->minSyncFactor <= MPT_ULTRA160)
2417
max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2418
else
2419
max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2420
} else
2421
max_depth = ioc->sh->can_queue;
2422
2423
if (!sdev->tagged_supported)
2424
max_depth = 1;
2425
2426
if (qdepth > max_depth)
2427
qdepth = max_depth;
2428
if (qdepth == 1)
2429
tagged = 0;
2430
else
2431
tagged = MSG_SIMPLE_TAG;
2432
2433
scsi_adjust_queue_depth(sdev, tagged, qdepth);
2434
return sdev->queue_depth;
2435
}
2436
2437
/*
2438
* OS entry point to adjust the queue_depths on a per-device basis.
2439
* Called once per device the bus scan. Use it to force the queue_depth
2440
* member to 1 if a device does not support Q tags.
2441
* Return non-zero if fails.
2442
*/
2443
int
2444
mptscsih_slave_configure(struct scsi_device *sdev)
2445
{
2446
struct Scsi_Host *sh = sdev->host;
2447
VirtTarget *vtarget;
2448
VirtDevice *vdevice;
2449
struct scsi_target *starget;
2450
MPT_SCSI_HOST *hd = shost_priv(sh);
2451
MPT_ADAPTER *ioc = hd->ioc;
2452
2453
starget = scsi_target(sdev);
2454
vtarget = starget->hostdata;
2455
vdevice = sdev->hostdata;
2456
2457
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2458
"device @ %p, channel=%d, id=%d, lun=%d\n",
2459
ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2460
if (ioc->bus_type == SPI)
2461
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2462
"sdtr %d wdtr %d ppr %d inq length=%d\n",
2463
ioc->name, sdev->sdtr, sdev->wdtr,
2464
sdev->ppr, sdev->inquiry_len));
2465
2466
vdevice->configured_lun = 1;
2467
2468
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2469
"Queue depth=%d, tflags=%x\n",
2470
ioc->name, sdev->queue_depth, vtarget->tflags));
2471
2472
if (ioc->bus_type == SPI)
2473
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2474
"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2475
ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2476
vtarget->minSyncFactor));
2477
2478
mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
2479
SCSI_QDEPTH_DEFAULT);
2480
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2481
"tagged %d, simple %d, ordered %d\n",
2482
ioc->name,sdev->tagged_supported, sdev->simple_tags,
2483
sdev->ordered_tags));
2484
2485
blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2486
2487
return 0;
2488
}
2489
2490
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2491
/*
2492
* Private routines...
2493
*/
2494
2495
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2496
/* Utility function to copy sense data from the scsi_cmnd buffer
2497
* to the FC and SCSI target structures.
2498
*
2499
*/
2500
static void
2501
mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2502
{
2503
VirtDevice *vdevice;
2504
SCSIIORequest_t *pReq;
2505
u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2506
MPT_ADAPTER *ioc = hd->ioc;
2507
2508
/* Get target structure
2509
*/
2510
pReq = (SCSIIORequest_t *) mf;
2511
vdevice = sc->device->hostdata;
2512
2513
if (sense_count) {
2514
u8 *sense_data;
2515
int req_index;
2516
2517
/* Copy the sense received into the scsi command block. */
2518
req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2519
sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2520
memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2521
2522
/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2523
*/
2524
if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2525
if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2526
int idx;
2527
2528
idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2529
ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2530
ioc->events[idx].eventContext = ioc->eventContext;
2531
2532
ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2533
(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2534
(sc->device->channel << 8) | sc->device->id;
2535
2536
ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2537
2538
ioc->eventContext++;
2539
if (ioc->pcidev->vendor ==
2540
PCI_VENDOR_ID_IBM) {
2541
mptscsih_issue_sep_command(ioc,
2542
vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2543
vdevice->vtarget->tflags |=
2544
MPT_TARGET_FLAGS_LED_ON;
2545
}
2546
}
2547
}
2548
} else {
2549
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2550
ioc->name));
2551
}
2552
}
2553
2554
/**
2555
* mptscsih_get_scsi_lookup - retrieves scmd entry
2556
* @ioc: Pointer to MPT_ADAPTER structure
2557
* @i: index into the array
2558
*
2559
* Returns the scsi_cmd pointer
2560
*/
2561
struct scsi_cmnd *
2562
mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2563
{
2564
unsigned long flags;
2565
struct scsi_cmnd *scmd;
2566
2567
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2568
scmd = ioc->ScsiLookup[i];
2569
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2570
2571
return scmd;
2572
}
2573
EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2574
2575
/**
2576
* mptscsih_getclear_scsi_lookup - retrieves and clears scmd entry from ScsiLookup[] array list
2577
* @ioc: Pointer to MPT_ADAPTER structure
2578
* @i: index into the array
2579
*
2580
* Returns the scsi_cmd pointer
2581
*
2582
**/
2583
static struct scsi_cmnd *
2584
mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2585
{
2586
unsigned long flags;
2587
struct scsi_cmnd *scmd;
2588
2589
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2590
scmd = ioc->ScsiLookup[i];
2591
ioc->ScsiLookup[i] = NULL;
2592
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2593
2594
return scmd;
2595
}
2596
2597
/**
2598
* mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2599
*
2600
* @ioc: Pointer to MPT_ADAPTER structure
2601
* @i: index into the array
2602
* @scmd: scsi_cmnd pointer
2603
*
2604
**/
2605
static void
2606
mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2607
{
2608
unsigned long flags;
2609
2610
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2611
ioc->ScsiLookup[i] = scmd;
2612
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2613
}
2614
2615
/**
2616
* SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2617
* @ioc: Pointer to MPT_ADAPTER structure
2618
* @sc: scsi_cmnd pointer
2619
*/
2620
static int
2621
SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2622
{
2623
unsigned long flags;
2624
int i, index=-1;
2625
2626
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2627
for (i = 0; i < ioc->req_depth; i++) {
2628
if (ioc->ScsiLookup[i] == sc) {
2629
index = i;
2630
goto out;
2631
}
2632
}
2633
2634
out:
2635
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2636
return index;
2637
}
2638
2639
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2640
int
2641
mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2642
{
2643
MPT_SCSI_HOST *hd;
2644
2645
if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2646
return 0;
2647
2648
hd = shost_priv(ioc->sh);
2649
switch (reset_phase) {
2650
case MPT_IOC_SETUP_RESET:
2651
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2652
"%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2653
break;
2654
case MPT_IOC_PRE_RESET:
2655
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2656
"%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2657
mptscsih_flush_running_cmds(hd);
2658
break;
2659
case MPT_IOC_POST_RESET:
2660
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2661
"%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2662
if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2663
ioc->internal_cmds.status |=
2664
MPT_MGMT_STATUS_DID_IOCRESET;
2665
complete(&ioc->internal_cmds.done);
2666
}
2667
break;
2668
default:
2669
break;
2670
}
2671
return 1; /* currently means nothing really */
2672
}
2673
2674
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2675
int
2676
mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2677
{
2678
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2679
2680
devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2681
"MPT event (=%02Xh) routed to SCSI host driver!\n",
2682
ioc->name, event));
2683
2684
if ((event == MPI_EVENT_IOC_BUS_RESET ||
2685
event == MPI_EVENT_EXT_BUS_RESET) &&
2686
(ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2687
ioc->soft_resets++;
2688
2689
return 1; /* currently means nothing really */
2690
}
2691
2692
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2693
/*
2694
* Bus Scan and Domain Validation functionality ...
2695
*/
2696
2697
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2698
/*
2699
* mptscsih_scandv_complete - Scan and DV callback routine registered
2700
* to Fustion MPT (base) driver.
2701
*
2702
* @ioc: Pointer to MPT_ADAPTER structure
2703
* @mf: Pointer to original MPT request frame
2704
* @mr: Pointer to MPT reply frame (NULL if TurboReply)
2705
*
2706
* This routine is called from mpt.c::mpt_interrupt() at the completion
2707
* of any SCSI IO request.
2708
* This routine is registered with the Fusion MPT (base) driver at driver
2709
* load/init time via the mpt_register() API call.
2710
*
2711
* Returns 1 indicating alloc'd request frame ptr should be freed.
2712
*
2713
* Remark: Sets a completion code and (possibly) saves sense data
2714
* in the IOC member localReply structure.
2715
* Used ONLY for DV and other internal commands.
2716
*/
2717
int
2718
mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2719
MPT_FRAME_HDR *reply)
2720
{
2721
SCSIIORequest_t *pReq;
2722
SCSIIOReply_t *pReply;
2723
u8 cmd;
2724
u16 req_idx;
2725
u8 *sense_data;
2726
int sz;
2727
2728
ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2729
ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2730
if (!reply)
2731
goto out;
2732
2733
pReply = (SCSIIOReply_t *) reply;
2734
pReq = (SCSIIORequest_t *) req;
2735
ioc->internal_cmds.completion_code =
2736
mptscsih_get_completion_code(ioc, req, reply);
2737
ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2738
memcpy(ioc->internal_cmds.reply, reply,
2739
min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2740
cmd = reply->u.hdr.Function;
2741
if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2742
(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2743
(pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2744
req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2745
sense_data = ((u8 *)ioc->sense_buf_pool +
2746
(req_idx * MPT_SENSE_BUFFER_ALLOC));
2747
sz = min_t(int, pReq->SenseBufferLength,
2748
MPT_SENSE_BUFFER_ALLOC);
2749
memcpy(ioc->internal_cmds.sense, sense_data, sz);
2750
}
2751
out:
2752
if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2753
return 0;
2754
ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2755
complete(&ioc->internal_cmds.done);
2756
return 1;
2757
}
2758
2759
2760
/**
2761
* mptscsih_get_completion_code - get completion code from MPT request
2762
* @ioc: Pointer to MPT_ADAPTER structure
2763
* @req: Pointer to original MPT request frame
2764
* @reply: Pointer to MPT reply frame (NULL if TurboReply)
2765
*
2766
**/
2767
static int
2768
mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2769
MPT_FRAME_HDR *reply)
2770
{
2771
SCSIIOReply_t *pReply;
2772
MpiRaidActionReply_t *pr;
2773
u8 scsi_status;
2774
u16 status;
2775
int completion_code;
2776
2777
pReply = (SCSIIOReply_t *)reply;
2778
status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2779
scsi_status = pReply->SCSIStatus;
2780
2781
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2782
"IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2783
"IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2784
scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2785
2786
switch (status) {
2787
2788
case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2789
completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2790
break;
2791
2792
case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2793
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2794
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2795
case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2796
completion_code = MPT_SCANDV_DID_RESET;
2797
break;
2798
2799
case MPI_IOCSTATUS_BUSY:
2800
case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2801
completion_code = MPT_SCANDV_BUSY;
2802
break;
2803
2804
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2805
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2806
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2807
if (pReply->Function == MPI_FUNCTION_CONFIG) {
2808
completion_code = MPT_SCANDV_GOOD;
2809
} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2810
pr = (MpiRaidActionReply_t *)reply;
2811
if (le16_to_cpu(pr->ActionStatus) ==
2812
MPI_RAID_ACTION_ASTATUS_SUCCESS)
2813
completion_code = MPT_SCANDV_GOOD;
2814
else
2815
completion_code = MPT_SCANDV_SOME_ERROR;
2816
} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2817
completion_code = MPT_SCANDV_SENSE;
2818
else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2819
if (req->u.scsireq.CDB[0] == INQUIRY)
2820
completion_code = MPT_SCANDV_ISSUE_SENSE;
2821
else
2822
completion_code = MPT_SCANDV_DID_RESET;
2823
} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2824
completion_code = MPT_SCANDV_DID_RESET;
2825
else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2826
completion_code = MPT_SCANDV_DID_RESET;
2827
else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2828
completion_code = MPT_SCANDV_BUSY;
2829
else
2830
completion_code = MPT_SCANDV_GOOD;
2831
break;
2832
2833
case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2834
if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2835
completion_code = MPT_SCANDV_DID_RESET;
2836
else
2837
completion_code = MPT_SCANDV_SOME_ERROR;
2838
break;
2839
default:
2840
completion_code = MPT_SCANDV_SOME_ERROR;
2841
break;
2842
2843
} /* switch(status) */
2844
2845
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2846
" completionCode set to %08xh\n", ioc->name, completion_code));
2847
return completion_code;
2848
}
2849
2850
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2851
/**
2852
* mptscsih_do_cmd - Do internal command.
2853
* @hd: MPT_SCSI_HOST pointer
2854
* @io: INTERNAL_CMD pointer.
2855
*
2856
* Issue the specified internally generated command and do command
2857
* specific cleanup. For bus scan / DV only.
2858
* NOTES: If command is Inquiry and status is good,
2859
* initialize a target structure, save the data
2860
*
2861
* Remark: Single threaded access only.
2862
*
2863
* Return:
2864
* < 0 if an illegal command or no resources
2865
*
2866
* 0 if good
2867
*
2868
* > 0 if command complete but some type of completion error.
2869
*/
2870
static int
2871
mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2872
{
2873
MPT_FRAME_HDR *mf;
2874
SCSIIORequest_t *pScsiReq;
2875
int my_idx, ii, dir;
2876
int timeout;
2877
char cmdLen;
2878
char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2879
u8 cmd = io->cmd;
2880
MPT_ADAPTER *ioc = hd->ioc;
2881
int ret = 0;
2882
unsigned long timeleft;
2883
unsigned long flags;
2884
2885
/* don't send internal command during diag reset */
2886
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2887
if (ioc->ioc_reset_in_progress) {
2888
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2889
dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2890
"%s: busy with host reset\n", ioc->name, __func__));
2891
return MPT_SCANDV_BUSY;
2892
}
2893
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2894
2895
mutex_lock(&ioc->internal_cmds.mutex);
2896
2897
/* Set command specific information
2898
*/
2899
switch (cmd) {
2900
case INQUIRY:
2901
cmdLen = 6;
2902
dir = MPI_SCSIIO_CONTROL_READ;
2903
CDB[0] = cmd;
2904
CDB[4] = io->size;
2905
timeout = 10;
2906
break;
2907
2908
case TEST_UNIT_READY:
2909
cmdLen = 6;
2910
dir = MPI_SCSIIO_CONTROL_READ;
2911
timeout = 10;
2912
break;
2913
2914
case START_STOP:
2915
cmdLen = 6;
2916
dir = MPI_SCSIIO_CONTROL_READ;
2917
CDB[0] = cmd;
2918
CDB[4] = 1; /*Spin up the disk */
2919
timeout = 15;
2920
break;
2921
2922
case REQUEST_SENSE:
2923
cmdLen = 6;
2924
CDB[0] = cmd;
2925
CDB[4] = io->size;
2926
dir = MPI_SCSIIO_CONTROL_READ;
2927
timeout = 10;
2928
break;
2929
2930
case READ_BUFFER:
2931
cmdLen = 10;
2932
dir = MPI_SCSIIO_CONTROL_READ;
2933
CDB[0] = cmd;
2934
if (io->flags & MPT_ICFLAG_ECHO) {
2935
CDB[1] = 0x0A;
2936
} else {
2937
CDB[1] = 0x02;
2938
}
2939
2940
if (io->flags & MPT_ICFLAG_BUF_CAP) {
2941
CDB[1] |= 0x01;
2942
}
2943
CDB[6] = (io->size >> 16) & 0xFF;
2944
CDB[7] = (io->size >> 8) & 0xFF;
2945
CDB[8] = io->size & 0xFF;
2946
timeout = 10;
2947
break;
2948
2949
case WRITE_BUFFER:
2950
cmdLen = 10;
2951
dir = MPI_SCSIIO_CONTROL_WRITE;
2952
CDB[0] = cmd;
2953
if (io->flags & MPT_ICFLAG_ECHO) {
2954
CDB[1] = 0x0A;
2955
} else {
2956
CDB[1] = 0x02;
2957
}
2958
CDB[6] = (io->size >> 16) & 0xFF;
2959
CDB[7] = (io->size >> 8) & 0xFF;
2960
CDB[8] = io->size & 0xFF;
2961
timeout = 10;
2962
break;
2963
2964
case RESERVE:
2965
cmdLen = 6;
2966
dir = MPI_SCSIIO_CONTROL_READ;
2967
CDB[0] = cmd;
2968
timeout = 10;
2969
break;
2970
2971
case RELEASE:
2972
cmdLen = 6;
2973
dir = MPI_SCSIIO_CONTROL_READ;
2974
CDB[0] = cmd;
2975
timeout = 10;
2976
break;
2977
2978
case SYNCHRONIZE_CACHE:
2979
cmdLen = 10;
2980
dir = MPI_SCSIIO_CONTROL_READ;
2981
CDB[0] = cmd;
2982
// CDB[1] = 0x02; /* set immediate bit */
2983
timeout = 10;
2984
break;
2985
2986
default:
2987
/* Error Case */
2988
ret = -EFAULT;
2989
goto out;
2990
}
2991
2992
/* Get and Populate a free Frame
2993
* MsgContext set in mpt_get_msg_frame call
2994
*/
2995
if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2996
dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2997
ioc->name, __func__));
2998
ret = MPT_SCANDV_BUSY;
2999
goto out;
3000
}
3001
3002
pScsiReq = (SCSIIORequest_t *) mf;
3003
3004
/* Get the request index */
3005
my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3006
ADD_INDEX_LOG(my_idx); /* for debug */
3007
3008
if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3009
pScsiReq->TargetID = io->physDiskNum;
3010
pScsiReq->Bus = 0;
3011
pScsiReq->ChainOffset = 0;
3012
pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3013
} else {
3014
pScsiReq->TargetID = io->id;
3015
pScsiReq->Bus = io->channel;
3016
pScsiReq->ChainOffset = 0;
3017
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3018
}
3019
3020
pScsiReq->CDBLength = cmdLen;
3021
pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3022
3023
pScsiReq->Reserved = 0;
3024
3025
pScsiReq->MsgFlags = mpt_msg_flags(ioc);
3026
/* MsgContext set in mpt_get_msg_fram call */
3027
3028
int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3029
3030
if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3031
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3032
else
3033
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3034
3035
if (cmd == REQUEST_SENSE) {
3036
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3037
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3038
"%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
3039
}
3040
3041
for (ii = 0; ii < 16; ii++)
3042
pScsiReq->CDB[ii] = CDB[ii];
3043
3044
pScsiReq->DataLength = cpu_to_le32(io->size);
3045
pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3046
+ (my_idx * MPT_SENSE_BUFFER_ALLOC));
3047
3048
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3049
"%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
3050
ioc->name, __func__, cmd, io->channel, io->id, io->lun));
3051
3052
if (dir == MPI_SCSIIO_CONTROL_READ)
3053
ioc->add_sge((char *) &pScsiReq->SGL,
3054
MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
3055
else
3056
ioc->add_sge((char *) &pScsiReq->SGL,
3057
MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
3058
3059
INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
3060
mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3061
timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
3062
timeout*HZ);
3063
if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
3064
ret = MPT_SCANDV_DID_RESET;
3065
dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3066
"%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
3067
cmd));
3068
if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
3069
mpt_free_msg_frame(ioc, mf);
3070
goto out;
3071
}
3072
if (!timeleft) {
3073
printk(MYIOC_s_WARN_FMT
3074
"Issuing Reset from %s!! doorbell=0x%08xh"
3075
" cmd=0x%02x\n",
3076
ioc->name, __func__, mpt_GetIocState(ioc, 0),
3077
cmd);
3078
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
3079
mpt_free_msg_frame(ioc, mf);
3080
}
3081
goto out;
3082
}
3083
3084
ret = ioc->internal_cmds.completion_code;
3085
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
3086
ioc->name, __func__, ret));
3087
3088
out:
3089
CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
3090
mutex_unlock(&ioc->internal_cmds.mutex);
3091
return ret;
3092
}
3093
3094
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3095
/**
3096
* mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3097
* @hd: Pointer to a SCSI HOST structure
3098
* @vdevice: virtual target device
3099
*
3100
* Uses the ISR, but with special processing.
3101
* MUST be single-threaded.
3102
*
3103
*/
3104
static void
3105
mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3106
{
3107
INTERNAL_CMD iocmd;
3108
3109
/* Ignore hidden raid components, this is handled when the command
3110
* is sent to the volume
3111
*/
3112
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3113
return;
3114
3115
if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3116
!vdevice->configured_lun)
3117
return;
3118
3119
/* Following parameters will not change
3120
* in this routine.
3121
*/
3122
iocmd.cmd = SYNCHRONIZE_CACHE;
3123
iocmd.flags = 0;
3124
iocmd.physDiskNum = -1;
3125
iocmd.data = NULL;
3126
iocmd.data_dma = -1;
3127
iocmd.size = 0;
3128
iocmd.rsvd = iocmd.rsvd2 = 0;
3129
iocmd.channel = vdevice->vtarget->channel;
3130
iocmd.id = vdevice->vtarget->id;
3131
iocmd.lun = vdevice->lun;
3132
3133
mptscsih_do_cmd(hd, &iocmd);
3134
}
3135
3136
static ssize_t
3137
mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3138
char *buf)
3139
{
3140
struct Scsi_Host *host = class_to_shost(dev);
3141
MPT_SCSI_HOST *hd = shost_priv(host);
3142
MPT_ADAPTER *ioc = hd->ioc;
3143
3144
return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3145
(ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3146
(ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3147
(ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3148
ioc->facts.FWVersion.Word & 0x000000FF);
3149
}
3150
static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3151
3152
static ssize_t
3153
mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3154
char *buf)
3155
{
3156
struct Scsi_Host *host = class_to_shost(dev);
3157
MPT_SCSI_HOST *hd = shost_priv(host);
3158
MPT_ADAPTER *ioc = hd->ioc;
3159
3160
return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3161
(ioc->biosVersion & 0xFF000000) >> 24,
3162
(ioc->biosVersion & 0x00FF0000) >> 16,
3163
(ioc->biosVersion & 0x0000FF00) >> 8,
3164
ioc->biosVersion & 0x000000FF);
3165
}
3166
static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3167
3168
static ssize_t
3169
mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3170
char *buf)
3171
{
3172
struct Scsi_Host *host = class_to_shost(dev);
3173
MPT_SCSI_HOST *hd = shost_priv(host);
3174
MPT_ADAPTER *ioc = hd->ioc;
3175
3176
return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3177
}
3178
static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3179
3180
static ssize_t
3181
mptscsih_version_product_show(struct device *dev,
3182
struct device_attribute *attr,
3183
char *buf)
3184
{
3185
struct Scsi_Host *host = class_to_shost(dev);
3186
MPT_SCSI_HOST *hd = shost_priv(host);
3187
MPT_ADAPTER *ioc = hd->ioc;
3188
3189
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3190
}
3191
static DEVICE_ATTR(version_product, S_IRUGO,
3192
mptscsih_version_product_show, NULL);
3193
3194
static ssize_t
3195
mptscsih_version_nvdata_persistent_show(struct device *dev,
3196
struct device_attribute *attr,
3197
char *buf)
3198
{
3199
struct Scsi_Host *host = class_to_shost(dev);
3200
MPT_SCSI_HOST *hd = shost_priv(host);
3201
MPT_ADAPTER *ioc = hd->ioc;
3202
3203
return snprintf(buf, PAGE_SIZE, "%02xh\n",
3204
ioc->nvdata_version_persistent);
3205
}
3206
static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3207
mptscsih_version_nvdata_persistent_show, NULL);
3208
3209
static ssize_t
3210
mptscsih_version_nvdata_default_show(struct device *dev,
3211
struct device_attribute *attr, char *buf)
3212
{
3213
struct Scsi_Host *host = class_to_shost(dev);
3214
MPT_SCSI_HOST *hd = shost_priv(host);
3215
MPT_ADAPTER *ioc = hd->ioc;
3216
3217
return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3218
}
3219
static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3220
mptscsih_version_nvdata_default_show, NULL);
3221
3222
static ssize_t
3223
mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3224
char *buf)
3225
{
3226
struct Scsi_Host *host = class_to_shost(dev);
3227
MPT_SCSI_HOST *hd = shost_priv(host);
3228
MPT_ADAPTER *ioc = hd->ioc;
3229
3230
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3231
}
3232
static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3233
3234
static ssize_t
3235
mptscsih_board_assembly_show(struct device *dev,
3236
struct device_attribute *attr, char *buf)
3237
{
3238
struct Scsi_Host *host = class_to_shost(dev);
3239
MPT_SCSI_HOST *hd = shost_priv(host);
3240
MPT_ADAPTER *ioc = hd->ioc;
3241
3242
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3243
}
3244
static DEVICE_ATTR(board_assembly, S_IRUGO,
3245
mptscsih_board_assembly_show, NULL);
3246
3247
static ssize_t
3248
mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3249
char *buf)
3250
{
3251
struct Scsi_Host *host = class_to_shost(dev);
3252
MPT_SCSI_HOST *hd = shost_priv(host);
3253
MPT_ADAPTER *ioc = hd->ioc;
3254
3255
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3256
}
3257
static DEVICE_ATTR(board_tracer, S_IRUGO,
3258
mptscsih_board_tracer_show, NULL);
3259
3260
static ssize_t
3261
mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3262
char *buf)
3263
{
3264
struct Scsi_Host *host = class_to_shost(dev);
3265
MPT_SCSI_HOST *hd = shost_priv(host);
3266
MPT_ADAPTER *ioc = hd->ioc;
3267
3268
return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3269
}
3270
static DEVICE_ATTR(io_delay, S_IRUGO,
3271
mptscsih_io_delay_show, NULL);
3272
3273
static ssize_t
3274
mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3275
char *buf)
3276
{
3277
struct Scsi_Host *host = class_to_shost(dev);
3278
MPT_SCSI_HOST *hd = shost_priv(host);
3279
MPT_ADAPTER *ioc = hd->ioc;
3280
3281
return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3282
}
3283
static DEVICE_ATTR(device_delay, S_IRUGO,
3284
mptscsih_device_delay_show, NULL);
3285
3286
static ssize_t
3287
mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3288
char *buf)
3289
{
3290
struct Scsi_Host *host = class_to_shost(dev);
3291
MPT_SCSI_HOST *hd = shost_priv(host);
3292
MPT_ADAPTER *ioc = hd->ioc;
3293
3294
return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3295
}
3296
static ssize_t
3297
mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3298
const char *buf, size_t count)
3299
{
3300
struct Scsi_Host *host = class_to_shost(dev);
3301
MPT_SCSI_HOST *hd = shost_priv(host);
3302
MPT_ADAPTER *ioc = hd->ioc;
3303
int val = 0;
3304
3305
if (sscanf(buf, "%x", &val) != 1)
3306
return -EINVAL;
3307
3308
ioc->debug_level = val;
3309
printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3310
ioc->name, ioc->debug_level);
3311
return strlen(buf);
3312
}
3313
static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3314
mptscsih_debug_level_show, mptscsih_debug_level_store);
3315
3316
struct device_attribute *mptscsih_host_attrs[] = {
3317
&dev_attr_version_fw,
3318
&dev_attr_version_bios,
3319
&dev_attr_version_mpi,
3320
&dev_attr_version_product,
3321
&dev_attr_version_nvdata_persistent,
3322
&dev_attr_version_nvdata_default,
3323
&dev_attr_board_name,
3324
&dev_attr_board_assembly,
3325
&dev_attr_board_tracer,
3326
&dev_attr_io_delay,
3327
&dev_attr_device_delay,
3328
&dev_attr_debug_level,
3329
NULL,
3330
};
3331
3332
EXPORT_SYMBOL(mptscsih_host_attrs);
3333
3334
EXPORT_SYMBOL(mptscsih_remove);
3335
EXPORT_SYMBOL(mptscsih_shutdown);
3336
#ifdef CONFIG_PM
3337
EXPORT_SYMBOL(mptscsih_suspend);
3338
EXPORT_SYMBOL(mptscsih_resume);
3339
#endif
3340
EXPORT_SYMBOL(mptscsih_proc_info);
3341
EXPORT_SYMBOL(mptscsih_info);
3342
EXPORT_SYMBOL(mptscsih_qcmd);
3343
EXPORT_SYMBOL(mptscsih_slave_destroy);
3344
EXPORT_SYMBOL(mptscsih_slave_configure);
3345
EXPORT_SYMBOL(mptscsih_abort);
3346
EXPORT_SYMBOL(mptscsih_dev_reset);
3347
EXPORT_SYMBOL(mptscsih_bus_reset);
3348
EXPORT_SYMBOL(mptscsih_host_reset);
3349
EXPORT_SYMBOL(mptscsih_bios_param);
3350
EXPORT_SYMBOL(mptscsih_io_done);
3351
EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3352
EXPORT_SYMBOL(mptscsih_scandv_complete);
3353
EXPORT_SYMBOL(mptscsih_event_process);
3354
EXPORT_SYMBOL(mptscsih_ioc_reset);
3355
EXPORT_SYMBOL(mptscsih_change_queue_depth);
3356
3357
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3358
3359