1
/*******************************************************************************
2
Copyright (C) Marvell International Ltd. and its affiliates
4
This software file (the "File") is owned and distributed by Marvell
5
International Ltd. and/or its affiliates ("Marvell") under the following
6
alternative licensing terms. Once you have made an election to distribute the
7
File under one of the following license alternatives, please (i) delete this
8
introductory statement regarding license alternatives, (ii) delete the two
9
license alternatives that you have not elected to use and (iii) preserve the
10
Marvell copyright notice above.
13
********************************************************************************
14
Marvell GPL License Option
16
If you received this File from Marvell, you may opt to use, redistribute and/or
17
modify this File in accordance with the terms and conditions of the General
18
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
19
available along with the File in the license.txt file or by writing to the Free
20
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
21
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
23
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
24
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
25
DISCLAIMED. The GPL License provides additional details about this warranty
27
*******************************************************************************/
28
/*******************************************************************************
32
* C implementation for SCSI to ATA translation layer.
38
*******************************************************************************/
41
#include "mvScsiAtaLayer.h"
42
#include "mvIALCommon.h"
45
#define SAL_SPRINTF sprintf
49
/* Bits for HD_ERROR */
50
#define NM_ERR 0x02 /* media present */
51
#define ABRT_ERR 0x04 /* Command aborted */
52
#define MCR_ERR 0x08 /* media change request */
53
#define IDNF_ERR 0x10 /* ID field not found */
54
#define MC_ERR 0x20 /* media changed */
55
#define UNC_ERR 0x40 /* Uncorrect data */
56
#define WP_ERR 0x40 /* write protect */
57
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
60
static MV_VOID reportScbCompletion(MV_SATA_ADAPTER* pSataAdapter,
61
MV_SATA_SCSI_CMD_BLOCK *pScb);
65
static MV_VOID mvAta2HostString(IN MV_U16 *source,
67
IN MV_U32 wordsCount);
69
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetInquiryData(IN MV_SATA_ADAPTER* pSataAdapter,
70
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
72
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaTestUnitReady(IN MV_SATA_ADAPTER* pSataAdapter,
73
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
75
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendDataCommand(IN MV_SATA_ADAPTER* pSataAdapter,
76
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
78
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetReadCapacityData(IN MV_SATA_ADAPTER* pSataAdapter,
79
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
81
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaReportLuns(IN MV_SATA_ADAPTER* pSataAdapter,
82
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
84
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendVerifyCommand(IN MV_SATA_ADAPTER* pSataAdapter,
85
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
87
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaReassignBlocks(IN MV_SATA_ADAPTER *pSataAdapter,
88
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
90
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendSyncCacheCommand(IN MV_SATA_ADAPTER* pSataAdapter,
91
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
93
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetRequestSenseData(IN MV_SATA_ADAPTER* pSataAdapter,
94
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
96
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetModeSenseData(IN MV_SATA_ADAPTER* pSataAdapter,
97
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
99
static MV_BOOLEAN mvScsiAtaGetModeSenseDataPhase2(IN MV_SATA_ADAPTER *pSataAdapter,
100
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
102
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaModeSelect(IN MV_SATA_ADAPTER* pSataAdapter,
103
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
105
static MV_U8 modeSelect(IN MV_SATA_ADAPTER *pSataAdapter,
106
IN MV_SATA_SCSI_CMD_BLOCK *pScb,
107
MV_SCSI_COMMAND_STATUS_TYPE *pCommandStatus);
109
static MV_U8 mvParseModeCachingPage(MV_SATA_ADAPTER *pSataAdapter,
110
IN MV_SATA_SCSI_CMD_BLOCK *pScb,
112
MV_SCSI_COMMAND_STATUS_TYPE *pCommandStatus);
113
static MV_U32 mvModeSenseCachingPage(MV_SATA_SCSI_CMD_BLOCK *pScb,
114
MV_U8 *buffer, MV_U8 pageControl);
116
static MV_U32 mvModeSenseControlPage(MV_SATA_ADAPTER *pSataAdapter,
117
MV_SATA_SCSI_CMD_BLOCK *pScb,
118
MV_U8 *buffer, MV_U8 pageControl);
120
static MV_BOOLEAN SALCommandCompletionCB(MV_SATA_ADAPTER *pSataAdapter,
122
MV_COMPLETION_TYPE comp_type,
123
MV_VOID_PTR commandId,
124
MV_U16 responseFlags,
126
MV_STORAGE_DEVICE_REGISTERS *registerStruct);
128
MV_VOID setSenseData(IN MV_SATA_SCSI_CMD_BLOCK *pScb, IN MV_U8 SenseKey,
129
IN MV_U8 AdditionalSenseCode, IN MV_U8 ASCQ);
131
MV_VOID _fillSenseInformation(IN MV_SATA_SCSI_CMD_BLOCK *pScb, MV_SCSI_SENSE_DATA *SenseData,
132
MV_STORAGE_DEVICE_REGISTERS *registerStruct);
134
MV_VOID handleNoneUdmaError(MV_SATA_SCSI_CMD_BLOCK *pScb,
135
MV_STORAGE_DEVICE_REGISTERS *registerStruct);
137
static MV_VOID handleUdmaError(MV_SATA_SCSI_CMD_BLOCK *pScb,
138
MV_U32 responseFlags,
139
MV_STORAGE_DEVICE_REGISTERS *registerStruct);
141
/*static*/ MV_VOID checkQueueCommandResult(MV_SATA_SCSI_CMD_BLOCK *pScb,
142
MV_QUEUE_COMMAND_RESULT result);
144
static MV_VOID mvScsiAtaSendSplittedVerifyCommand(IN MV_SATA_SCSI_CMD_BLOCK *pScb);
146
static MV_VOID mvScsiAtaSendReadLookAhead(IN MV_SATA_ADAPTER* pSataAdapter,
147
IN MV_SATA_SCSI_CMD_BLOCK *pScb);
149
static MV_VOID mvAta2HostString(IN MV_U16 *source,
155
for (i=0 ; i < wordsCount; i++)
157
target[i] = (source[i] >> 8) | ((source[i] & 0xff) << 8);
158
target[i] = MV_LE16_TO_CPU(target[i]);
162
MV_VOID setSenseData(IN MV_SATA_SCSI_CMD_BLOCK *pScb, IN MV_U8 SenseKey,
163
IN MV_U8 AdditionalSenseCode, IN MV_U8 ASCQ)
165
MV_SCSI_SENSE_DATA SenseData;
167
if (pScb->senseBufferLength == 0)
169
pScb->senseDataLength = 0;
172
memset(&SenseData, 0, sizeof(MV_SCSI_SENSE_DATA));
173
// SenseData.Valid = 0;
174
SenseData.ResponseCode = MV_SCSI_RESPONSE_CODE;
175
SenseData.SenseKey = SenseKey;
176
SenseData.AdditionalSenseCode = AdditionalSenseCode;
177
SenseData.AdditionalSenseCodeQualifier = ASCQ;
178
SenseData.AdditionalSenseLength = sizeof(MV_SCSI_SENSE_DATA) - 8;
179
pScb->senseDataLength = sizeof(MV_SCSI_SENSE_DATA);
180
if (pScb->senseBufferLength < pScb->senseDataLength)
182
pScb->senseDataLength = pScb->senseBufferLength;
184
memcpy(pScb->pSenseBuffer, &SenseData, pScb->senseDataLength);
187
MV_VOID _fillSenseInformation(IN MV_SATA_SCSI_CMD_BLOCK *pScb, MV_SCSI_SENSE_DATA *SenseData,
188
MV_STORAGE_DEVICE_REGISTERS *registerStruct)
190
if (pScb->isExtended == MV_TRUE)
192
/* LBA 48 error handling */
193
SenseData->InformationDesc.information[2] = (MV_U8)((registerStruct->lbaHighRegister >> 8) & 0xff);
194
SenseData->InformationDesc.information[3] = (MV_U8)((registerStruct->lbaMidRegister >> 8) & 0xff);
195
SenseData->InformationDesc.information[4] = (MV_U8)((registerStruct->lbaLowRegister >> 8) & 0xff);
199
/* LBA 28 error handling */
200
SenseData->InformationDesc.information[4] = (MV_U8)((registerStruct->deviceRegister) & 0x0f);
202
SenseData->InformationDesc.information[5] = (MV_U8)(registerStruct->lbaHighRegister & 0xff);
203
SenseData->InformationDesc.information[6] = (MV_U8)(registerStruct->lbaMidRegister & 0xff);
204
SenseData->InformationDesc.information[7] = (MV_U8)(registerStruct->lbaLowRegister & 0xff);
206
static MV_BOOLEAN checkLBAOutOfRange(IN MV_SATA_ADAPTER* pSataAdapter,
207
IN MV_SATA_SCSI_CMD_BLOCK *pScb,
208
IN MV_U64 ATADiskSize, IN MV_U64 LBA,
211
if ((ATADiskSize <= LBA) || ((ATADiskSize - LBA) < sectors) || sectors > 0xFFFF)
213
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Error LBA out of range. DiskSize %x sectors %x LBA %x\n"
214
, ATADiskSize, sectors, LBA);
216
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
217
SCSI_ADSENSE_ILLEGAL_BLOCK, 0);
218
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
219
pScb->dataTransfered = 0;
220
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
222
reportScbCompletion(pSataAdapter, pScb);
224
pScb->completionCallBack(pSataAdapter, pScb);
230
/*******************************************************************************
231
* mvScsiAtaGetInquiryData - Get the SCSI-3 standard inquiry(12h) data
233
* DESCRIPTION: This function fills the data buffer with Scsi standard inquiry
234
* data according to the ATA Identify data
237
* pSataAdapter - pointer to the SATA adapter data structure.
238
* pScb->bus - the index of the specific SATA channel.
239
* pScb - pointer to the Scsi command block.
242
* MV_TRUE on success, MV_FALSE on failure.
245
* No sanity check is done for the parameters.
247
*******************************************************************************/
249
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetInquiryData(IN MV_SATA_ADAPTER* pSataAdapter,
250
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
254
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
258
if ((pScb->ScsiCdb[1] & (MV_BIT0 | MV_BIT1)) ||
261
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%d %d: Inquiry completed with error: cmd[1] %x cmd[2] %x\n",
262
pSataAdapter->adapterId, pScb->bus, pScb->ScsiCdb[1],
264
if (pDriveData->UAConditionPending == MV_TRUE)
267
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Unit Attention condition is pending.\n");
269
if (pDriveData->UAEvents & MV_BIT0)
271
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Bus Reset.\n");
273
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UA_RESET;
274
setSenseData(pScb, SCSI_SENSE_UNIT_ATTENTION, SCSI_ADSENSE_BUS_RESET
276
pDriveData->UAEvents &= ~MV_BIT0;
278
else if (pDriveData->UAEvents & MV_BIT1)
280
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Mode Parameters Changed.\n");
281
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UA_PARAMS_CHANGED;
282
setSenseData(pScb, SCSI_SENSE_UNIT_ATTENTION,
283
SCSI_ADSENSE_PARAMETERS_CHANGED, 1);
284
pDriveData->UAEvents &= ~MV_BIT1;
287
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
288
pScb->dataTransfered = 0;
290
reportScbCompletion(pSataAdapter, pScb);
292
pScb->completionCallBack(pSataAdapter, pScb);
293
if (pDriveData->UAEvents == 0)
295
pDriveData->UAConditionPending = MV_FALSE;
297
return MV_SCSI_COMMAND_STATUS_COMPLETED;
300
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB,
302
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
303
pScb->dataTransfered = 0;
304
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
306
reportScbCompletion(pSataAdapter, pScb);
308
pScb->completionCallBack(pSataAdapter, pScb);
309
return MV_SCSI_COMMAND_STATUS_COMPLETED;
319
MV_U8 Vendor[9],Product[17], temp[24];
320
buff[0] = MV_SCSI_DIRECT_ACCESS_DEVICE;
321
buff[1] = 0; /* Not Removable disk */
322
buff[2] = 5; /*claim conformance to SCSI-3*/
323
buff[3] = 2; /* set RESPONSE DATA FORMAT to 2*/
324
buff[4] = 41 - 4; /* n - 4, n start from 0 */
326
buff[6] = 0x80; /* basic queuing*/
329
buff[6] = 0x0; /* tagged queuing*/
332
memcpy(temp, pDriveData->identifyInfo.model, 24);
333
mvAta2HostString((MV_U16 *)temp, (MV_U16 *)(temp), 12);
336
for (i = 0; i < 9; i++)
345
if (((temp[0] == 'I') && (temp[1] == 'C')) ||
346
((temp[0] == 'H') && (temp[1] == 'T')) ||
347
((temp[0] == 'H') && (temp[1] == 'D')) ||
348
((temp[0] == 'D') && (temp[1] == 'K')))
360
else if ((temp[0] == 'S') && (temp[1] == 'T'))
386
memcpy(Product, temp, 16);
392
memcpy(Vendor, temp, j);
405
memcpy(Product, &temp[i], 24 - i);
408
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Vendor %s Product %s\n", Vendor, Product);
409
memcpy(&buff[8], Vendor, 8);
410
memcpy(&buff[16], Product, 16);
411
memcpy(&buff[32], pDriveData->identifyInfo.firmware, 4);
412
mvAta2HostString((MV_U16 *)(&buff[32]), (MV_U16 *)(&buff[32]), 2);
414
memcpy(&buff[36], "MVSATA", 6);
420
if (pScb->dataBufferLength > inquiryLen)
422
memcpy(pScb->pDataBuffer, buff, inquiryLen);
423
pScb->dataTransfered = inquiryLen;
427
memcpy(pScb->pDataBuffer, buff, pScb->dataBufferLength);
428
pScb->dataTransfered = pScb->dataBufferLength;
430
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
431
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
432
pScb->senseDataLength = 0;
434
reportScbCompletion(pSataAdapter, pScb);
436
pScb->completionCallBack(pSataAdapter, pScb);
437
return MV_SCSI_COMMAND_STATUS_COMPLETED;
440
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaTestUnitReady(IN MV_SATA_ADAPTER* pSataAdapter,
441
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
443
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
444
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
445
pScb->senseDataLength = 0;
446
pScb->dataTransfered = 0;
449
reportScbCompletion(pSataAdapter, pScb);
451
pScb->completionCallBack(pSataAdapter, pScb);
452
return MV_SCSI_COMMAND_STATUS_COMPLETED;
456
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendDataCommand(IN MV_SATA_ADAPTER* pSataAdapter,
457
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
459
MV_U8 *cmd = pScb->ScsiCdb;
460
MV_QUEUE_COMMAND_RESULT result;
461
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
462
MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
465
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
466
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
467
MV_UDMA_COMMAND_PARAMS *pUdmaParams = &pCommandInfo->commandParams.udmaCommand;
468
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_UDMA;
469
pCommandInfo->PMPort = pScb->target;
470
pUdmaParams->readWrite = MV_UDMA_TYPE_WRITE;
471
pUdmaParams->isEXT = MV_FALSE;
472
pUdmaParams->FUA = MV_FALSE;
473
pUdmaParams->highLBAAddress = 0;
474
pUdmaParams->callBack = SALCommandCompletionCB;
475
pUdmaParams->commandId = (MV_VOID_PTR )pScb;
476
#ifdef MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
477
pUdmaParams->singleDataRegion = pScb->singleDataRegion;
478
pUdmaParams->byteCount = pScb->byteCount;
481
MV_QUEUE_COMMAND_INFO commandInfo =
483
MV_QUEUED_COMMAND_TYPE_UDMA,
487
MV_UDMA_TYPE_WRITE, MV_FALSE, MV_FALSE, 0, 0, 0, 0, 0,
488
#ifdef MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
489
pScb->singleDataRegion,
492
SALCommandCompletionCB, (MV_VOID_PTR )pScb
496
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
497
MV_UDMA_COMMAND_PARAMS *pUdmaParams = &pCommandInfo->commandParams.udmaCommand;
500
if ((cmd[0] == SCSI_OPCODE_READ6) || (cmd[0] == SCSI_OPCODE_WRITE6))
502
pUdmaParams->lowLBAAddress =
504
(((MV_U32) cmd[2]) << 8) |
505
((((MV_U32) cmd[1]) & 0x1f) << 16);
506
sectors = (MV_U16) cmd[4];
508
else if ((cmd[0] == SCSI_OPCODE_READ10) || (cmd[0] == SCSI_OPCODE_WRITE10))
510
pUdmaParams->lowLBAAddress =
511
(((MV_U32) cmd[5]) << 0) |
512
(((MV_U32) cmd[4]) << 8) |
513
(((MV_U32) cmd[3]) << 16) |
514
(((MV_U32) cmd[2]) << 24);
516
sectors = ((MV_U16) cmd[8]) |
517
(((MV_U16) cmd[7]) << 8);
518
if (cmd[1] & MV_BIT3)
520
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%d %d: READ10/WRITE10 command "
521
"received with FUA\n",
522
pSataAdapter->adapterId, pScb->bus);
523
pUdmaParams->FUA = MV_TRUE;
528
pUdmaParams->lowLBAAddress =
529
(((MV_U32) cmd[9]) << 0) |
530
(((MV_U32) cmd[8]) << 8) |
531
(((MV_U32) cmd[7]) << 16) |
532
(((MV_U32) cmd[6]) << 24);
534
pUdmaParams->highLBAAddress =
535
(((MV_U32) cmd[5]) << 0) |
536
(((MV_U32) cmd[4]) << 8) |
537
(((MV_U32) cmd[3]) << 16) |
538
(((MV_U32) cmd[2]) << 24);
540
sectors = (cmd[13]) |
545
if (cmd[1] & MV_BIT3)
547
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%d %d: READ16/WRITE16 command "
548
"received with FUA\n",
549
pSataAdapter->adapterId, pScb->bus);
550
pUdmaParams->FUA = MV_TRUE;
553
LBA = ((MV_U64)pUdmaParams->highLBAAddress << 32) | (MV_U64)pUdmaParams->lowLBAAddress;
554
pScb->isExtended = pUdmaParams->isEXT = pDriveData->identifyInfo.LBA48Supported;
556
/* If READ10 / WRITE10 with 0 sectors (no data transfer), then complete */
557
/* the command with OK. */
558
/* If READ6 / WRITE6 with 0 sectors, seemse the Windows have problem with */
559
/* this and doesn't allocate and buffers for this ; so complete this */
560
/* command with ILLEGAL REQUEST sense and INVLAID CDB in addition sense */
565
if ((cmd[0] == SCSI_OPCODE_READ10) || (cmd[0] == SCSI_OPCODE_WRITE10) ||
566
(cmd[0] == SCSI_OPCODE_WRITE16) || (cmd[0] == SCSI_OPCODE_WRITE16))
569
if (checkLBAOutOfRange(pSataAdapter, pScb,
570
pDriveData->identifyInfo.ATADiskSize,
573
return MV_SCSI_COMMAND_STATUS_COMPLETED;
575
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
576
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
577
pScb->dataTransfered = 0;
578
pScb->senseDataLength = 0;
580
reportScbCompletion(pSataAdapter, pScb);
582
pScb->completionCallBack(pSataAdapter, pScb);
583
return MV_SCSI_COMMAND_STATUS_COMPLETED;
587
/* READ6 / WRITE6 with sector count 0, which means 256 sectors */
591
if (checkLBAOutOfRange(pSataAdapter, pScb,
592
pDriveData->identifyInfo.ATADiskSize,
593
LBA, sectors) == MV_TRUE)
595
return MV_SCSI_COMMAND_STATUS_COMPLETED;
598
/* If trying to send more than 256 sectors or DataTransferLength field is
599
* not equal to number of sectors request in CDB then return invalid
603
if (((sectors > 256) && (pUdmaParams->isEXT == MV_FALSE)) ||
604
((sectors * ATA_SECTOR_SIZE) != pScb->dataBufferLength))
606
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
607
pScb->dataTransfered = 0;
608
pScb->senseDataLength = 0;
610
reportScbCompletion(pSataAdapter, pScb);
612
pScb->completionCallBack(pSataAdapter, pScb);
613
return MV_SCSI_COMMAND_STATUS_COMPLETED;
616
if ((cmd[0] == SCSI_OPCODE_READ6) || (cmd[0] == SCSI_OPCODE_READ10) ||
617
(cmd[0] == SCSI_OPCODE_READ16))
619
pUdmaParams->readWrite = MV_UDMA_TYPE_READ;
621
pScb->dataTransfered = sectors * ATA_SECTOR_SIZE;
622
pScb->udmaType = pUdmaParams->readWrite;
623
pScb->commandType = MV_QUEUED_COMMAND_TYPE_UDMA;
624
pScb->LowLbaAddress = pUdmaParams->lowLBAAddress;
625
pUdmaParams->numOfSectors = sectors;
627
if ((sectors == 256) &&
628
((pDriveData->identifyInfo.LBA48Supported == MV_FALSE)))
630
pUdmaParams->numOfSectors = 0;
632
pUdmaParams->prdLowAddr = pScb->PRDTableLowPhyAddress;
633
pUdmaParams->prdHighAddr = pScb->PRDTableHighPhyAddress;
635
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
636
if (result != MV_QUEUE_COMMAND_RESULT_OK)
638
checkQueueCommandResult(pScb, result);
640
reportScbCompletion(pSataAdapter, pScb);
642
pScb->completionCallBack(pSataAdapter, pScb);
643
return MV_SCSI_COMMAND_STATUS_COMPLETED;
646
/*update statistics*/
648
pAdapterExt->totalAccumulatedOutstanding[pScb->bus] +=
649
mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
650
pDriveData->stats.totalIOs++;
651
pDriveData->stats.totalSectorsTransferred += pUdmaParams->numOfSectors;
653
return MV_SCSI_COMMAND_STATUS_QUEUED;
656
/*******************************************************************************
657
* mvScsiAtaGetReadCapacityData - Get the SCSI-3 Read Capacity (10h/16h) data
659
* DESCRIPTION: This function fills the data buffer with Scsi Read Capacity 10 or
660
* Read Capacity 16 data according to the disk size as it is reported in
661
* the ATA Identify data.
664
* pSataAdapter - pointer to the SATA adapter data structure.
665
* pScb->bus - the index of the specific SATA channel.
669
* MV_TRUE on success, MV_FALSE on failure.
672
* No sanity check is done for the parameters.
674
*******************************************************************************/
675
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetReadCapacityData(IN MV_SATA_ADAPTER* pSataAdapter,
676
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
678
MV_U32 lastAddressableLBA;
680
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
682
if ((pScb->ScsiCdb[8] & MV_BIT1) == 0)
684
if (pScb->ScsiCdb[2] || pScb->ScsiCdb[3] ||pScb->ScsiCdb[4] ||
688
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Inquiry completed with error: PMI = 0, LBA != 0\n",
689
pSataAdapter->adapterId, pScb->bus);
690
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
691
SCSI_ADSENSE_INVALID_CDB, 0);
692
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
693
pScb->dataTransfered = 0;
694
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
696
reportScbCompletion(pSataAdapter, pScb);
698
pScb->completionCallBack(pSataAdapter, pScb);
699
return MV_SCSI_COMMAND_STATUS_COMPLETED;
702
if((pDriveData->identifyInfo.ATADiskSize >> 32) & 0xFFFFFFFF)
704
lastAddressableLBA = 0xFFFFFFFF;
708
lastAddressableLBA = pDriveData->identifyInfo.ATADiskSize - 1;
710
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "MVSATA: last Addressable sector = 0x%x "
711
" (sec size=%d bytes)\n", lastAddressableLBA, ATA_SECTOR_SIZE);
713
/* The disk size as indicated by the ATA spec is the total addressable
714
* secotrs on the drive ; while the SCSI translation of the command
715
* should be the last addressable sector.
717
buff = pScb->pDataBuffer;
718
memset(buff, 0, pScb->dataBufferLength);
719
buff[0] = (MV_U8)(lastAddressableLBA >> 24);
720
buff[1] = (MV_U8)((lastAddressableLBA >> 16) & 0xff);
721
buff[2] = (MV_U8)((lastAddressableLBA >> 8) & 0xff);
722
buff[3] = (MV_U8)(lastAddressableLBA & 0xff);
725
buff[6] = (MV_U8)((ATA_SECTOR_SIZE >> 8) & 0xff); /* 512 byte sectors */
726
buff[7] = (MV_U8)(ATA_SECTOR_SIZE & 0xff);
727
pScb->dataTransfered = 8;
728
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
729
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
730
pScb->senseDataLength = 0;
732
reportScbCompletion(pSataAdapter, pScb);
734
pScb->completionCallBack(pSataAdapter, pScb);
735
return MV_SCSI_COMMAND_STATUS_COMPLETED;
738
/*******************************************************************************
739
* mvScsiAtaGetReadCapacity16Data - Get the SCSI-3 Read Capacity (16h) data
741
* DESCRIPTION: This function fills the data buffer with Scsi Read Capacity 16
742
* data according to the disk size as it is reported in
743
* the ATA Identify data.
746
* pSataAdapter - pointer to the SATA adapter data structure.
747
* pScb->bus - the index of the specific SATA channel.
751
* MV_TRUE on success, MV_FALSE on failure.
754
* No sanity check is done for the parameters.
756
*******************************************************************************/
757
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetReadCapacity16Data(IN MV_SATA_ADAPTER* pSataAdapter,
758
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
760
MV_U64 lastAddressableLBA;
762
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
764
if ((pScb->ScsiCdb[14] & MV_BIT1) == 0)
766
if (pScb->ScsiCdb[2] || pScb->ScsiCdb[3] ||pScb->ScsiCdb[4] ||
767
pScb->ScsiCdb[5] || pScb->ScsiCdb[6] ||pScb->ScsiCdb[7] ||
768
pScb->ScsiCdb[8] || pScb->ScsiCdb[9])
771
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Read Capacity completed with error: PMI = 0, LBA != 0\n",
772
pSataAdapter->adapterId, pScb->bus);
773
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
774
SCSI_ADSENSE_INVALID_CDB, 0);
775
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
776
pScb->dataTransfered = 0;
777
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
779
reportScbCompletion(pSataAdapter, pScb);
781
pScb->completionCallBack(pSataAdapter, pScb);
782
return MV_SCSI_COMMAND_STATUS_COMPLETED;
786
lastAddressableLBA = pDriveData->identifyInfo.ATADiskSize - 1;
787
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "MVSATA: last Addressable sector = 0x%x "
788
" (sec size=%d bytes)\n", lastAddressableLBA, ATA_SECTOR_SIZE);
790
/* The disk size as indicated by the ATA spec is the total addressable
791
* secotrs on the drive ; while the SCSI translation of the command
792
* should be the last addressable sector.
794
buff = pScb->pDataBuffer;
795
memset(buff, 0, pScb->dataBufferLength);
796
buff[0] = (MV_U8)((lastAddressableLBA >> 56) & 0xff);
797
buff[1] = (MV_U8)((lastAddressableLBA >> 48) & 0xff);
798
buff[2] = (MV_U8)((lastAddressableLBA >> 40) & 0xff);
799
buff[3] = (MV_U8)((lastAddressableLBA >> 32) & 0xff);
800
buff[4] = (MV_U8)((lastAddressableLBA >> 24) & 0xff);
801
buff[5] = (MV_U8)((lastAddressableLBA >> 16) & 0xff);
802
buff[6] = (MV_U8)((lastAddressableLBA >> 8) & 0xff);
803
buff[7] = (MV_U8)(lastAddressableLBA & 0xff);
806
buff[10] = (MV_U8)((ATA_SECTOR_SIZE >> 8) & 0xff); /* 512 byte sectors */
807
buff[11] = (MV_U8)(ATA_SECTOR_SIZE & 0xff);
808
pScb->dataTransfered = 8;
809
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
810
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
811
pScb->senseDataLength = 0;
813
reportScbCompletion(pSataAdapter, pScb);
815
pScb->completionCallBack(pSataAdapter, pScb);
816
return MV_SCSI_COMMAND_STATUS_COMPLETED;
820
/*******************************************************************************
821
* mvScsiAtaReportLuns - handle the SCSI-3 Report LUNS
823
* DESCRIPTION: Report 1 LUN
826
* pSataAdapter - pointer to the SATA adapter data structure.
827
* pScb->bus - the index of the specific SATA channel.
831
* MV_TRUE on success, MV_FALSE on failure.
834
* No sanity check is done for the parameters.
836
*******************************************************************************/
837
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaReportLuns(IN MV_SATA_ADAPTER* pSataAdapter,
838
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
843
buff = pScb->pDataBuffer;
844
memset(buff, 0, pScb->dataBufferLength);
845
buff[3] = 8; /* 1 lun*/
846
pScb->dataTransfered = 16;
847
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
848
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
849
pScb->senseDataLength = 0;
851
reportScbCompletion(pSataAdapter, pScb);
853
pScb->completionCallBack(pSataAdapter, pScb);
854
return MV_SCSI_COMMAND_STATUS_COMPLETED;
857
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendVerifyCommand(IN MV_SATA_ADAPTER* pSataAdapter,
858
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
860
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
861
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
863
MV_QUEUE_COMMAND_INFO commandInfo;
864
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
866
MV_QUEUE_COMMAND_RESULT result;
867
MV_U8 *cmd = pScb->ScsiCdb;
871
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
872
MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
874
if (cmd[0] == SCSI_OPCODE_VERIFY6)
877
( (unsigned) cmd[3]) |
878
(((unsigned) cmd[2]) << 8) |
879
((((unsigned) cmd[1]) & 0x1f) << 16);
880
sectors = (unsigned) cmd[4];
882
else if (cmd[0] == SCSI_OPCODE_VERIFY10)
885
(((unsigned) cmd[5]) << 0) |
886
(((unsigned) cmd[4]) << 8) |
887
(((unsigned) cmd[3]) << 16) |
888
(((unsigned) cmd[2]) << 24);
891
sectors = ((unsigned) cmd[8]) |
892
(((unsigned) cmd[7]) << 8);
897
(((MV_U64) cmd[9]) << 0) |
898
(((MV_U64) cmd[8]) << 8) |
899
(((MV_U64) cmd[7]) << 16) |
900
(((MV_U64) cmd[6]) << 24) |
901
(((MV_U64) cmd[5]) << 32) |
902
(((MV_U64) cmd[4]) << 40) |
903
(((MV_U64) cmd[3]) << 48) |
904
(((MV_U64) cmd[2]) << 56);
908
((unsigned) cmd[13]) |
909
(((unsigned) cmd[12]) << 8) |
910
(((unsigned) cmd[11]) << 16) |
911
(((unsigned) cmd[10]) << 24);
916
if ((cmd[0] == SCSI_OPCODE_VERIFY10) || (cmd[0] == SCSI_OPCODE_VERIFY16))
918
if (checkLBAOutOfRange(pSataAdapter, pScb,
919
pDriveData->identifyInfo.ATADiskSize,
920
LbaAddress, 0) == MV_TRUE)
922
return MV_SCSI_COMMAND_STATUS_COMPLETED;
924
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
925
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
926
pScb->senseDataLength = 0;
927
pScb->dataTransfered = 0;
929
reportScbCompletion(pSataAdapter, pScb);
931
pScb->completionCallBack(pSataAdapter, pScb);
932
return MV_SCSI_COMMAND_STATUS_COMPLETED;
936
/* If VERIFY6 to 48bit device, then 256 sectors is OK ; otherwise
937
the CORE driver must get sector count of 0 in order to understand that
938
256 sectors must be transferred
941
if (pDriveData->identifyInfo.LBA48Supported == MV_TRUE)
950
if (checkLBAOutOfRange(pSataAdapter, pScb,
951
pDriveData->identifyInfo.ATADiskSize,
952
LbaAddress, 256) == MV_TRUE)
954
return MV_SCSI_COMMAND_STATUS_COMPLETED;
959
if (checkLBAOutOfRange(pSataAdapter, pScb,
960
pDriveData->identifyInfo.ATADiskSize,
961
LbaAddress, sectors) == MV_TRUE)
963
return MV_SCSI_COMMAND_STATUS_COMPLETED;
967
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
968
pScb->LowLbaAddress = (MV_U32)(LbaAddress & 0xFFFFFFFF);
969
// pScb->highLbaAddress = (MV_U32)(LbaAddress >> 32);
971
if (pDriveData->identifyInfo.LBA48Supported == MV_TRUE)
973
pScb->splitCount = 1;
974
pScb->isExtended = MV_TRUE;
975
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
976
pCommandInfo->PMPort = pScb->target;
977
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = NULL;
978
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
979
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_READ_VERIFY_SECTORS_EXT;
980
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
981
pCommandInfo->commandParams.NoneUdmaCommand.count = 0;
982
pCommandInfo->commandParams.NoneUdmaCommand.features = 0;
983
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_TRUE;
984
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh =
985
(MV_U16)(((LbaAddress & 0xff0000000000ULL) >> 40) | ((LbaAddress & 0xff0000) >> 16));
986
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid =
987
(MV_U16)(((LbaAddress & 0xff00000000ULL) >> 32) | ((LbaAddress & 0xff00) >> 8));
988
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow =
989
(MV_U16)(((LbaAddress & 0xff000000) >> 24) | (LbaAddress & 0xff));
990
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_NON_DATA;
991
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = sectors;
992
pCommandInfo->commandParams.NoneUdmaCommand.device = (MV_U8)(MV_BIT6);
994
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending EXT Verify command: channel %d, code %x lba %x(%x.%x.%x), sectors %d[%d] Srb %p\n",
995
pScb->bus, cmd[0], LbaAddress,
996
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh,
997
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid,
998
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow,
999
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount,
1000
mvSataNumOfDmaCommands(pSataAdapter,pScb->bus), pScb);
1002
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1004
if (result != MV_QUEUE_COMMAND_RESULT_OK)
1006
checkQueueCommandResult(pScb, result);
1008
reportScbCompletion(pSataAdapter, pScb);
1010
pScb->completionCallBack(pSataAdapter, pScb);
1011
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1014
pAdapterExt->totalAccumulatedOutstanding[pScb->bus] +=
1015
mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1016
pDriveData->stats.totalIOs++;
1017
pDriveData->stats.totalSectorsTransferred += sectors;
1022
/* The following only in case command is VERIFY 6 with 0 sector count */
1029
commands = (MV_U16)((((MV_U32)sectors + 0xff) & 0x1ff00) >> 8);
1032
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "split Verify to %d commands: channel %d, lba %x, sectors %d\n",
1033
commands,pScb->bus, LbaAddress, sectors);
1035
pScb->splitCount = commands;
1036
pScb->sequenceNumber = 0;
1037
pScb->isExtended = MV_FALSE;
1038
mvScsiAtaSendSplittedVerifyCommand(pScb);
1040
return MV_SCSI_COMMAND_STATUS_QUEUED;
1043
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSeek(IN MV_SATA_ADAPTER *pSataAdapter,
1044
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1047
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1049
lbaAddress = (((MV_U32) pScb->ScsiCdb[5]) << 0) |
1050
(((MV_U32) pScb->ScsiCdb[4]) << 8) |
1051
(((MV_U32) pScb->ScsiCdb[3]) << 16) |
1052
(((MV_U32) pScb->ScsiCdb[2]) << 24);
1053
if (checkLBAOutOfRange(pSataAdapter, pScb,
1054
pDriveData->identifyInfo.ATADiskSize,
1055
lbaAddress, 0) == MV_TRUE)
1057
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1059
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1060
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1061
pScb->dataTransfered = 0;
1062
pScb->senseDataLength = 0;
1064
reportScbCompletion(pSataAdapter, pScb);
1066
pScb->completionCallBack(pSataAdapter, pScb);
1067
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1071
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaReassignBlocks(IN MV_SATA_ADAPTER *pSataAdapter,
1072
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1074
setSenseData(pScb, SCSI_SENSE_HARDWARE_ERROR, 0x32, 0);
1075
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1076
pScb->dataTransfered = 0;
1077
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_ATA_FAILED;
1079
reportScbCompletion(pSataAdapter, pScb);
1081
pScb->completionCallBack(pSataAdapter, pScb);
1087
#ifdef MV_SATA_SUPPORT_READ_WRITE_LONG
1088
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaWriteLong(IN MV_SATA_ADAPTER *pSataAdapter,
1089
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1091
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1092
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
1094
MV_QUEUE_COMMAND_INFO commandInfo;
1095
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
1097
MV_QUEUE_COMMAND_RESULT result;
1100
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1101
MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
1103
memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1106
LBA = (((MV_U32) pScb->ScsiCdb[5]) << 0) |
1107
(((MV_U32) pScb->ScsiCdb[4]) << 8) |
1108
(((MV_U32) pScb->ScsiCdb[3]) << 16) |
1109
(((MV_U32) pScb->ScsiCdb[2]) << 24);
1111
eccBytes = (MV_U16)pScb->ScsiCdb[8];
1113
if ((pScb->ScsiCdb[7] != 2) || ((eccBytes != 4) && (eccBytes != 8)))
1115
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
1116
pScb->dataTransfered = 0;
1117
pScb->senseDataLength = 0;
1119
reportScbCompletion(pSataAdapter, pScb);
1121
pScb->completionCallBack(pSataAdapter, pScb);
1122
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1124
if (checkLBAOutOfRange(pSataAdapter, pScb,
1125
pDriveData->identifyInfo.ATADiskSize,
1128
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1131
/*if (checkLBAOutOfRange(pSataAdapter, pScb, MV_BIT28 - 2,
1134
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1136
if (LBA & (MV_BIT31|MV_BIT30|MV_BIT29|MV_BIT28))
1139
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Error LBA (0x%x) out of range.\n", LBA);
1141
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1142
SCSI_ADSENSE_ILLEGAL_BLOCK, 0);
1143
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1144
pScb->dataTransfered = 0;
1145
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1147
reportScbCompletion(pSataAdapter, pScb);
1149
pScb->completionCallBack(pSataAdapter, pScb);
1152
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1154
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1155
pCommandInfo->PMPort = pScb->target;
1156
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = (MV_U16_PTR)pScb->pDataBuffer;
1157
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
1158
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
1159
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
1160
pCommandInfo->commandParams.NoneUdmaCommand.count = 256+4;
1161
pCommandInfo->commandParams.NoneUdmaCommand.features = eccBytes;
1162
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh = (MV_U16)((LBA & 0xff0000) >> 16);
1163
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid = (MV_U16)((LBA & 0xff00) >> 8) ;
1164
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow = (MV_U16)LBA & 0xff;
1165
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_PIO_DATA_OUT;
1166
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = 1;
1167
pCommandInfo->commandParams.NoneUdmaCommand.device = MV_BIT6 | (MV_U16)((LBA & 0xf000000) >> 24) ;
1168
pScb->isExtended = MV_FALSE;
1169
pCommandInfo->commandParams.NoneUdmaCommand.command = 0x32;
1172
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending WRITE LONG command : channel %d, code %x pScb %p\n",
1173
pScb->bus, pScb->ScsiCdb[0], pScb);
1175
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1176
if (result != MV_QUEUE_COMMAND_RESULT_OK)
1178
checkQueueCommandResult(pScb, result);
1179
/* shoudl complete the Scsi request here*/
1181
reportScbCompletion(pSataAdapter, pScb);
1183
pScb->completionCallBack(pSataAdapter, pScb);
1184
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1187
pAdapterExt->totalAccumulatedOutstanding[pScb->bus] += mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1188
pDriveData->stats.totalIOs++;
1190
return MV_SCSI_COMMAND_STATUS_QUEUED;
1192
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaReadLong(IN MV_SATA_ADAPTER *pSataAdapter,
1193
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1195
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1196
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
1198
MV_QUEUE_COMMAND_INFO commandInfo;
1199
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
1201
MV_QUEUE_COMMAND_RESULT result;
1204
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1205
MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
1207
memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1210
LBA = (((MV_U32) pScb->ScsiCdb[5]) << 0) |
1211
(((MV_U32) pScb->ScsiCdb[4]) << 8) |
1212
(((MV_U32) pScb->ScsiCdb[3]) << 16) |
1213
(((MV_U32) pScb->ScsiCdb[2]) << 24);
1215
eccBytes = (MV_U16)pScb->ScsiCdb[8];
1217
if ((pScb->ScsiCdb[7] != 2) || ((eccBytes != 4) && (eccBytes != 8)))
1219
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
1220
pScb->dataTransfered = 0;
1221
pScb->senseDataLength = 0;
1223
reportScbCompletion(pSataAdapter, pScb);
1225
pScb->completionCallBack(pSataAdapter, pScb);
1226
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1228
if (checkLBAOutOfRange(pSataAdapter, pScb,
1229
pDriveData->identifyInfo.ATADiskSize,
1232
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1235
/*if (checkLBAOutOfRange(pSataAdapter, pScb, MV_BIT28 - 2,
1238
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1240
if (LBA & (MV_BIT31|MV_BIT30|MV_BIT29|MV_BIT28))
1243
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Error LBA (0x%x) out of range.\n", LBA);
1245
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1246
SCSI_ADSENSE_ILLEGAL_BLOCK, 0);
1247
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1248
pScb->dataTransfered = 0;
1249
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1251
reportScbCompletion(pSataAdapter, pScb);
1253
pScb->completionCallBack(pSataAdapter, pScb);
1256
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1258
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1259
pCommandInfo->PMPort = pScb->target;
1260
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = (MV_U16_PTR)pScb->pDataBuffer;
1261
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
1262
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
1263
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
1264
pCommandInfo->commandParams.NoneUdmaCommand.count = 256+4;
1265
pCommandInfo->commandParams.NoneUdmaCommand.features = eccBytes;
1266
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh = (MV_U16)((LBA & 0xff0000) >> 16);
1267
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid = (MV_U16)((LBA & 0xff00) >> 8) ;
1268
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow = (MV_U16)LBA & 0xff;
1269
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_PIO_DATA_IN;
1270
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = 1;
1271
pCommandInfo->commandParams.NoneUdmaCommand.device = MV_BIT6 | (MV_U16)((LBA & 0xf000000) >> 24) ;
1272
pScb->isExtended = MV_FALSE;
1273
pCommandInfo->commandParams.NoneUdmaCommand.command = 0x22;
1276
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending READ LONG command : channel %d, code %x pScb %p\n",
1277
pScb->bus, pScb->ScsiCdb[0], pScb);
1279
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1280
if (result != MV_QUEUE_COMMAND_RESULT_OK)
1282
checkQueueCommandResult(pScb, result);
1283
/* shoudl complete the Scsi request here*/
1285
reportScbCompletion(pSataAdapter, pScb);
1287
pScb->completionCallBack(pSataAdapter, pScb);
1288
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1291
pAdapterExt->totalAccumulatedOutstanding[pScb->bus] += mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1292
pDriveData->stats.totalIOs++;
1294
return MV_SCSI_COMMAND_STATUS_QUEUED;
1297
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendSyncCacheCommand(IN MV_SATA_ADAPTER *pSataAdapter,
1298
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1300
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1301
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
1303
MV_QUEUE_COMMAND_INFO commandInfo;
1304
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
1306
MV_QUEUE_COMMAND_RESULT result;
1309
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1310
MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
1312
/* Check if IMMED bit is set, if so then return ILLEGAL REQUEST */
1313
if (pScb->ScsiCdb[1] & MV_BIT1)
1315
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Synchronise cache completed with error:"
1316
" IMMED is set\n", pSataAdapter->adapterId,
1319
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB,
1321
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1322
pScb->dataTransfered = 0;
1323
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1325
reportScbCompletion(pSataAdapter, pScb);
1327
pScb->completionCallBack(pSataAdapter, pScb);
1328
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1331
memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1333
if(pScb->ScsiCdb[0] == SCSI_OPCODE_SYNCHRONIZE_CACHE10)
1335
LBA = (((MV_U64) pScb->ScsiCdb[5]) << 0) |
1336
(((MV_U64) pScb->ScsiCdb[4]) << 8) |
1337
(((MV_U64) pScb->ScsiCdb[3]) << 16) |
1338
(((MV_U64) pScb->ScsiCdb[2]) << 24);
1340
sectors = ((MV_U32) pScb->ScsiCdb[8]) |
1341
(((MV_U32) pScb->ScsiCdb[7]) << 8);
1345
LBA = (((MV_U64) pScb->ScsiCdb[9]) << 0) |
1346
(((MV_U64) pScb->ScsiCdb[8]) << 8) |
1347
(((MV_U64) pScb->ScsiCdb[7]) << 16) |
1348
(((MV_U64) pScb->ScsiCdb[6]) << 24) |
1349
(((MV_U64) pScb->ScsiCdb[5]) << 32) |
1350
(((MV_U64) pScb->ScsiCdb[4]) << 40) |
1351
(((MV_U64) pScb->ScsiCdb[3]) << 48) |
1352
(((MV_U64) pScb->ScsiCdb[2]) << 56);
1354
sectors = ((MV_U32) pScb->ScsiCdb[13]) |
1355
(((MV_U32) pScb->ScsiCdb[12]) << 8) |
1356
(((MV_U32) pScb->ScsiCdb[11]) << 16) |
1357
(((MV_U32) pScb->ScsiCdb[10]) << 24);
1359
if (checkLBAOutOfRange(pSataAdapter, pScb,
1360
pDriveData->identifyInfo.ATADiskSize,LBA, sectors)
1363
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1366
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1368
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1369
pCommandInfo->PMPort = pScb->target;
1370
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = NULL;
1371
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
1372
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
1373
pCommandInfo->commandParams.NoneUdmaCommand.count = 0;
1374
pCommandInfo->commandParams.NoneUdmaCommand.features = 0;
1375
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh = 0;
1376
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid = 0;
1377
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow = 0;
1378
pCommandInfo->commandParams.NoneUdmaCommand.protocolType =
1379
MV_NON_UDMA_PROTOCOL_NON_DATA;
1380
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = 0;
1381
pCommandInfo->commandParams.NoneUdmaCommand.device = (MV_U8)(MV_BIT6);
1383
if (pDriveData->identifyInfo.LBA48Supported == MV_TRUE)
1385
pScb->isExtended = MV_TRUE;
1386
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_FLUSH_CACHE_EXT;
1387
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_TRUE;
1391
pScb->isExtended = MV_FALSE;
1392
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_FLUSH_CACHE;
1393
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
1396
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending Flush Cache command : channel %d, code %x (extended -->"
1397
" %s) pScb %p\n", pScb->bus, pScb->ScsiCdb[0],
1398
(pScb->isExtended == MV_TRUE) ? "Yes":"No", pScb);
1400
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1401
if (result != MV_QUEUE_COMMAND_RESULT_OK)
1403
checkQueueCommandResult(pScb, result);
1404
/* shoudl complete the Scsi request here*/
1406
reportScbCompletion(pSataAdapter, pScb);
1408
pScb->completionCallBack(pSataAdapter, pScb);
1409
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1412
pAdapterExt->totalAccumulatedOutstanding[pScb->bus] += mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1413
pDriveData->stats.totalIOs++;
1415
return MV_SCSI_COMMAND_STATUS_QUEUED;
1418
/*******************************************************************************
1419
* mvScsiAtaGetRequestSenseData - Get the SCSI-3 Request Sense(03h) data
1421
* DESCRIPTION: This function fills the sense buffer with a sense key of NO SENSE
1422
* and an additional sense code of NO ADDITIONAL SENSE INFORMATION.
1425
* pSataAdapter - pointer to the SATA adapter data structure.
1426
* pScb->bus - the index of the specific SATA channel.
1427
* Cdb - specifies the SCSI-3 command descriptor block.
1430
* pScsiStatus - pointer to the Scsi status to be returned.
1431
* pSenseBuffer - pointer to the Scsi sense buffer.
1432
* senseBufferLength - the size in bytes of the sense buffer.
1433
* pDataTransfered - the size in bytes of the data transfered into the data
1434
* buffer(alwasy zero for this command).
1437
* MV_TRUE on success, MV_FALSE on failure.
1440
* No sanity check is done for the parameters.
1442
*******************************************************************************/
1443
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetRequestSenseData(IN MV_SATA_ADAPTER* pSataAdapter,
1444
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1446
MV_SCSI_SENSE_DATA SenseData;
1447
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1449
memset(pScb->pDataBuffer, 0, pScb->dataBufferLength);
1451
memset(&SenseData, 0, sizeof(MV_SCSI_SENSE_DATA));
1452
// SenseData.Valid = 0;
1453
SenseData.ResponseCode = MV_SCSI_RESPONSE_CODE;
1454
SenseData.SenseKey = SCSI_SENSE_NO_SENSE;
1455
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
1456
SenseData.AdditionalSenseLength = sizeof(MV_SCSI_SENSE_DATA) - 8;
1458
pScb->senseDataLength = 0;
1459
if (pDriveData->UAConditionPending == MV_TRUE)
1461
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Unit Attention condition is pending.\n");
1462
SenseData.SenseKey = SCSI_SENSE_UNIT_ATTENTION;
1463
if (pDriveData->UAEvents & MV_BIT0)
1465
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Bus Reset.\n");
1467
SenseData.AdditionalSenseCode = SCSI_ADSENSE_BUS_RESET;
1468
SenseData.AdditionalSenseCodeQualifier = 2;
1469
pDriveData->UAEvents &= ~MV_BIT0;
1471
else if (pDriveData->UAEvents & MV_BIT1)
1473
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Mode Parameters Changed.\n");
1474
SenseData.AdditionalSenseCode = SCSI_ADSENSE_PARAMETERS_CHANGED;
1475
SenseData.AdditionalSenseCodeQualifier = 1;
1476
pDriveData->UAEvents &= ~MV_BIT1;
1479
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1480
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1481
if (pDriveData->UAEvents == 0)
1483
pDriveData->UAConditionPending = MV_FALSE;
1488
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1489
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1491
if (pScb->dataBufferLength >= sizeof(MV_SCSI_SENSE_DATA))
1493
pScb->dataTransfered = sizeof(MV_SCSI_SENSE_DATA);
1494
memcpy(pScb->pDataBuffer, &SenseData, pScb->dataTransfered);
1495
/*pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;*/
1496
/*pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;*/
1500
pScb->dataTransfered = pScb->dataBufferLength;
1501
memcpy(pScb->pDataBuffer, &SenseData, pScb->dataTransfered);
1502
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;/*TBD*/
1503
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1506
reportScbCompletion(pSataAdapter, pScb);
1508
pScb->completionCallBack(pSataAdapter, pScb);
1509
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1512
/*******************************************************************************
1513
* mvScsiAtaGetModeSenseData - Get the SCSI-3 Mode Sense data
1515
* DESCRIPTION: This function issues ATA Identify command, in the command
1516
* completion, the Mode Sense data will be filled according to the returned
1520
* pSataAdapter - pointer to the SATA adapter data structure.
1521
* pScb->bus - the index of the specific SATA channel.
1522
* Cdb - specifies the SCSI-3 command descriptor block.
1525
* MV_TRUE on success, MV_FALSE on failure.
1528
* No sanity check is done for the parameters.
1530
*******************************************************************************/
1531
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaGetModeSenseData(IN MV_SATA_ADAPTER *pSataAdapter,
1532
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1534
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1535
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
1537
MV_QUEUE_COMMAND_INFO commandInfo;
1538
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
1540
MV_QUEUE_COMMAND_RESULT result;
1541
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1543
memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1544
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1545
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1546
pCommandInfo->PMPort = pScb->target;
1547
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = pDriveData->identifyBuffer;
1548
pCommandInfo->commandParams.NoneUdmaCommand.count = 256; /* 512 bytes */
1549
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
1550
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_IDENTIFY;
1551
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
1552
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
1553
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_PIO_DATA_IN;
1554
pCommandInfo->commandParams.NoneUdmaCommand.device = (MV_U8)(MV_BIT6);
1555
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending Identify command: channel %d, Srb %p\n",
1558
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1559
if (result != MV_QUEUE_COMMAND_RESULT_OK)
1561
checkQueueCommandResult(pScb, result);
1562
/* shoudl complete the Scsi request here*/
1564
reportScbCompletion(pSataAdapter, pScb);
1566
pScb->completionCallBack(pSataAdapter, pScb);
1567
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1570
return MV_SCSI_COMMAND_STATUS_QUEUED;
1572
static MV_BOOLEAN mvScsiAtaGetModeSenseDataPhase2(IN MV_SATA_ADAPTER *pSataAdapter,
1573
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1575
MV_U8 AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
1576
MV_U8 *cmd = pScb->ScsiCdb;
1577
MV_U8 pageCode= cmd[2] & 0x3f;
1578
MV_U8 pageControl = (MV_U8)((cmd[2] & 0xc0) >> 6);
1579
MV_U8 modeSenseResult[MV_MAX_MODE_SENSE_RESULT_LENGTH];
1582
MV_BOOLEAN commandFailed = MV_FALSE;
1584
memset(pScb->pDataBuffer, 0, pScb->dataBufferLength);
1585
memset(modeSenseResult, 0, MV_MAX_MODE_SENSE_RESULT_LENGTH);
1586
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Sense: cmd[2] 0x%xcode 0x%x control 0x%x "
1587
"allocation length %d \n", pSataAdapter->adapterId, pScb->bus,
1588
cmd[2], pageCode, pageControl, (MV_U32)cmd[4]);
1591
if (pageControl == 0x3)
1593
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Sense: save control not supported\n.",
1594
pSataAdapter->adapterId, pScb->bus);
1595
AdditionalSenseCode = 0x39; /*SAVING PARAMETERS NOT SUPPORTED */
1596
commandFailed = MV_TRUE;
1598
if (commandFailed != MV_TRUE)
1600
memset(modeSenseResult, 0, MV_MAX_MODE_SENSE_RESULT_LENGTH);
1601
/*1. Mode parameter header*/
1602
/* Mode data length will be set later */
1603
/* Medium Type 0: Default medium type */
1604
/* Device-specific parameter 0: write enabled, target */
1605
/* supports the DPO and FUA bits only in NCQ mode*/
1606
if (pSataAdapter->sataChannel[pScb->bus]->queuedDMA == MV_EDMA_MODE_NATIVE_QUEUING)
1608
modeSenseResult[2] = MV_BIT4;
1611
/* Block descriptor length 0: no block descriptors*/
1613
/*2. Block descriptor(s): Empty list*/
1620
case 0x8: /*Caching page */
1621
pageLength = mvModeSenseCachingPage(pScb,
1622
modeSenseResult + offset,
1625
offset += pageLength;
1627
if (pageCode == 0x8)
1632
pageLength = mvModeSenseControlPage(pSataAdapter,pScb,
1633
modeSenseResult + offset,
1636
offset += pageLength;
1639
AdditionalSenseCode = SCSI_ADSENSE_INVALID_CDB;
1640
commandFailed = MV_TRUE;
1643
/* set the DATA LENGTH of the Mode parameter list not including the number*/
1644
/* of bytes of the DATA LENGTH itself ( 1 byte for Mode Selet(6)) */
1645
modeSenseResult[0] = (MV_U8)(offset - 1);
1647
if (pScb->dataBufferLength < offset)
1649
memcpy(pScb->pDataBuffer, modeSenseResult, pScb->dataBufferLength);
1650
pScb->dataTransfered = pScb->dataBufferLength;
1654
memcpy(pScb->pDataBuffer, modeSenseResult, offset);
1655
pScb->dataTransfered = offset;
1659
if (commandFailed == MV_TRUE)
1661
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, AdditionalSenseCode, 0);
1663
pScb->dataTransfered = 0;
1664
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1665
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1669
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1670
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1674
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaModeSelect(IN MV_SATA_ADAPTER *pSataAdapter,
1675
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
1678
MV_SCSI_COMMAND_STATUS_TYPE commandStatus;
1679
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " MODE SELECT RECEIVED: cmd:");
1681
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %02x, %02x, %02x, %02x, %02x, %02x\n", pScb->ScsiCdb[0], pScb->ScsiCdb[1],
1682
pScb->ScsiCdb[2], pScb->ScsiCdb[3], pScb->ScsiCdb[4], pScb->ScsiCdb[5]);
1684
result = modeSelect(pSataAdapter, pScb, &commandStatus);
1687
if (result == 0x1)/*PARAMETER LIST LENGTH ERROR*/
1689
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, 0x1a, 0);
1692
else if (result == 0x2)
1694
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1695
SCSI_ADSENSE_INVALID_CDB, 0);
1698
else if (result == 0x3)
1700
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1701
SCSI_ADSENSE_INVALID_FIELD_IN_PARAMETER_LIST, 0);
1706
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1707
SCSI_ADSENSE_NO_SENSE, 0);
1711
pScb->dataTransfered = 0;
1712
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1713
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1715
reportScbCompletion(pSataAdapter, pScb);
1717
pScb->completionCallBack(pSataAdapter, pScb);
1718
return MV_SCSI_COMMAND_STATUS_COMPLETED;
1720
return commandStatus;
1724
modeSelect(IN MV_SATA_ADAPTER *pSataAdapter,
1725
IN MV_SATA_SCSI_CMD_BLOCK *pScb,
1726
MV_SCSI_COMMAND_STATUS_TYPE *pCommandStatus)
1728
MV_U8 *cmd = pScb->ScsiCdb;
1729
MV_VOID_PTR pBuffer = pScb->pDataBuffer;
1730
MV_U32 length = pScb->dataBufferLength;
1731
MV_U8 PF = (cmd[1] & MV_BIT4) >> 4;
1732
MV_U8 SP = (cmd[1] & MV_BIT0);
1733
MV_U8 *list = (MV_U8 *)pBuffer;
1735
MV_U32 cachePageOffset = 0;
1739
for (i =0 ; i < length; i++)
1741
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %02x", list[i]);
1743
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "\n");
1747
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%d %d: Mode Select Error: PF not supported\n.",
1748
pSataAdapter->adapterId, pScb->bus);
1749
return 0x2; /* Invalid field in CDB */
1753
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%d %d: Mode Select Error: SP not supported\n.",
1754
pSataAdapter->adapterId, pScb->bus);
1755
return 0x2; /* PARAMETER LIST LENGTH ERROR */
1759
pScb->dataTransfered = 0;
1760
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1761
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1763
reportScbCompletion(pSataAdapter, pScb);
1765
pScb->completionCallBack(pSataAdapter, pScb);
1766
*pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1771
return 0x1; /* PARAMETER LIST LENGTH ERROR */
1773
if (list[0] || (list[1] != MV_SCSI_DIRECT_ACCESS_DEVICE) || list[2])
1775
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in parameter "
1776
"list\n", pSataAdapter->adapterId, pScb->bus);
1777
return 0x3; /* Invalid field in parameter list */
1783
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: wrong size for mode parameter"
1784
" block descriptor, BLOCK DESCRIPTOR LENGTH %d\n.",
1785
pSataAdapter->adapterId, pScb->bus, list[3]);
1786
return 0x3; /* Invalid field in parameter list */
1790
return 0x1; /* PARAMETER LIST LENGTH ERROR */
1792
if (list[4] || list[5] || list[6] || list[7] || list[8] || list[9] ||
1793
(list[10] != 0x2) || list[11])
1795
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in parameter "
1796
"block descriptor list\n", pSataAdapter->adapterId,
1798
return 0x3; /* Invalid field in parameter list */
1801
offset = 4 + list[3];/* skip the mode parameter block descriptor */
1803
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select: PF 0x%x SP 0x%x parameter length %x "
1804
"length %d(0x%x)\n offset %d", pSataAdapter->adapterId, pScb->bus,
1805
PF, SP, (MV_U32)cmd[4], length, length,
1807
if (length == offset)
1809
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select : no mode pages available\n",
1810
pSataAdapter->adapterId, pScb->bus);
1811
pScb->dataTransfered = 0;
1812
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1813
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1815
reportScbCompletion(pSataAdapter, pScb);
1817
pScb->completionCallBack(pSataAdapter, pScb);
1818
*pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1822
while ((offset + 2) < length)
1824
switch (list[offset] & 0x3f)
1827
if (list[offset + 1] != 0x12)
1829
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: bad length in caching mode "
1831
pSataAdapter->adapterId, pScb->bus, list[offset + 1]);
1832
return 0x3; /* Invalid field in parameter list */
1834
cachePageOffset = offset;
1835
offset += list[offset + 1] + 2;
1838
if ((list[offset] != 0xa) || (list[offset+1] != 0xa))
1840
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in"
1841
" mode control page, list[%x] %x, list[%x] %x\n",
1842
pSataAdapter->adapterId, pScb->bus, offset,
1843
list[offset], offset + 1, list[offset+1]);
1847
if (list[offset + 3] != MV_BIT4)
1849
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in"
1850
" mode control page, list[%x] %x\n",
1851
pSataAdapter->adapterId, pScb->bus, offset + 3,
1856
if (list[offset + 2] || list[offset + 4] || list[offset + 5] ||
1857
list[offset + 6] || list[offset + 7]||list[offset + 8] ||
1858
list[offset + 9]|| list[offset + 10] || list[offset + 11])
1860
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in"
1861
" mode control page, line %d\n",
1862
pSataAdapter->adapterId, pScb->bus, __LINE__);
1865
offset += list[offset + 1] + 2;
1868
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in parameter "
1869
"list, mode page %d not supported, offset %d\n",
1870
pSataAdapter->adapterId, pScb->bus, list[offset],
1872
return 0x3; /* Invalid field in parameter list */
1876
if (length != offset)
1878
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: bad length %d\n.",
1879
pSataAdapter->adapterId, pScb->bus, length);
1880
return 0x1; /* PARAMETER LIST LENGTH ERROR */
1883
if (cachePageOffset)
1885
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Mode Select: caching Page found, offset %d\n", cachePageOffset);
1886
return mvParseModeCachingPage(pSataAdapter, pScb,list + cachePageOffset, pCommandStatus);
1890
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Mode Select: No caching Page found\n");
1891
pScb->dataTransfered = 0;
1892
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1893
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1895
reportScbCompletion(pSataAdapter, pScb);
1897
pScb->completionCallBack(pSataAdapter, pScb);
1898
*pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1904
mvParseModeCachingPage(MV_SATA_ADAPTER *pSataAdapter,
1905
IN MV_SATA_SCSI_CMD_BLOCK *pScb,
1907
MV_SCSI_COMMAND_STATUS_TYPE *pCommandStatus)
1909
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1910
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
1912
MV_QUEUE_COMMAND_INFO commandInfo;
1913
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
1915
MV_QUEUE_COMMAND_RESULT result;
1917
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1920
if ((buffer[index++] & 0xc0) || (buffer[index++] != 0x12) ||
1921
((buffer[index++] | MV_BIT2)!= MV_BIT2) || (buffer[index++]) ||
1922
(buffer[index++] != 0xff) || (buffer[index++] != 0xff) ||
1923
buffer[index++] || buffer[index++] || buffer[index++] ||
1924
(buffer[index++] != 0x10) || buffer[index++] ||
1925
(buffer[index++] != 0x10) || ((buffer[index++] | MV_BIT5) != MV_BIT5) ||
1926
(buffer[index++] != 0x1) || (buffer[index++] != 0xff) ||
1927
(buffer[index++] != 0xff) || buffer[index++] || buffer[index++]
1928
|| buffer[index++] || buffer[index++])
1930
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in caching mode"
1931
" page, index %d\n", pSataAdapter->adapterId, pScb->bus,
1933
return 0x3; /* Invalid field in parameter list */
1936
pScb->splitCount = 2;
1937
pScb->sequenceNumber = 1;
1938
if (buffer[12] & MV_BIT5) /* Disable Look Ahead*/
1940
if (pDriveData->identifyInfo.readAheadSupported == MV_FALSE)
1944
pScb->LowLbaAddress = 0;
1948
if (pDriveData->identifyInfo.readAheadSupported == MV_FALSE)
1950
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in caching mode"
1951
" page, enable read ahead (feature not supported)\n",
1952
pSataAdapter->adapterId, pScb->bus);
1953
return 0x3; /* Invalid field in parameter list */
1955
pScb->LowLbaAddress = 1;
1958
if (buffer[2] & MV_BIT2) /* enable write cache*/
1960
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Parse Caching Page: enable Write Cache\n");
1961
if (pDriveData->identifyInfo.writeCacheSupported == MV_FALSE)
1963
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in caching mode"
1964
" page, enable write cache (feature not supported)\n",
1965
pSataAdapter->adapterId, pScb->bus);
1966
return 0x3; /* Invalid field in parameter list */
1968
pCommandInfo->commandParams.NoneUdmaCommand.features = MV_ATA_SET_FEATURES_ENABLE_WCACHE;
1972
if (pDriveData->identifyInfo.writeCacheSupported == MV_FALSE)
1975
if (pScb->splitCount == 1)
1977
mvScsiAtaSendReadLookAhead(pSataAdapter, pScb);
1978
*pCommandStatus = MV_SCSI_COMMAND_STATUS_QUEUED;
1982
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Parse Caching Page: disable Write Cache\n");
1983
pCommandInfo->commandParams.NoneUdmaCommand.features = MV_ATA_SET_FEATURES_DISABLE_WCACHE;
1986
if (pScb->splitCount == 0)
1988
pScb->dataTransfered = 0;
1989
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1990
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1992
reportScbCompletion(pSataAdapter, pScb);
1994
pScb->completionCallBack(pSataAdapter, pScb);
1995
*pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1999
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2001
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2002
pCommandInfo->PMPort = pScb->target;
2003
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = NULL;
2004
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
2005
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_SET_FEATURES;
2006
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
2007
pCommandInfo->commandParams.NoneUdmaCommand.count = 0;
2009
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
2010
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh = 0;
2011
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid = 0;
2012
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow = 0;
2013
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_NON_DATA;
2014
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = 0;
2015
pCommandInfo->commandParams.NoneUdmaCommand.device = (MV_U8)(MV_BIT6);
2017
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending SET FEATURES command: features %d\n",
2018
pCommandInfo->commandParams.NoneUdmaCommand.features);
2020
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
2022
if (result != MV_QUEUE_COMMAND_RESULT_OK)
2024
checkQueueCommandResult(pScb, result);
2026
reportScbCompletion(pSataAdapter, pScb);
2028
pScb->completionCallBack(pSataAdapter, pScb);
2029
*pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
2033
*pCommandStatus = MV_SCSI_COMMAND_STATUS_QUEUED;
2038
mvModeSenseCachingPage(MV_SATA_SCSI_CMD_BLOCK *pScb,
2039
MV_U8 *buffer,MV_U8 pageControl)
2041
MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
2044
buffer[0] = 0x8; /* caching page*/
2045
buffer[1] = 0x12; /* length = 2 + 0x12*/
2047
if (pageControl == 2) /*default values*/
2049
if (pDriveData->identifyInfo.writeCacheSupported == MV_TRUE)
2051
buffer[2] = MV_BIT2;
2052
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: writeCacheEnabledByDefault\n");
2055
else if (pageControl == 0) /* current values*/
2057
if ((pDriveData->identifyInfo.writeCacheSupported == MV_TRUE) &&
2058
(pDriveData->identifyBuffer[85] & MV_BIT5))
2060
buffer[2] = MV_BIT2;
2061
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: writeCacheEnabled\n");
2064
else if (pageControl == 1) /* changeable values*/
2066
if (pDriveData->identifyInfo.writeCacheSupported == MV_TRUE)
2068
buffer[2] = MV_BIT2;
2069
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: writeCacheSupported\n");
2074
if (pageControl != 1)
2081
if (pageControl == 2) /*default values*/
2083
if (pDriveData->identifyInfo.readAheadSupported == MV_FALSE)
2085
buffer[12] = MV_BIT5;
2088
else if (pageControl == 0) /* current values*/
2090
if ((pDriveData->identifyInfo.readAheadSupported == MV_TRUE) &&
2091
(pDriveData->identifyBuffer[85] & MV_BIT6))
2097
buffer[12] = MV_BIT5;
2100
else if (pageControl == 1) /* changeable values*/
2102
if (pDriveData->identifyInfo.readAheadSupported == MV_TRUE)
2104
buffer[12] = MV_BIT5;
2107
if (pageControl != 1)
2117
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: \n");
2118
for (i = 0; i < 0x14; i++)
2120
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "[%d] %x\n",i, buffer[i]);
2127
mvModeSenseControlPage(MV_SATA_ADAPTER *pSataAdapter,
2128
MV_SATA_SCSI_CMD_BLOCK *pScb,
2129
MV_U8 *buffer, MV_U8 pageControl)
2131
buffer[0] = 0xA; /* control page */
2132
buffer[1] = 0xA; /* length 2 + 0xa*/
2133
if (pageControl != 1)
2135
buffer[3] = MV_BIT4/*Unrestricted reordering allowed*/;
2141
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Control Page: \n");
2142
for (i = 0; i < 0xc; i++)
2144
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "[%d] %x\n",i , buffer[i]);
2151
SALCommandCompletionCB(MV_SATA_ADAPTER *pSataAdapter,
2153
MV_COMPLETION_TYPE comp_type,
2154
MV_VOID_PTR commandId,
2155
MV_U16 responseFlags,
2157
MV_STORAGE_DEVICE_REGISTERS *registerStruct)
2159
MV_SATA_SCSI_CMD_BLOCK *pScb;
2160
if (commandId == NULL)
2162
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_FATAL_ERROR, " commandId is NULL, can't hanlde this !!!,adapterId=%d,"
2163
" channel=%d \n", pSataAdapter->adapterId, channelNum);
2170
case MV_COMPLETION_TYPE_NORMAL:
2172
#ifdef MV_SUPPORT_ATAPI
2173
if(pScb->commandType == MV_QUEUED_COMMAND_TYPE_PACKET)
2175
if ((registerStruct->statusRegister & MV_ATA_ERROR_STATUS) ||
2176
(registerStruct->statusRegister & MV_ATA_DEVICE_FAULT_STATUS))
2178
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
2179
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "packet command completed ",
2180
"with check condition\n", pScb);
2184
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
2186
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
2187
pScb->dataTransfered = timeStamp;
2191
/* If splited VERIFY command, then SRB completion will be on the last fragment */
2192
if ((((pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY6) ||
2193
(pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY10) ||
2194
(pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY16) ||
2195
(pScb->ScsiCdb[0] == SCSI_OPCODE_MODE_SELECT6)))
2196
&& (pScb->splitCount > pScb->sequenceNumber))
2198
/* add the command to the list for post interrupt service*/
2199
pScb->pNext = pScb->pSalAdapterExtension->pHead;
2200
pScb->pSalAdapterExtension->pHead = pScb;
2203
if (pScb->ScsiCdb[0] == SCSI_OPCODE_MODE_SENSE6)
2205
mvScsiAtaGetModeSenseDataPhase2(pSataAdapter, pScb);
2209
pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
2210
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
2212
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "command completed. pScb %p\n", pScb);
2215
case MV_COMPLETION_TYPE_ABORT:
2216
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "Error: command Aborted. Cdb: %02x %02x %02x %02x %02x "
2217
"%02x %02x %02x %02x %02x\n", pScb->ScsiCdb[0],
2218
pScb->ScsiCdb[1], pScb->ScsiCdb[2], pScb->ScsiCdb[3],
2219
pScb->ScsiCdb[4], pScb->ScsiCdb[5], pScb->ScsiCdb[6],
2220
pScb->ScsiCdb[7], pScb->ScsiCdb[8], pScb->ScsiCdb[9]);
2222
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_ABORTED;
2223
pScb->dataTransfered = 0;
2224
pScb->senseDataLength = 0;
2225
mvCommandCompletionErrorHandler(pScb->pIalAdapterExtension, channelNum);
2227
case MV_COMPLETION_TYPE_ERROR:
2228
pScb->dataTransfered = 0;
2229
pScb->senseDataLength = 0;
2230
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_ATA_FAILED;
2232
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "COMPLETION ERROR , adapter =%d, channel=%d, flags=%x\n",
2233
pSataAdapter->adapterId, channelNum, responseFlags);
2234
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Failed command Cdb: %02x %02x %02x %02x %02x "
2235
"%02x %02x %02x %02x %02x\n", pScb->ScsiCdb[0],
2236
pScb->ScsiCdb[1], pScb->ScsiCdb[2], pScb->ScsiCdb[3],
2237
pScb->ScsiCdb[4], pScb->ScsiCdb[5], pScb->ScsiCdb[6],
2238
pScb->ScsiCdb[7], pScb->ScsiCdb[8], pScb->ScsiCdb[9]);
2239
/* here the eDMA will be stopped, so we have to flush */
2240
/* the pending commands */
2242
if (pScb->commandType == MV_QUEUED_COMMAND_TYPE_UDMA)
2244
handleUdmaError(pScb, responseFlags, registerStruct);
2246
memcpy(&pScb->ATAregStruct, registerStruct,
2247
sizeof(pScb->ATAregStruct));
2252
handleNoneUdmaError(pScb, registerStruct);
2254
memcpy(&pScb->ATAregStruct, registerStruct,
2255
sizeof(pScb->ATAregStruct));
2258
mvCommandCompletionErrorHandler(pScb->pIalAdapterExtension, channelNum);
2261
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_FATAL_ERROR, " Unknown completion type (%d)\n", comp_type);
2265
reportScbCompletion(pSataAdapter, pScb);
2268
pScb->completionCallBack(pSataAdapter, pScb);
2272
handleNoneUdmaError(MV_SATA_SCSI_CMD_BLOCK *pScb,
2273
MV_STORAGE_DEVICE_REGISTERS *registerStruct)
2275
MV_U8 errorReg = registerStruct->errorRegister;
2276
MV_SCSI_SENSE_DATA SenseData;
2278
memset(&SenseData, 0, sizeof(MV_SCSI_SENSE_DATA));
2280
pScb->dataBufferLength = 0;
2282
/*if (pSrb->SenseInfoBufferLength < 13)
2284
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "IAL ERROR: invalid Sense Info buffer len (%d)\n",
2285
Srb->SenseInfoBufferLength);
2286
Srb->SrbStatus = SRB_STATUS_ERROR;
2289
memset(pScb->pSenseBuffer, 0, pScb->senseBufferLength);
2290
/*pScb->ScsiCommandCompletion = ;*/
2291
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
2293
SenseData.ResponseCode = MV_SCSI_RESPONSE_CODE;
2294
// SenseData.Valid = 0;
2296
SenseData.AdditionalSenseLength = 12;
2297
SenseData.InformationDesc.type = 0;
2298
SenseData.InformationDesc.AdditionalLength = 0xA;
2299
SenseData.InformationDesc.valid = 1 << 7;
2301
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " ATA Drive Registers:\n");
2302
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","Error", registerStruct->errorRegister);
2303
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","SectorCount", registerStruct->sectorCountRegister);
2304
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","LBA Low", registerStruct->lbaLowRegister);
2305
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","LBA Mid", registerStruct->lbaMidRegister);
2306
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","LBA High", registerStruct->lbaHighRegister);
2307
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","Device", registerStruct->deviceRegister);
2308
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","Status", registerStruct->statusRegister);
2310
/* If the command is synchronize cache */
2311
if ((pScb->ScsiCdb[0] == SCSI_OPCODE_SYNCHRONIZE_CACHE10) ||
2312
(pScb->ScsiCdb[0] == SCSI_OPCODE_SYNCHRONIZE_CACHE16))
2314
if (!(registerStruct->errorRegister & ABRT_ERR))
2316
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " received error completion on flush cache command"
2317
" but ABORT bit in error register is not set\n");
2319
SenseData.SenseKey = SCSI_SENSE_MEDIUM_ERROR;
2320
_fillSenseInformation(pScb, &SenseData, registerStruct);
2322
else if ((pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY10) ||
2323
(pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY6) ||
2324
(pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY16))
2326
if (errorReg & (NM_ERR | MC_ERR | MCR_ERR))
2328
SenseData.SenseKey = SCSI_SENSE_UNIT_ATTENTION;
2330
else if (errorReg & UNC_ERR)
2333
MV_U32 LowLbaAddress = pScb->LowLbaAddress;
2335
SenseData.SenseKey = SCSI_SENSE_MEDIUM_ERROR;
2337
/* Since high 8 bit address are taken immediatly from LowLbaAddress and
2338
not from the completion info ; the following code is relevant for both
2339
48bit and 28bit LBA addressing*/
2340
SenseData.Information[0] = (MV_U8)((LowLbaAddress & 0xff000000) >> 24);
2341
SenseData.Information[1] = (MV_U8)(registerStruct->lbaHighRegister & 0xff);
2342
SenseData.Information[2] = (MV_U8)(registerStruct->lbaMidRegister & 0xff);
2343
SenseData.Information[3] = (MV_U8)(registerStruct->lbaLowRegister & 0xff);
2345
_fillSenseInformation(pScb, &SenseData, registerStruct);
2346
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Read Verify failed on UNC at sector %02x %02x %02x %02x %02x %02x\n",
2347
SenseData.InformationDesc.information[2],
2348
SenseData.InformationDesc.information[3],
2349
SenseData.InformationDesc.information[4],
2350
SenseData.InformationDesc.information[5],
2351
SenseData.InformationDesc.information[6],
2352
SenseData.InformationDesc.information[7]
2355
/*else if (errorReg & IDNF_ERR)
2357
SenseData.SenseKey = SCSI_SENSE_VOL_OVERFLOW;
2359
else if ((errorReg & ABRT_ERR) || (errorReg & IDNF_ERR))
2361
SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2362
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2366
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " in mapping ATA error to SCSI error\n");
2367
SenseData.SenseKey = SCSI_SENSE_NO_SENSE;
2370
else if (pScb->ScsiCdb[0] == SCSI_OPCODE_MODE_SELECT6)
2372
/* MODE SELECT is only when enabling / disabling write cache */
2373
if (errorReg & ABRT_ERR)
2375
SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2376
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2380
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " in mapping ATA error to SCSI error\n");
2381
SenseData.SenseKey = SCSI_SENSE_NO_SENSE;
2384
pScb->senseDataLength = 20;
2385
memcpy(pScb->pSenseBuffer, &SenseData,
2386
(pScb->senseBufferLength > pScb->senseDataLength) ?
2387
pScb->senseDataLength : pScb->senseBufferLength);
2393
handleUdmaError(MV_SATA_SCSI_CMD_BLOCK *pScb,
2394
MV_U32 responseFlags,
2395
MV_STORAGE_DEVICE_REGISTERS *registerStruct)
2398
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "UDMA %s command failed\n", (pScb->udmaType == MV_UDMA_TYPE_READ) ?
2400
if (responseFlags & (MV_BIT3))
2402
/* prevent the error_handler from re-send any commands */
2403
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_DISCONNECT;
2405
else if (responseFlags & MV_BIT2) /* ATA error*/
2407
MV_SCSI_SENSE_DATA SenseData;
2409
memset(&SenseData, 0, sizeof(MV_SCSI_SENSE_DATA));
2410
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
2411
pScb->dataTransfered = 0;
2412
pScb->senseDataLength = 13;
2413
// SenseData.Valid = 1;
2414
SenseData.ResponseCode = MV_SCSI_RESPONSE_CODE;
2415
SenseData.AdditionalSenseLength = 12;
2416
SenseData.InformationDesc.type = 0;
2417
SenseData.InformationDesc.AdditionalLength = 0xA;
2418
SenseData.InformationDesc.valid = 1 << 7;
2421
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " ATA Drive Registers:\n");
2422
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","Error", registerStruct->errorRegister);
2423
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","SectorCount", registerStruct->sectorCountRegister);
2424
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","LBA Low", registerStruct->lbaLowRegister);
2425
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","LBA Mid", registerStruct->lbaMidRegister);
2426
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","LBA High", registerStruct->lbaHighRegister);
2427
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","Device", registerStruct->deviceRegister);
2428
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "%20s : %04x\n","Status", registerStruct->statusRegister);
2430
if ((registerStruct->errorRegister & ICRC_ERR)||
2431
(registerStruct->errorRegister == 0xC))/*error code injected by 88i8030*/
2433
SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2434
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2436
else if (registerStruct->errorRegister &
2437
(NM_ERR | MC_ERR | MCR_ERR))
2439
SenseData.SenseKey = SCSI_SENSE_UNIT_ATTENTION;
2440
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_MEDIA_IN_DEVICE;
2442
else if ((registerStruct->errorRegister & UNC_ERR) ||
2443
(registerStruct->errorRegister == 1))
2446
MV_U32 LowLbaAddress = pScb->LowLbaAddress;
2448
SenseData.Valid = 1;
2449
SenseData.Information[0] = (MV_U8)((LowLbaAddress & 0xff000000) >> 24);
2450
SenseData.Information[1] = (MV_U8)(registerStruct->lbaHighRegister & 0xff);
2451
SenseData.Information[2] = (MV_U8)(registerStruct->lbaMidRegister & 0xff);
2452
SenseData.Information[3] = (MV_U8)(registerStruct->lbaLowRegister & 0xff);
2454
_fillSenseInformation(pScb, &SenseData, registerStruct);
2455
if (pScb->udmaType == MV_UDMA_TYPE_READ)
2457
SenseData.SenseKey = SCSI_SENSE_MEDIUM_ERROR;
2458
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2460
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " DMA Read failed on UNC at sector %02x %02x %02x %02x %02x %02x\n",
2461
SenseData.InformationDesc.information[2],
2462
SenseData.InformationDesc.information[3],
2463
SenseData.InformationDesc.information[4],
2464
SenseData.InformationDesc.information[5],
2465
SenseData.InformationDesc.information[6],
2466
SenseData.InformationDesc.information[7]
2471
SenseData.SenseKey = SCSI_SENSE_DATA_PROTECT;
2472
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2475
else if ((registerStruct->errorRegister & IDNF_ERR) &&
2476
(!(registerStruct->errorRegister & ABRT_ERR)))
2478
/* In case IDNF is set and ABRT reset OR IDNF reset and ABRT is set */
2479
SenseData.SenseKey = SCSI_SENSE_ILLEGAL_REQUEST;
2480
SenseData.AdditionalSenseCode = SCSI_ADSENSE_ILLEGAL_BLOCK;
2482
else if (registerStruct->errorRegister & ABRT_ERR)
2484
SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2485
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2489
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " in mapping ATA error to SCSI error\n");
2490
SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2491
SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2493
pScb->senseDataLength = 20;
2494
memcpy(pScb->pSenseBuffer, &SenseData,
2495
(pScb->senseBufferLength > pScb->senseDataLength) ?
2496
pScb->senseDataLength : pScb->senseBufferLength);
2498
else if (responseFlags & (MV_BIT0 | MV_BIT1))
2500
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_PARITY_ERROR;
2501
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
2502
pScb->senseDataLength = 0;
2503
pScb->dataTransfered = 0;
2505
else if (responseFlags & (MV_BIT6|MV_BIT5))
2507
if (responseFlags & MV_BIT6)
2509
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UNDERRUN;
2513
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_OVERRUN;
2515
pScb->dataTransfered = 0;
2520
/*******************************************************************************
2521
* checkQueueCommandResult -
2523
* DESCRIPTION: set the scsi request completion status and the Scsi Status
2524
* according to the result returned form the mvSataQueueCommand function
2535
*******************************************************************************/
2537
/*static*/ MV_VOID checkQueueCommandResult(MV_SATA_SCSI_CMD_BLOCK *pScb,
2538
MV_QUEUE_COMMAND_RESULT result)
2542
case MV_QUEUE_COMMAND_RESULT_BAD_LBA_ADDRESS:
2543
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Edma Queue command failed. Bad LBA \n");
2544
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
2546
case MV_QUEUE_COMMAND_RESULT_QUEUED_MODE_DISABLED:
2547
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Edma Queue command failed. EDMA disabled\n");
2548
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_NOT_READY;
2551
case MV_QUEUE_COMMAND_RESULT_FULL:
2552
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Edma Queue command failed. Queue is Full\n");
2553
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_QUEUE_FULL;
2554
pScb->ScsiStatus = MV_SCSI_STATUS_QUEUE_FULL;
2556
case MV_QUEUE_COMMAND_RESULT_BAD_PARAMS:
2557
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Edma Queue command failed. (Bad Params)\n");
2558
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
2561
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Bad result value (%d) from queue"
2562
" command\n", result);
2564
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " mvSataQueueUDmaCommand Failed\n");
2565
pScb->dataTransfered = 0;
2566
pScb->senseDataLength = 0;
2569
static MV_VOID reportScbCompletion(MV_SATA_ADAPTER* pSataAdapter,
2570
MV_SATA_SCSI_CMD_BLOCK *pScb)
2572
if (pScb->ScsiCommandCompletion != MV_SCSI_COMPLETION_SUCCESS)
2576
MV_BOOLEAN printInfo = MV_TRUE;
2578
switch (pScb->ScsiCommandCompletion)
2580
case MV_SCSI_COMPLETION_BAD_SCSI_COMMAND:
2581
SAL_SPRINTF(buffer, "%s", "MV_SCSI_COMPLETION_BAD_SCSI_COMMAND");
2583
case MV_SCSI_COMPLETION_ATA_FAILED:
2584
SAL_SPRINTF(buffer, "%s", "MV_SCSI_COMPLETION_ATA_FAILED");
2586
case MV_SCSI_COMPLETION_PARITY_ERROR:
2587
SAL_SPRINTF(buffer, "%s", "MV_SCSI_COMPLETION_PARITY");
2590
printInfo = MV_FALSE;
2593
if (printInfo == MV_TRUE)
2595
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " %d %d %d :Scsi command completed. pScb %p, ScsiStatus %d "
2596
"completionStatus %s\n", pSataAdapter->adapterId,
2597
pScb->bus, pScb->target, pScb, pScb->ScsiStatus, buffer);
2601
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Scsi command completed. pScb %p, ScsiStatus %d "
2602
"completionStatus %d\n", pScb, pScb->ScsiStatus,
2603
pScb->ScsiCommandCompletion);
2606
index = SAL_SPRINTF(buffer, "%s", "CDB:");
2609
for (i =0 ; i < pScb->ScsiCdbLength; i++)
2611
index += SAL_SPRINTF(&buffer[index], "%x ",
2614
buffer[index] = '\n';
2615
buffer[index+1] = 0;
2616
mvLogMsg(MV_SAL_LOG_ID,(printInfo == MV_TRUE) ?
2617
MV_DEBUG_ERROR : MV_DEBUG, buffer);
2618
if (pScb->ScsiStatus == MV_SCSI_STATUS_CHECK_CONDITION)
2620
if ((pScb->pSenseBuffer != NULL) && (pScb->senseBufferLength > 0))
2622
MV_U32 len = pScb->senseDataLength > pScb->senseBufferLength ?
2623
pScb->senseBufferLength:pScb->senseDataLength;
2624
index = SAL_SPRINTF(buffer, "%s", "Sense Data:");
2625
for (i = 0; i < len; i++)
2627
index += SAL_SPRINTF(buffer + index, "%x ",
2628
pScb->pSenseBuffer[i]);
2630
buffer[index] = '\n';
2631
buffer[index+1] = 0;
2632
mvLogMsg(MV_SAL_LOG_ID, (printInfo == MV_TRUE) ?
2633
MV_DEBUG_ERROR : MV_DEBUG, buffer);
2637
if (pScb->ScsiCommandCompletion == MV_SCSI_COMPLETION_ATA_FAILED)
2639
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " ATA Drive Registers:\n");
2640
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","Error", pScb->ATAregStruct.errorRegister);
2641
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","SectorCount", pScb->ATAregStruct.sectorCountRegister);
2642
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","LBA Low", pScb->ATAregStruct.lbaLowRegister);
2643
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","LBA Mid", pScb->ATAregStruct.lbaMidRegister);
2644
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","LBA High", pScb->ATAregStruct.lbaHighRegister);
2645
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","Device", pScb->ATAregStruct.deviceRegister);
2646
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "%20s : %04x\n","Status", pScb->ATAregStruct.statusRegister);
2651
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Scsi command completed. pScb %p, ScsiStatus %d "
2652
"completionStatus %d dataTransfered %d \n", pScb, pScb->ScsiStatus,
2653
pScb->ScsiCommandCompletion, pScb->dataTransfered);
2658
static MV_VOID mvScsiAtaSendSplittedVerifyCommand(IN MV_SATA_SCSI_CMD_BLOCK *pScb)
2660
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
2661
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
2663
MV_QUEUE_COMMAND_INFO commandInfo;
2664
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
2666
MV_QUEUE_COMMAND_RESULT result;
2667
MV_U8 sectors = 0;/*256 sectors*/
2669
pScb->sequenceNumber++;
2670
if (pScb->sequenceNumber == 1)/*for the first command*/
2672
if (pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY6)
2674
sectors = pScb->ScsiCdb[4];
2676
else if (pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY10)
2678
sectors = pScb->ScsiCdb[8];
2682
sectors = pScb->ScsiCdb[13];
2685
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2686
pCommandInfo->PMPort = pScb->target;
2687
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = NULL;
2688
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
2689
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_READ_VERIFY_SECTORS;
2690
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
2691
pCommandInfo->commandParams.NoneUdmaCommand.count = 0;
2693
pCommandInfo->commandParams.NoneUdmaCommand.features = 0;
2694
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
2695
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_NON_DATA;
2697
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh = (MV_U16)((pScb->LowLbaAddress & 0xff0000) >> 16);
2698
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid = (MV_U16)((pScb->LowLbaAddress & 0xff00) >> 8);
2699
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow = (MV_U16)(pScb->LowLbaAddress & 0xff);
2700
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = sectors;
2701
pCommandInfo->commandParams.NoneUdmaCommand.device = (MV_U8)(MV_BIT6 |
2702
((pScb->LowLbaAddress & 0xf000000) >> 24));
2704
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: Sending Splitted Verify command:seq# %d code %x lba"
2705
" %x(%x.%x.%x), sectors %d[%d] Srb %p\n",
2706
pScb->pSalAdapterExtension->pSataAdapter->adapterId, pScb->bus,
2708
pScb->sequenceNumber,pScb->ScsiCdb[0],
2709
pScb->LowLbaAddress,
2710
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh,
2711
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid,
2712
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow,
2713
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount,
2714
mvSataNumOfDmaCommands(pScb->pSalAdapterExtension->pSataAdapter,
2719
pScb->LowLbaAddress += sectors;
2723
pScb->LowLbaAddress += 0x100;
2726
result = mvSataQueueCommand(pScb->pSalAdapterExtension->pSataAdapter,
2727
pScb->bus, pCommandInfo);
2729
if (result != MV_QUEUE_COMMAND_RESULT_OK)
2731
checkQueueCommandResult(pScb, result);
2733
reportScbCompletion(pScb->pSalAdapterExtension->pSataAdapter, pScb);
2740
pScb->pSalAdapterExtension->totalAccumulatedOutstanding[pScb->bus] +=
2741
mvSataNumOfDmaCommands(pScb->pSalAdapterExtension->pSataAdapter,pScb->bus);
2742
pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target].stats.totalIOs++;
2743
pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target].stats.totalSectorsTransferred += sectors;
2746
static MV_VOID mvScsiAtaSendReadLookAhead(IN MV_SATA_ADAPTER *pSataAdapter,
2747
IN MV_SATA_SCSI_CMD_BLOCK *pScb)
2749
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
2750
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
2752
MV_QUEUE_COMMAND_INFO commandInfo;
2753
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
2755
MV_QUEUE_COMMAND_RESULT result;
2757
if (pScb->LowLbaAddress == 0) /* Disable Look Ahead*/
2759
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Parse Caching Page: Disable Read Look Ahead\n");
2760
pCommandInfo->commandParams.NoneUdmaCommand.features = MV_ATA_SET_FEATURES_DISABLE_RLA;
2764
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Parse Caching Page: Enable Look Ahead\n");
2765
pCommandInfo->commandParams.NoneUdmaCommand.features = MV_ATA_SET_FEATURES_ENABLE_RLA;
2768
pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2770
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2771
pCommandInfo->PMPort = pScb->target;
2772
pCommandInfo->commandParams.NoneUdmaCommand.bufPtr = NULL;
2773
pCommandInfo->commandParams.NoneUdmaCommand.callBack = SALCommandCompletionCB;
2774
pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_SET_FEATURES;
2775
pCommandInfo->commandParams.NoneUdmaCommand.commandId = (MV_VOID_PTR) pScb;
2776
pCommandInfo->commandParams.NoneUdmaCommand.count = 0;
2778
pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
2779
pCommandInfo->commandParams.NoneUdmaCommand.lbaHigh = 0;
2780
pCommandInfo->commandParams.NoneUdmaCommand.lbaMid = 0;
2781
pCommandInfo->commandParams.NoneUdmaCommand.lbaLow = 0;
2782
pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_NON_DATA;
2783
pCommandInfo->commandParams.NoneUdmaCommand.sectorCount = 0;
2784
pCommandInfo->commandParams.NoneUdmaCommand.device = (MV_U8)(MV_BIT6);
2786
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending SET FEATURES command: features %d\n",
2787
pCommandInfo->commandParams.NoneUdmaCommand.features);
2789
pScb->sequenceNumber++;
2790
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
2792
if (result != MV_QUEUE_COMMAND_RESULT_OK)
2794
checkQueueCommandResult(pScb, result);
2796
reportScbCompletion(pSataAdapter, pScb);
2798
pScb->completionCallBack(pSataAdapter, pScb);
2803
MV_VOID mvSataScsiInitAdapterExt(MV_SAL_ADAPTER_EXTENSION *pAdapterExt,
2804
MV_SATA_ADAPTER* pSataAdapter)
2808
pAdapterExt->pSataAdapter = pSataAdapter;
2809
pAdapterExt->pHead = NULL;
2810
pAdapterExt->UAMask = 0xFF;
2811
for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM; channelIndex++)
2813
for (PMPort = 0; PMPort < MV_SATA_PM_MAX_PORTS; PMPort++)
2815
pAdapterExt->ataDriveData[channelIndex][PMPort].driveReady = MV_FALSE;
2816
/* one identify data buffer used for all the drives connected to */
2817
/* the same channel*/
2818
pAdapterExt->ataDriveData[channelIndex][PMPort].identifyBuffer =
2819
pAdapterExt->identifyBuffer[channelIndex];
2823
#ifdef MV_SUPPORT_ATAPI
2824
MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendATAPICommand(MV_SATA_ADAPTER *pSataAdapter,
2825
MV_SATA_SCSI_CMD_BLOCK *pScb)
2827
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
2828
MV_QUEUE_COMMAND_INFO *pCommandInfo = pScb->pCommandInfo;
2830
MV_QUEUE_COMMAND_INFO commandInfo;
2831
MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
2833
MV_QUEUE_COMMAND_RESULT result;
2836
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Send Packet command, adapter %d bus %d target %d lun %"
2837
"d pScb %p\n dir(%d) Data Buffer %p (%d), cdb %p (%d)\n",
2838
pSataAdapter->adapterId, pScb->bus, pScb->target,
2839
pScb->lun, pScb, pScb->dataDirection,
2841
pScb->dataBufferLength, pScb->ScsiCdb, pScb->ScsiCdbLength);
2843
pScb->commandType = MV_QUEUED_COMMAND_TYPE_PACKET;
2845
pCommandInfo->type = MV_QUEUED_COMMAND_TYPE_PACKET;
2846
pCommandInfo->PMPort = pScb->target;
2847
pCommandInfo->commandParams.packetCommand.bufPtr = (MV_U16_PTR)pScb->pDataBuffer;
2848
pCommandInfo->commandParams.packetCommand.buffer_len = pScb->dataBufferLength;
2849
pCommandInfo->commandParams.packetCommand.transfered_data = 0;
2850
pCommandInfo->commandParams.packetCommand.cdb_len = (pScb->ScsiCdbLength >> 1);
2851
pCommandInfo->commandParams.packetCommand.cdb_buffer = (MV_U16_PTR)pScb->ScsiCdb;
2852
pCommandInfo->commandParams.packetCommand.flags = 0;
2853
pCommandInfo->commandParams.packetCommand.callBack = SALCommandCompletionCB;
2854
pCommandInfo->commandParams.packetCommand.commandId = (MV_VOID_PTR) pScb;
2855
pCommandInfo->commandParams.packetCommand.prdLowAddr = pScb->PRDTableLowPhyAddress;
2856
pCommandInfo->commandParams.packetCommand.prdHighAddr = pScb->PRDTableHighPhyAddress;
2858
if((pScb->dataDirection == MV_SCSI_COMMAND_DATA_DIRECTION_IN) && (pScb->pDataBuffer == NULL))
2860
pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_DMA;
2862
else if((pScb->dataDirection == MV_SCSI_COMMAND_DATA_DIRECTION_OUT) && (pScb->pDataBuffer == NULL))
2864
pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_DMA;
2865
pCommandInfo->commandParams.packetCommand.flags = MV_BIT0;
2869
switch(pScb->dataDirection)
2871
case MV_SCSI_COMMAND_DATA_DIRECTION_IN:
2872
pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_PIO_DATA_IN;
2874
case MV_SCSI_COMMAND_DATA_DIRECTION_OUT:
2875
pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_PIO_DATA_OUT;
2878
pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_PIO_NON_DATA;
2881
pScb->sequenceNumber = 0;
2882
result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
2884
if (result != MV_QUEUE_COMMAND_RESULT_OK)
2886
checkQueueCommandResult(pScb, result);
2888
reportScbCompletion(pSataAdapter, pScb);
2890
pScb->completionCallBack(pSataAdapter, pScb);
2891
return MV_SCSI_COMMAND_STATUS_COMPLETED;
2893
return MV_SCSI_COMMAND_STATUS_QUEUED;
2896
MV_SCSI_COMMAND_STATUS_TYPE mvSataExecuteScsiCommand(MV_SATA_SCSI_CMD_BLOCK *pScb)
2898
MV_U8 *cmd = pScb->ScsiCdb;
2899
MV_BOOLEAN invalidCDB = MV_FALSE;
2900
MV_SATA_ADAPTER *pSataAdapter = pScb->pSalAdapterExtension->pSataAdapter;
2901
MV_SATA_SCSI_DRIVE_DATA *pDriveData;
2903
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Scsi Command Received, adapter %d bus %d target %d lun %"
2904
"d pScb %p\n Data Buffer length %d, Sense buffer length %x\n",
2905
pSataAdapter->adapterId, pScb->bus, pScb->target,
2906
pScb->lun, pScb, pScb->dataBufferLength, pScb->senseBufferLength);
2914
index = SAL_SPRINTF(buffer, "%s", "CDB:");
2915
for (i =0 ; i < pScb->ScsiCdbLength; i++)
2917
index += SAL_SPRINTF(&buffer[index], "%x ",
2920
buffer[index] = '\n';
2921
buffer[index+1] = 0;
2922
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, buffer);
2925
pScb->dataTransfered = 0;
2926
pScb->senseDataLength = 0;
2927
pScb->ScsiStatus = 0;
2928
if (pScb->bus >= pSataAdapter->numberOfChannels)
2930
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_INVALID_BUS;
2931
pScb->dataTransfered = 0;
2933
reportScbCompletion(pSataAdapter, pScb);
2935
pScb->completionCallBack(pSataAdapter, pScb);
2936
return MV_SCSI_COMMAND_STATUS_COMPLETED;
2939
if ((pScb->target >= MV_SATA_PM_MAX_PORTS) ||
2940
(pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target].driveReady == MV_FALSE) ||
2941
((pScb->lun) && (pScb->ScsiCdb[0] != SCSI_OPCODE_INQUIRY)))
2943
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_NO_DEVICE;
2944
pScb->dataTransfered = 0;
2946
reportScbCompletion(pSataAdapter, pScb);
2948
pScb->completionCallBack(pSataAdapter, pScb);
2949
return MV_SCSI_COMMAND_STATUS_COMPLETED;
2951
pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
2952
#ifdef MV_SUPPORT_ATAPI
2953
if(pDriveData->identifyInfo.deviceType == MV_SATA_DEVICE_TYPE_ATAPI_DEVICE)
2955
return mvScsiAtaSendATAPICommand(pSataAdapter, pScb);
2960
case SCSI_OPCODE_READ10:
2961
case SCSI_OPCODE_WRITE10:
2962
case SCSI_OPCODE_READ_CAPACITY10:
2963
case SCSI_OPCODE_VERIFY10:
2964
case SCSI_OPCODE_SYNCHRONIZE_CACHE10:
2966
#ifdef MV_SATA_SUPPORT_READ_WRITE_LONG
2967
case SCSI_OPCODE_WRITE_LONG10:
2968
case SCSI_OPCODE_READ_LONG10:
2970
if (cmd[1] & MV_BIT0) /* if related address*/
2972
invalidCDB = MV_TRUE;
2973
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: Scsi command received with "
2974
"RELADR bit enabled - returning ILLEGAL REQUEST\n"
2975
,pSataAdapter->adapterId, pScb->bus, pScb->target);
2979
if (cmd[pScb->ScsiCdbLength - 1] != 0) /*if CONTROL is set*/
2981
MV_BOOLEAN commandSupported = MV_TRUE;
2985
case SCSI_OPCODE_READ6:
2986
case SCSI_OPCODE_READ10:
2987
case SCSI_OPCODE_READ16:
2988
case SCSI_OPCODE_WRITE6:
2989
case SCSI_OPCODE_WRITE10:
2990
case SCSI_OPCODE_WRITE16:
2991
case SCSI_OPCODE_INQUIRY:
2992
case SCSI_OPCODE_TEST_UNIT_READY:
2993
case SCSI_OPCODE_MODE_SELECT6:
2994
case SCSI_OPCODE_MODE_SENSE6:
2995
case SCSI_OPCODE_READ_CAPACITY10: /* read capctiy CDB*/
2996
case SCSI_OPCODE_REQUEST_SENSE6:
2997
case SCSI_OPCODE_VERIFY6:
2998
case SCSI_OPCODE_VERIFY10:
2999
case SCSI_OPCODE_VERIFY16:
3000
case SCSI_OPCODE_SYNCHRONIZE_CACHE10:
3001
case SCSI_OPCODE_SYNCHRONIZE_CACHE16:
3002
case SCSI_OPCODE_SEEK10:
3003
case SCSI_OPCODE_REASSIGN_BLOCKS:
3004
case SCSI_OPCODE_REPORT_LUNS:
3005
#ifdef MV_SATA_SUPPORT_READ_WRITE_LONG
3006
case SCSI_OPCODE_WRITE_LONG10:
3007
case SCSI_OPCODE_READ_LONG10:
3012
commandSupported = MV_FALSE;
3014
if (commandSupported == MV_TRUE)
3016
invalidCDB = MV_TRUE;
3017
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "[%d,%d] Scsi command received with "
3018
"none zero CONTROL bits - returning ILLEGAL REQUEST\n"
3019
,pSataAdapter->adapterId, pScb->bus);
3023
if (pDriveData->UAConditionPending == MV_TRUE)
3025
if (((cmd[0] != SCSI_OPCODE_INQUIRY) &&
3026
(cmd[0] != SCSI_OPCODE_REPORT_LUNS) &&
3027
(cmd[0] != SCSI_OPCODE_REQUEST_SENSE6)) || (invalidCDB == MV_TRUE))
3029
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Unit Attention condition is pending.\n");
3031
if (pDriveData->UAEvents & MV_BIT0)
3033
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Bus Reset.\n");
3034
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UA_RESET;
3035
setSenseData(pScb, SCSI_SENSE_UNIT_ATTENTION, SCSI_ADSENSE_BUS_RESET
3037
pDriveData->UAEvents &= ~MV_BIT0;
3039
else if (pDriveData->UAEvents & MV_BIT1)
3041
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Mode Parameters Changed.\n");
3042
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UA_PARAMS_CHANGED;
3043
setSenseData(pScb, SCSI_SENSE_UNIT_ATTENTION,
3044
SCSI_ADSENSE_PARAMETERS_CHANGED, 1);
3045
pDriveData->UAEvents &= ~MV_BIT1;
3048
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
3049
pScb->dataTransfered = 0;
3051
reportScbCompletion(pSataAdapter, pScb);
3053
pScb->completionCallBack(pSataAdapter, pScb);
3054
if (pDriveData->UAEvents == 0)
3056
pDriveData->UAConditionPending = MV_FALSE;
3058
return MV_SCSI_COMMAND_STATUS_COMPLETED;
3061
if (invalidCDB == MV_TRUE)
3063
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB,
3065
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
3066
pScb->dataTransfered = 0;
3067
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
3069
reportScbCompletion(pSataAdapter, pScb);
3071
pScb->completionCallBack(pSataAdapter, pScb);
3072
return MV_SCSI_COMMAND_STATUS_COMPLETED;
3077
case SCSI_OPCODE_READ6:
3078
case SCSI_OPCODE_READ10:
3079
case SCSI_OPCODE_READ16:
3080
case SCSI_OPCODE_WRITE6:
3081
case SCSI_OPCODE_WRITE10:
3082
case SCSI_OPCODE_WRITE16:
3083
return mvScsiAtaSendDataCommand(pSataAdapter, pScb);
3084
case SCSI_OPCODE_INQUIRY:
3085
return mvScsiAtaGetInquiryData(pSataAdapter, pScb);
3086
case SCSI_OPCODE_TEST_UNIT_READY:
3087
return mvScsiAtaTestUnitReady(pSataAdapter, pScb);
3088
case SCSI_OPCODE_MODE_SELECT6:
3089
return mvScsiAtaModeSelect(pSataAdapter, pScb);
3090
case SCSI_OPCODE_MODE_SENSE6:
3091
return mvScsiAtaGetModeSenseData(pSataAdapter,pScb);
3092
/* Used to detect write protected status.*/
3093
case SCSI_OPCODE_READ_CAPACITY10: /* read capctiy CDB*/
3094
return mvScsiAtaGetReadCapacityData(pSataAdapter, pScb);
3095
case SCSI_OPCODE_READ_CAPACITY16: /* read capctiy CDB*/
3096
return mvScsiAtaGetReadCapacity16Data(pSataAdapter, pScb);
3097
case SCSI_OPCODE_REQUEST_SENSE6:
3098
return mvScsiAtaGetRequestSenseData(pSataAdapter, pScb);
3099
case SCSI_OPCODE_REPORT_LUNS:
3100
return mvScsiAtaReportLuns(pSataAdapter, pScb);
3101
case SCSI_OPCODE_VERIFY6:
3102
case SCSI_OPCODE_VERIFY10:
3103
case SCSI_OPCODE_VERIFY16:
3104
return mvScsiAtaSendVerifyCommand(pSataAdapter, pScb);
3105
case SCSI_OPCODE_SYNCHRONIZE_CACHE10:
3106
case SCSI_OPCODE_SYNCHRONIZE_CACHE16:
3107
return mvScsiAtaSendSyncCacheCommand(pSataAdapter, pScb);
3108
case SCSI_OPCODE_SEEK10:
3109
return mvScsiAtaSeek(pSataAdapter, pScb);
3110
case SCSI_OPCODE_REASSIGN_BLOCKS:
3111
return mvScsiAtaReassignBlocks(pSataAdapter, pScb);
3112
#ifdef MV_SATA_SUPPORT_READ_WRITE_LONG
3113
case SCSI_OPCODE_WRITE_LONG10:
3114
return mvScsiAtaWriteLong(pSataAdapter, pScb);
3115
case SCSI_OPCODE_READ_LONG10:
3116
return mvScsiAtaReadLong(pSataAdapter, pScb);
3121
setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
3122
SCSI_ADSENSE_ILLEGAL_COMMAND, 0);
3123
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "mvExecuteScsiCommand: ERROR: Unsupported command %02X\n", pScb->ScsiCdb[0]);
3124
pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
3125
pScb->dataTransfered = 0;
3126
pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
3128
reportScbCompletion(pSataAdapter, pScb);
3130
pScb->completionCallBack(pSataAdapter, pScb);
3131
return MV_SCSI_COMMAND_STATUS_COMPLETED;
3136
return MV_SCSI_COMMAND_STATUS_FAILED;
3139
MV_VOID mvSataScsiPostIntService(MV_SAL_ADAPTER_EXTENSION *pAdapterExt)
3141
MV_SATA_SCSI_CMD_BLOCK *pScb = pAdapterExt->pHead;
3144
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Post Interrupt Service: pScb %p command %x\n", pScb,
3146
switch (pScb->ScsiCdb[0])
3148
case SCSI_OPCODE_VERIFY16:
3149
case SCSI_OPCODE_VERIFY10:
3150
case SCSI_OPCODE_VERIFY6:
3151
mvScsiAtaSendSplittedVerifyCommand(pScb);
3153
case SCSI_OPCODE_MODE_SELECT6:
3154
mvScsiAtaSendReadLookAhead(pAdapterExt->pSataAdapter,
3158
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Post Interrupt Service called for bad scsi"
3159
" command(%x)\n", pScb->ScsiCdb[0]);
3163
pAdapterExt->pHead = NULL;
3167
MV_VOID mvSataScsiSetDriveReady(MV_SAL_ADAPTER_EXTENSION *pAdapterExt,
3168
MV_U8 channelIndex, MV_U8 PMPort,
3171
if (isReady == MV_TRUE)
3173
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: ATA Drive is Ready.\n",
3174
pAdapterExt->pSataAdapter->adapterId, channelIndex, PMPort);
3175
pAdapterExt->ataDriveData[channelIndex][PMPort].driveReady = MV_TRUE;
3176
pAdapterExt->totalAccumulatedOutstanding[channelIndex] = 0;
3177
pAdapterExt->ataDriveData[channelIndex][PMPort].stats.totalIOs = 0;
3178
pAdapterExt->ataDriveData[channelIndex][PMPort].stats.totalSectorsTransferred = 0;
3186
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d : SATA Channel is Removed.\n",
3187
pAdapterExt->pSataAdapter->adapterId, channelIndex);
3188
for (i = 0; i < MV_SATA_PM_MAX_PORTS; i++)
3190
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: SATA Drive is Removed.\n",
3191
pAdapterExt->pSataAdapter->adapterId, channelIndex,
3193
pAdapterExt->ataDriveData[channelIndex][i].driveReady = MV_FALSE;
3199
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: SATA Drive is Removed.\n",
3200
pAdapterExt->pSataAdapter->adapterId, channelIndex,
3202
pAdapterExt->ataDriveData[channelIndex][PMPort].driveReady = MV_FALSE;
3209
/* notify the translation layer with Reset and Power on reset*/
3210
MV_VOID mvSataScsiNotifyUA(MV_SAL_ADAPTER_EXTENSION *pAdapterExt,
3211
MV_U8 channelIndex, MV_U8 PMPort)
3213
pAdapterExt->ataDriveData[channelIndex][PMPort].UAConditionPending = MV_TRUE;
3215
/* bit 1 - parameters changed*/
3216
pAdapterExt->ataDriveData[channelIndex][PMPort].UAEvents = MV_BIT1 | MV_BIT0;
3217
pAdapterExt->ataDriveData[channelIndex][PMPort].UAEvents &=
3218
pAdapterExt->UAMask;
3219
mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: Notify SAL with Unit Attention condition.\n",
3220
pAdapterExt->pSataAdapter->adapterId, channelIndex, PMPort);