~ubuntu-branches/ubuntu/karmic/linux-mvl-dove/karmic-proposed

« back to all changes in this revision

Viewing changes to arch/arm/plat-orion/mv_hal_drivers/mv_drivers_lsp/mv_sata/mvScsiAtaLayer.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader
  • Date: 2010-03-10 22:24:12 UTC
  • mto: (15.1.2 karmic-security)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100310222412-k86m3r53jw0je7x1
Tags: upstream-2.6.31
ImportĀ upstreamĀ versionĀ 2.6.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*******************************************************************************
2
 
Copyright (C) Marvell International Ltd. and its affiliates
3
 
 
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.
11
 
 
12
 
 
13
 
********************************************************************************
14
 
Marvell GPL License Option
15
 
 
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. 
22
 
 
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 
26
 
disclaimer.
27
 
*******************************************************************************/
28
 
/*******************************************************************************
29
 
* mvScsiAtaLayer.c
30
 
*
31
 
* DESCRIPTION:
32
 
*       C implementation for SCSI to ATA translation layer.
33
 
*
34
 
* DEPENDENCIES:
35
 
*   mvIALCommon.h
36
 
*   mvScsiAtaLayer.h
37
 
*
38
 
*******************************************************************************/
39
 
 
40
 
/* includes */
41
 
#include "mvScsiAtaLayer.h"
42
 
#include "mvIALCommon.h"
43
 
 
44
 
#ifdef MV_LOGGER
45
 
    #define SAL_SPRINTF     sprintf
46
 
#endif
47
 
 
48
 
/* ATA defines */
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 */
58
 
 
59
 
#ifdef MV_LOGGER
60
 
static MV_VOID reportScbCompletion(MV_SATA_ADAPTER*    pSataAdapter,
61
 
                                   MV_SATA_SCSI_CMD_BLOCK *pScb);
62
 
#endif
63
 
 
64
 
/* Locals */
65
 
static MV_VOID mvAta2HostString(IN   MV_U16 *source,
66
 
                                OUT  MV_U16 *target,
67
 
                                IN   MV_U32 wordsCount);
68
 
 
69
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetInquiryData(IN  MV_SATA_ADAPTER*    pSataAdapter,
70
 
                                                            IN  MV_SATA_SCSI_CMD_BLOCK  *pScb);
71
 
 
72
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaTestUnitReady(IN  MV_SATA_ADAPTER*    pSataAdapter,
73
 
                                                           IN  MV_SATA_SCSI_CMD_BLOCK  *pScb);
74
 
 
75
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSendDataCommand(IN  MV_SATA_ADAPTER*    pSataAdapter,
76
 
                                                             IN  MV_SATA_SCSI_CMD_BLOCK  *pScb);
77
 
 
78
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetReadCapacityData(IN MV_SATA_ADAPTER*    pSataAdapter,
79
 
                                                                 IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
80
 
 
81
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaReportLuns(IN MV_SATA_ADAPTER*    pSataAdapter,
82
 
                                                        IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
83
 
 
84
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSendVerifyCommand(IN MV_SATA_ADAPTER*    pSataAdapter,
85
 
                                                               IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
86
 
 
87
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaReassignBlocks(IN MV_SATA_ADAPTER    *pSataAdapter,
88
 
                                                            IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
89
 
 
90
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSendSyncCacheCommand(IN MV_SATA_ADAPTER*    pSataAdapter,
91
 
                                                                  IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
92
 
 
93
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetRequestSenseData(IN MV_SATA_ADAPTER*    pSataAdapter,
94
 
                                                                 IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
95
 
 
96
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetModeSenseData(IN    MV_SATA_ADAPTER*    pSataAdapter,
97
 
                                                              IN    MV_SATA_SCSI_CMD_BLOCK  *pScb);
98
 
 
99
 
static MV_BOOLEAN  mvScsiAtaGetModeSenseDataPhase2(IN MV_SATA_ADAPTER    *pSataAdapter,
100
 
                                                   IN  MV_SATA_SCSI_CMD_BLOCK  *pScb);
101
 
 
102
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaModeSelect(IN    MV_SATA_ADAPTER*    pSataAdapter,
103
 
                                                        IN    MV_SATA_SCSI_CMD_BLOCK  *pScb);
104
 
 
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);
108
 
 
109
 
static MV_U8 mvParseModeCachingPage(MV_SATA_ADAPTER *pSataAdapter,
110
 
                                    IN  MV_SATA_SCSI_CMD_BLOCK  *pScb,
111
 
                                    MV_U8 *buffer,
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);
115
 
 
116
 
static MV_U32 mvModeSenseControlPage(MV_SATA_ADAPTER *pSataAdapter,
117
 
                                     MV_SATA_SCSI_CMD_BLOCK  *pScb,
118
 
                                     MV_U8 *buffer, MV_U8 pageControl);
119
 
 
120
 
static MV_BOOLEAN SALCommandCompletionCB(MV_SATA_ADAPTER *pSataAdapter,
121
 
                                         MV_U8 channelNum,
122
 
                                         MV_COMPLETION_TYPE comp_type,
123
 
                                         MV_VOID_PTR commandId,
124
 
                                         MV_U16 responseFlags,
125
 
                                         MV_U32 timeStamp,
126
 
                                         MV_STORAGE_DEVICE_REGISTERS *registerStruct);
127
 
 
128
 
MV_VOID setSenseData(IN MV_SATA_SCSI_CMD_BLOCK *pScb, IN MV_U8 SenseKey,
129
 
                     IN MV_U8 AdditionalSenseCode, IN MV_U8 ASCQ);
130
 
 
131
 
MV_VOID _fillSenseInformation(IN MV_SATA_SCSI_CMD_BLOCK *pScb, MV_SCSI_SENSE_DATA *SenseData,
132
 
                              MV_STORAGE_DEVICE_REGISTERS *registerStruct);
133
 
 
134
 
MV_VOID handleNoneUdmaError(MV_SATA_SCSI_CMD_BLOCK  *pScb,
135
 
                            MV_STORAGE_DEVICE_REGISTERS *registerStruct);
136
 
 
137
 
static MV_VOID handleUdmaError(MV_SATA_SCSI_CMD_BLOCK  *pScb,
138
 
                               MV_U32 responseFlags,
139
 
                               MV_STORAGE_DEVICE_REGISTERS *registerStruct);
140
 
 
141
 
/*static*/ MV_VOID  checkQueueCommandResult(MV_SATA_SCSI_CMD_BLOCK *pScb,
142
 
                                            MV_QUEUE_COMMAND_RESULT result);
143
 
 
144
 
static MV_VOID  mvScsiAtaSendSplittedVerifyCommand(IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
145
 
 
146
 
static MV_VOID  mvScsiAtaSendReadLookAhead(IN MV_SATA_ADAPTER*    pSataAdapter,
147
 
                                           IN MV_SATA_SCSI_CMD_BLOCK  *pScb);
148
 
 
149
 
static MV_VOID mvAta2HostString(IN MV_U16 *source,
150
 
                                OUT MV_U16 *target,
151
 
                                IN MV_U32 wordsCount
152
 
                               )
153
 
{
154
 
    MV_U32 i;
155
 
    for (i=0 ; i < wordsCount; i++)
156
 
    {
157
 
        target[i] = (source[i] >> 8) | ((source[i] & 0xff) << 8);
158
 
        target[i] = MV_LE16_TO_CPU(target[i]);
159
 
    }
160
 
}
161
 
 
162
 
MV_VOID setSenseData(IN MV_SATA_SCSI_CMD_BLOCK *pScb, IN MV_U8 SenseKey,
163
 
                     IN MV_U8 AdditionalSenseCode, IN MV_U8 ASCQ)
164
 
{
165
 
    MV_SCSI_SENSE_DATA SenseData;
166
 
 
167
 
    if (pScb->senseBufferLength == 0)
168
 
    {
169
 
        pScb->senseDataLength = 0;
170
 
        return;
171
 
    }
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)
181
 
    {
182
 
        pScb->senseDataLength = pScb->senseBufferLength;
183
 
    }
184
 
    memcpy(pScb->pSenseBuffer, &SenseData, pScb->senseDataLength);
185
 
}
186
 
 
187
 
MV_VOID _fillSenseInformation(IN MV_SATA_SCSI_CMD_BLOCK *pScb, MV_SCSI_SENSE_DATA *SenseData,
188
 
                              MV_STORAGE_DEVICE_REGISTERS *registerStruct)
189
 
{
190
 
        if (pScb->isExtended == MV_TRUE)
191
 
        {
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);
196
 
        }
197
 
        else
198
 
        {
199
 
            /* LBA 28 error handling */
200
 
            SenseData->InformationDesc.information[4] =  (MV_U8)((registerStruct->deviceRegister) & 0x0f);
201
 
        }
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);
205
 
}
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,
209
 
                                     IN MV_U32 sectors)
210
 
{
211
 
    if ((ATADiskSize <= LBA) ||  ((ATADiskSize - LBA) < sectors) || sectors > 0xFFFF)
212
 
    {
213
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Error LBA out of range. DiskSize %x sectors %x LBA %x\n"
214
 
                 , ATADiskSize, sectors, LBA);
215
 
 
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;
221
 
#ifdef MV_LOGGER
222
 
        reportScbCompletion(pSataAdapter, pScb);
223
 
#endif
224
 
        pScb->completionCallBack(pSataAdapter, pScb);
225
 
        return MV_TRUE;
226
 
 
227
 
    }
228
 
    return MV_FALSE;
229
 
}
230
 
/*******************************************************************************
231
 
* mvScsiAtaGetInquiryData - Get the SCSI-3 standard inquiry(12h) data
232
 
*
233
 
* DESCRIPTION: This function fills the data buffer with Scsi standard inquiry
234
 
*       data according to the ATA Identify data
235
 
*
236
 
* INPUT:
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.
240
 
*
241
 
* RETURN:
242
 
*   MV_TRUE on success, MV_FALSE on failure.
243
 
*
244
 
* COMMENTS:
245
 
*   No sanity check is done for the parameters.
246
 
*
247
 
*******************************************************************************/
248
 
 
249
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetInquiryData(IN  MV_SATA_ADAPTER*    pSataAdapter,
250
 
                                                            IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
251
 
{
252
 
    MV_U8           buff[42];
253
 
    MV_U32          inquiryLen;
254
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
255
 
 
256
 
    memset(buff, 0, 42);
257
 
 
258
 
    if ((pScb->ScsiCdb[1] & (MV_BIT0 | MV_BIT1)) ||
259
 
        (pScb->ScsiCdb[2]))
260
 
    {
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],
263
 
                 pScb->ScsiCdb[2]);
264
 
        if (pDriveData->UAConditionPending == MV_TRUE)
265
 
        {
266
 
 
267
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Unit Attention condition is pending.\n");
268
 
 
269
 
            if (pDriveData->UAEvents & MV_BIT0)
270
 
            {
271
 
                mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Bus Reset.\n");
272
 
 
273
 
                pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UA_RESET;
274
 
                setSenseData(pScb, SCSI_SENSE_UNIT_ATTENTION, SCSI_ADSENSE_BUS_RESET
275
 
                             , 2);
276
 
                pDriveData->UAEvents &= ~MV_BIT0;
277
 
            }
278
 
            else if (pDriveData->UAEvents & MV_BIT1)
279
 
            {
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;
285
 
            }
286
 
 
287
 
            pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
288
 
            pScb->dataTransfered = 0;
289
 
#ifdef MV_LOGGER
290
 
            reportScbCompletion(pSataAdapter, pScb);
291
 
#endif
292
 
            pScb->completionCallBack(pSataAdapter, pScb);
293
 
            if (pDriveData->UAEvents == 0)
294
 
            {
295
 
                pDriveData->UAConditionPending = MV_FALSE;
296
 
            }
297
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
298
 
        }
299
 
 
300
 
        setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB,
301
 
                     0);
302
 
        pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
303
 
        pScb->dataTransfered = 0;
304
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
305
 
#ifdef MV_LOGGER
306
 
        reportScbCompletion(pSataAdapter, pScb);
307
 
#endif
308
 
        pScb->completionCallBack(pSataAdapter, pScb);
309
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
310
 
    }
311
 
 
312
 
    if (pScb->lun)
313
 
    {
314
 
        buff[0] = 0x7f;
315
 
        inquiryLen = 5;
316
 
    }
317
 
    else
318
 
    {
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 */
325
 
#if 0
326
 
        buff[6] = 0x80;     /* basic queuing*/
327
 
        buff[7] = 0;
328
 
#else
329
 
        buff[6] = 0x0;     /* tagged queuing*/
330
 
        buff[7] = 2;
331
 
#endif
332
 
        memcpy(temp, pDriveData->identifyInfo.model, 24);
333
 
        mvAta2HostString((MV_U16 *)temp, (MV_U16 *)(temp), 12);
334
 
        {
335
 
            MV_U32 i;
336
 
            for (i = 0; i < 9; i++)
337
 
            {
338
 
                if (temp[i] == ' ')
339
 
                {
340
 
                    break;
341
 
                }
342
 
            }
343
 
            if (i == 9)
344
 
            {
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')))
349
 
                { /*Hitachi*/
350
 
                    Vendor[0] = 'H';
351
 
                    Vendor[1] = 'i';
352
 
                    Vendor[2] = 't';
353
 
                    Vendor[3] = 'a';
354
 
                    Vendor[4] = 'c';
355
 
                    Vendor[5] = 'h';
356
 
                    Vendor[6] = 'i';
357
 
                    Vendor[7] = ' ';
358
 
                    Vendor[8] = '\0';
359
 
                }
360
 
                else if ((temp[0] == 'S') && (temp[1] == 'T'))
361
 
                {
362
 
                    /*Seagate*/
363
 
                    Vendor[0] = 'S';
364
 
                    Vendor[1] = 'e';
365
 
                    Vendor[2] = 'a';
366
 
                    Vendor[3] = 'g';
367
 
                    Vendor[4] = 'a';
368
 
                    Vendor[5] = 't';
369
 
                    Vendor[6] = 'e';
370
 
                    Vendor[7] = ' ';
371
 
                    Vendor[8] = '\0';
372
 
                }
373
 
                else
374
 
                {
375
 
                    /*Unkown*/
376
 
                    Vendor[0] = 'A';
377
 
                    Vendor[1] = 'T';
378
 
                    Vendor[2] = 'A';
379
 
                    Vendor[3] = ' ';
380
 
                    Vendor[4] = ' ';
381
 
                    Vendor[5] = ' ';
382
 
                    Vendor[6] = ' ';
383
 
                    Vendor[7] = ' ';
384
 
                    Vendor[8] = '\0';
385
 
                }
386
 
                memcpy(Product, temp, 16);
387
 
                Product[16] = '\0';
388
 
            }
389
 
            else
390
 
            {
391
 
                MV_U32 j = i;
392
 
                memcpy(Vendor, temp, j);
393
 
                for (; j < 9; j++)
394
 
                {
395
 
                    Vendor[j] = ' ';
396
 
                }
397
 
                Vendor[8] = '\0';
398
 
                for (; i < 24; i++)
399
 
                {
400
 
                    if (temp[i] != ' ')
401
 
                    {
402
 
                        break;
403
 
                    }
404
 
                }
405
 
                memcpy(Product, &temp[i], 24 - i);
406
 
                Product[16] = '\0';
407
 
            }
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);
413
 
        }
414
 
        memcpy(&buff[36], "MVSATA", 6);
415
 
 
416
 
        /*buff[32] = '3';*/
417
 
 
418
 
        inquiryLen = 42;
419
 
    }
420
 
    if (pScb->dataBufferLength > inquiryLen)
421
 
    {
422
 
        memcpy(pScb->pDataBuffer, buff, inquiryLen);
423
 
        pScb->dataTransfered = inquiryLen;
424
 
    }
425
 
    else
426
 
    {
427
 
        memcpy(pScb->pDataBuffer, buff, pScb->dataBufferLength);
428
 
        pScb->dataTransfered = pScb->dataBufferLength;
429
 
    }
430
 
    pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
431
 
    pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
432
 
    pScb->senseDataLength = 0;
433
 
#ifdef MV_LOGGER
434
 
    reportScbCompletion(pSataAdapter, pScb);
435
 
#endif
436
 
    pScb->completionCallBack(pSataAdapter, pScb);
437
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
438
 
}
439
 
 
440
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaTestUnitReady(IN  MV_SATA_ADAPTER*    pSataAdapter,
441
 
                                                           IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
442
 
{
443
 
    pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
444
 
    pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
445
 
    pScb->senseDataLength = 0;
446
 
    pScb->dataTransfered = 0;
447
 
 
448
 
#ifdef MV_LOGGER
449
 
    reportScbCompletion(pSataAdapter, pScb);
450
 
#endif
451
 
    pScb->completionCallBack(pSataAdapter, pScb);
452
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
453
 
}
454
 
 
455
 
 
456
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSendDataCommand(IN  MV_SATA_ADAPTER*    pSataAdapter,
457
 
                                                             IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
458
 
{
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;
463
 
    MV_U32                  sectors;
464
 
    MV_U64                  LBA;
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;
479
 
#endif
480
 
#else    
481
 
    MV_QUEUE_COMMAND_INFO commandInfo =
482
 
    {
483
 
        MV_QUEUED_COMMAND_TYPE_UDMA,
484
 
        pScb->target,
485
 
        {
486
 
            {
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,
490
 
                pScb->byteCount,
491
 
#endif
492
 
                SALCommandCompletionCB, (MV_VOID_PTR )pScb
493
 
            }
494
 
        }
495
 
    };
496
 
    MV_QUEUE_COMMAND_INFO *pCommandInfo = &commandInfo;
497
 
    MV_UDMA_COMMAND_PARAMS  *pUdmaParams = &pCommandInfo->commandParams.udmaCommand;
498
 
#endif
499
 
 
500
 
    if ((cmd[0] == SCSI_OPCODE_READ6) || (cmd[0] == SCSI_OPCODE_WRITE6))
501
 
    {
502
 
        pUdmaParams->lowLBAAddress =
503
 
        ( (MV_U32)  cmd[3]) |
504
 
        (((MV_U32)  cmd[2]) << 8) |
505
 
        ((((MV_U32) cmd[1]) & 0x1f) << 16);
506
 
        sectors = (MV_U16) cmd[4];
507
 
    }
508
 
    else if ((cmd[0] == SCSI_OPCODE_READ10) || (cmd[0] == SCSI_OPCODE_WRITE10))
509
 
    {
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);
515
 
 
516
 
        sectors = ((MV_U16) cmd[8]) |
517
 
                (((MV_U16) cmd[7]) << 8);
518
 
        if (cmd[1] & MV_BIT3)
519
 
        {
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;
524
 
        }
525
 
    }
526
 
    else
527
 
    {
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);
533
 
 
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);
539
 
 
540
 
        sectors = (cmd[13]) |
541
 
                  (cmd[12] << 8) |
542
 
                  (cmd[11] << 16) |
543
 
                  (cmd[10] << 24);
544
 
 
545
 
        if (cmd[1] & MV_BIT3)
546
 
        {
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;
551
 
        }
552
 
    }
553
 
    LBA = ((MV_U64)pUdmaParams->highLBAAddress << 32) | (MV_U64)pUdmaParams->lowLBAAddress;
554
 
    pScb->isExtended = pUdmaParams->isEXT = pDriveData->identifyInfo.LBA48Supported;
555
 
 
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 */
561
 
    /* code.                                                                */
562
 
 
563
 
    if (sectors == 0)
564
 
    {
565
 
        if ((cmd[0] == SCSI_OPCODE_READ10) || (cmd[0] == SCSI_OPCODE_WRITE10) || 
566
 
            (cmd[0] == SCSI_OPCODE_WRITE16) || (cmd[0] == SCSI_OPCODE_WRITE16))
567
 
        {
568
 
 
569
 
            if (checkLBAOutOfRange(pSataAdapter, pScb,
570
 
                                   pDriveData->identifyInfo.ATADiskSize,
571
 
                                   LBA, 0) == MV_TRUE)
572
 
            {
573
 
                return MV_SCSI_COMMAND_STATUS_COMPLETED;
574
 
            }
575
 
            pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
576
 
            pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
577
 
            pScb->dataTransfered = 0;
578
 
            pScb->senseDataLength = 0;
579
 
#ifdef MV_LOGGER
580
 
            reportScbCompletion(pSataAdapter, pScb);
581
 
#endif
582
 
            pScb->completionCallBack(pSataAdapter, pScb);
583
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
584
 
        }
585
 
        else
586
 
        {
587
 
            /* READ6 / WRITE6 with sector count 0, which means 256 sectors */
588
 
            sectors = 256;
589
 
        }
590
 
    }
591
 
    if (checkLBAOutOfRange(pSataAdapter, pScb,
592
 
                           pDriveData->identifyInfo.ATADiskSize,
593
 
                           LBA, sectors) == MV_TRUE)
594
 
    {
595
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
596
 
    }
597
 
 
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
600
 
     * request.
601
 
     */
602
 
 
603
 
    if (((sectors > 256) && (pUdmaParams->isEXT == MV_FALSE)) ||
604
 
        ((sectors * ATA_SECTOR_SIZE) != pScb->dataBufferLength))
605
 
    {
606
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
607
 
        pScb->dataTransfered = 0;
608
 
        pScb->senseDataLength = 0;
609
 
#ifdef MV_LOGGER
610
 
        reportScbCompletion(pSataAdapter, pScb);
611
 
#endif
612
 
        pScb->completionCallBack(pSataAdapter, pScb);
613
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
614
 
    }
615
 
 
616
 
    if ((cmd[0] == SCSI_OPCODE_READ6) || (cmd[0] == SCSI_OPCODE_READ10) || 
617
 
        (cmd[0] == SCSI_OPCODE_READ16))
618
 
    {
619
 
        pUdmaParams->readWrite = MV_UDMA_TYPE_READ;
620
 
    }
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;
626
 
 
627
 
    if ((sectors == 256) &&
628
 
        ((pDriveData->identifyInfo.LBA48Supported == MV_FALSE)))
629
 
    {
630
 
        pUdmaParams->numOfSectors = 0;
631
 
    }
632
 
    pUdmaParams->prdLowAddr = pScb->PRDTableLowPhyAddress;
633
 
    pUdmaParams->prdHighAddr = pScb->PRDTableHighPhyAddress;
634
 
 
635
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
636
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
637
 
    {
638
 
        checkQueueCommandResult(pScb, result);
639
 
#ifdef MV_LOGGER
640
 
        reportScbCompletion(pSataAdapter, pScb);
641
 
#endif
642
 
        pScb->completionCallBack(pSataAdapter, pScb);
643
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
644
 
    }
645
 
 
646
 
    /*update statistics*/
647
 
 
648
 
    pAdapterExt->totalAccumulatedOutstanding[pScb->bus] +=
649
 
    mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
650
 
    pDriveData->stats.totalIOs++;
651
 
    pDriveData->stats.totalSectorsTransferred += pUdmaParams->numOfSectors;
652
 
 
653
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
654
 
}
655
 
 
656
 
/*******************************************************************************
657
 
* mvScsiAtaGetReadCapacityData - Get the SCSI-3 Read Capacity (10h/16h) data
658
 
*
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.
662
 
*
663
 
* INPUT:
664
 
*   pSataAdapter    - pointer to the SATA adapter data structure.
665
 
*   pScb->bus    - the index of the specific SATA channel.
666
 
*
667
 
* OUTPUT:
668
 
* RETURN:
669
 
*   MV_TRUE on success, MV_FALSE on failure.
670
 
*
671
 
* COMMENTS:
672
 
*   No sanity check is done for the parameters.
673
 
*
674
 
*******************************************************************************/
675
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetReadCapacityData(IN MV_SATA_ADAPTER*    pSataAdapter,
676
 
                                                                 IN    MV_SATA_SCSI_CMD_BLOCK  *pScb)
677
 
{
678
 
    MV_U32  lastAddressableLBA;
679
 
    MV_U8   *buff;
680
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
681
 
 
682
 
    if ((pScb->ScsiCdb[8] & MV_BIT1) == 0)
683
 
    {
684
 
        if (pScb->ScsiCdb[2] || pScb->ScsiCdb[3] ||pScb->ScsiCdb[4] ||
685
 
            pScb->ScsiCdb[5])
686
 
        {
687
 
 
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;
695
 
#ifdef MV_LOGGER
696
 
            reportScbCompletion(pSataAdapter, pScb);
697
 
#endif
698
 
            pScb->completionCallBack(pSataAdapter, pScb);
699
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
700
 
        }
701
 
    }
702
 
    if((pDriveData->identifyInfo.ATADiskSize >> 32) & 0xFFFFFFFF)
703
 
    {
704
 
            lastAddressableLBA = 0xFFFFFFFF;
705
 
    }
706
 
    else
707
 
    {
708
 
            lastAddressableLBA = pDriveData->identifyInfo.ATADiskSize - 1;
709
 
    }
710
 
    mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "MVSATA: last Addressable sector = 0x%x "
711
 
             " (sec size=%d bytes)\n", lastAddressableLBA, ATA_SECTOR_SIZE);
712
 
 
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.
716
 
     */
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);
723
 
    buff[4] = 0;
724
 
    buff[5] = 0;
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;
731
 
#ifdef MV_LOGGER
732
 
    reportScbCompletion(pSataAdapter, pScb);
733
 
#endif
734
 
    pScb->completionCallBack(pSataAdapter, pScb);
735
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
736
 
}
737
 
 
738
 
/*******************************************************************************
739
 
* mvScsiAtaGetReadCapacity16Data - Get the SCSI-3 Read Capacity (16h) data
740
 
*
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.
744
 
*
745
 
* INPUT:
746
 
*   pSataAdapter    - pointer to the SATA adapter data structure.
747
 
*   pScb->bus    - the index of the specific SATA channel.
748
 
*
749
 
* OUTPUT:
750
 
* RETURN:
751
 
*   MV_TRUE on success, MV_FALSE on failure.
752
 
*
753
 
* COMMENTS:
754
 
*   No sanity check is done for the parameters.
755
 
*
756
 
*******************************************************************************/
757
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetReadCapacity16Data(IN MV_SATA_ADAPTER*    pSataAdapter,
758
 
                                                                 IN    MV_SATA_SCSI_CMD_BLOCK  *pScb)
759
 
{
760
 
    MV_U64  lastAddressableLBA;
761
 
    MV_U8   *buff;
762
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
763
 
 
764
 
    if ((pScb->ScsiCdb[14] & MV_BIT1) == 0)
765
 
    {
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])
769
 
        {
770
 
 
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;
778
 
#ifdef MV_LOGGER
779
 
            reportScbCompletion(pSataAdapter, pScb);
780
 
#endif
781
 
            pScb->completionCallBack(pSataAdapter, pScb);
782
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
783
 
        }
784
 
    }
785
 
 
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);
789
 
 
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.
793
 
     */
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);
804
 
    buff[8] = 0;
805
 
    buff[9] = 0;
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;
812
 
#ifdef MV_LOGGER
813
 
    reportScbCompletion(pSataAdapter, pScb);
814
 
#endif
815
 
    pScb->completionCallBack(pSataAdapter, pScb);
816
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
817
 
}
818
 
 
819
 
 
820
 
/*******************************************************************************
821
 
* mvScsiAtaReportLuns - handle the SCSI-3 Report LUNS
822
 
*
823
 
* DESCRIPTION: Report 1 LUN
824
 
*
825
 
* INPUT:
826
 
*   pSataAdapter    - pointer to the SATA adapter data structure.
827
 
*   pScb->bus    - the index of the specific SATA channel.
828
 
*
829
 
* OUTPUT:
830
 
* RETURN:
831
 
*   MV_TRUE on success, MV_FALSE on failure.
832
 
*
833
 
* COMMENTS:
834
 
*   No sanity check is done for the parameters.
835
 
*
836
 
*******************************************************************************/
837
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaReportLuns(IN MV_SATA_ADAPTER*    pSataAdapter,
838
 
                                                        IN    MV_SATA_SCSI_CMD_BLOCK  *pScb)
839
 
{
840
 
        MV_U8   *buff;
841
 
 
842
 
 
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;
850
 
#ifdef MV_LOGGER
851
 
    reportScbCompletion(pSataAdapter, pScb);
852
 
#endif
853
 
    pScb->completionCallBack(pSataAdapter, pScb);
854
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
855
 
}
856
 
 
857
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSendVerifyCommand(IN MV_SATA_ADAPTER*    pSataAdapter,
858
 
                                                               IN MV_SATA_SCSI_CMD_BLOCK  *pScb)
859
 
{
860
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
861
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
862
 
#else
863
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
864
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
865
 
#endif
866
 
    MV_QUEUE_COMMAND_RESULT result;
867
 
    MV_U8                   *cmd = pScb->ScsiCdb;
868
 
    MV_U64                   LbaAddress;
869
 
    MV_U32                  sectors;
870
 
    MV_U16                  commands;
871
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
872
 
    MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
873
 
 
874
 
    if (cmd[0] == SCSI_OPCODE_VERIFY6)
875
 
    {
876
 
            LbaAddress =
877
 
                    ( (unsigned)  cmd[3]) |
878
 
                    (((unsigned)  cmd[2]) << 8) |
879
 
                    ((((unsigned) cmd[1]) & 0x1f) << 16);
880
 
            sectors = (unsigned) cmd[4];
881
 
    }
882
 
    else if (cmd[0] == SCSI_OPCODE_VERIFY10)
883
 
    {
884
 
            LbaAddress =
885
 
                    (((unsigned) cmd[5]) << 0) |
886
 
                    (((unsigned) cmd[4]) << 8) |
887
 
                    (((unsigned) cmd[3]) << 16) |
888
 
                    (((unsigned) cmd[2]) << 24);
889
 
            
890
 
            
891
 
            sectors = ((unsigned) cmd[8]) |
892
 
                    (((unsigned) cmd[7]) << 8);
893
 
    }
894
 
    else
895
 
    {
896
 
            LbaAddress =
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);
905
 
 
906
 
 
907
 
            sectors = 
908
 
                    ((unsigned) cmd[13]) |
909
 
                    (((unsigned) cmd[12]) << 8) |
910
 
                    (((unsigned) cmd[11]) << 16) |
911
 
                    (((unsigned) cmd[10]) << 24);
912
 
    }
913
 
 
914
 
    if (sectors == 0)
915
 
    {
916
 
        if ((cmd[0] == SCSI_OPCODE_VERIFY10) || (cmd[0] == SCSI_OPCODE_VERIFY16))
917
 
        {
918
 
            if (checkLBAOutOfRange(pSataAdapter, pScb,
919
 
                                   pDriveData->identifyInfo.ATADiskSize,
920
 
                                   LbaAddress, 0) == MV_TRUE)
921
 
            {
922
 
                return MV_SCSI_COMMAND_STATUS_COMPLETED;
923
 
            }
924
 
            pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
925
 
            pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
926
 
            pScb->senseDataLength = 0;
927
 
            pScb->dataTransfered = 0;
928
 
#ifdef MV_LOGGER
929
 
            reportScbCompletion(pSataAdapter, pScb);
930
 
#endif
931
 
            pScb->completionCallBack(pSataAdapter, pScb);
932
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
933
 
        }
934
 
        else
935
 
        {
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
939
 
            */
940
 
 
941
 
            if (pDriveData->identifyInfo.LBA48Supported == MV_TRUE)
942
 
            {
943
 
                sectors = 256;
944
 
            }
945
 
            else
946
 
            {
947
 
                sectors = 0;
948
 
            }
949
 
        }
950
 
        if (checkLBAOutOfRange(pSataAdapter, pScb,
951
 
                               pDriveData->identifyInfo.ATADiskSize,
952
 
                               LbaAddress, 256) == MV_TRUE)
953
 
        {
954
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
955
 
        }
956
 
    }
957
 
    else
958
 
    {
959
 
        if (checkLBAOutOfRange(pSataAdapter, pScb,
960
 
                               pDriveData->identifyInfo.ATADiskSize,
961
 
                               LbaAddress, sectors) == MV_TRUE)
962
 
        {
963
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
964
 
        }
965
 
    }
966
 
 
967
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
968
 
    pScb->LowLbaAddress = (MV_U32)(LbaAddress & 0xFFFFFFFF);
969
 
//    pScb->highLbaAddress = (MV_U32)(LbaAddress >> 32);
970
 
 
971
 
    if (pDriveData->identifyInfo.LBA48Supported == MV_TRUE)
972
 
    {
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);
993
 
 
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);
1001
 
 
1002
 
        result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1003
 
 
1004
 
        if (result != MV_QUEUE_COMMAND_RESULT_OK)
1005
 
        {
1006
 
            checkQueueCommandResult(pScb, result);
1007
 
#ifdef MV_LOGGER
1008
 
            reportScbCompletion(pSataAdapter, pScb);
1009
 
#endif
1010
 
            pScb->completionCallBack(pSataAdapter, pScb);
1011
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
1012
 
        }
1013
 
        /* update stats*/
1014
 
        pAdapterExt->totalAccumulatedOutstanding[pScb->bus] +=
1015
 
        mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1016
 
        pDriveData->stats.totalIOs++;
1017
 
        pDriveData->stats.totalSectorsTransferred += sectors;
1018
 
 
1019
 
    }
1020
 
    else
1021
 
    {
1022
 
        /* The following only in case command is VERIFY 6 with 0 sector count */
1023
 
        if (sectors == 0)
1024
 
        {
1025
 
            commands = 1;
1026
 
        }
1027
 
        else
1028
 
        {
1029
 
            commands = (MV_U16)((((MV_U32)sectors + 0xff) & 0x1ff00) >> 8);
1030
 
        }
1031
 
 
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);
1034
 
 
1035
 
        pScb->splitCount = commands;
1036
 
        pScb->sequenceNumber = 0;
1037
 
        pScb->isExtended = MV_FALSE;
1038
 
        mvScsiAtaSendSplittedVerifyCommand(pScb);
1039
 
    }
1040
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
1041
 
}
1042
 
 
1043
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSeek(IN MV_SATA_ADAPTER    *pSataAdapter,
1044
 
                                                  IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
1045
 
{
1046
 
    MV_U32 lbaAddress;
1047
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1048
 
 
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)
1056
 
    {
1057
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1058
 
    }
1059
 
    pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1060
 
    pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1061
 
    pScb->dataTransfered = 0;
1062
 
    pScb->senseDataLength = 0;
1063
 
#ifdef MV_LOGGER
1064
 
    reportScbCompletion(pSataAdapter, pScb);
1065
 
#endif
1066
 
    pScb->completionCallBack(pSataAdapter, pScb);
1067
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
1068
 
 
1069
 
}
1070
 
 
1071
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaReassignBlocks(IN MV_SATA_ADAPTER    *pSataAdapter,
1072
 
                                                            IN MV_SATA_SCSI_CMD_BLOCK  *pScb)
1073
 
{
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;
1078
 
#ifdef MV_LOGGER
1079
 
    reportScbCompletion(pSataAdapter, pScb);
1080
 
#endif
1081
 
    pScb->completionCallBack(pSataAdapter, pScb);
1082
 
    return MV_TRUE;
1083
 
 
1084
 
}
1085
 
 
1086
 
 
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)
1090
 
{
1091
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1092
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
1093
 
#else
1094
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
1095
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
1096
 
#endif
1097
 
    MV_QUEUE_COMMAND_RESULT result;
1098
 
    MV_U32                  LBA;
1099
 
    MV_U16                  eccBytes;
1100
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1101
 
    MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
1102
 
 
1103
 
    memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1104
 
 
1105
 
 
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);
1110
 
 
1111
 
    eccBytes = (MV_U16)pScb->ScsiCdb[8];
1112
 
 
1113
 
    if ((pScb->ScsiCdb[7] != 2) || ((eccBytes != 4) && (eccBytes != 8)))
1114
 
    {
1115
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
1116
 
        pScb->dataTransfered = 0;
1117
 
        pScb->senseDataLength = 0;
1118
 
#ifdef MV_LOGGER
1119
 
        reportScbCompletion(pSataAdapter, pScb);
1120
 
#endif
1121
 
        pScb->completionCallBack(pSataAdapter, pScb);
1122
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1123
 
    }
1124
 
    if (checkLBAOutOfRange(pSataAdapter, pScb,
1125
 
                           pDriveData->identifyInfo.ATADiskSize,
1126
 
                           LBA, 1) == MV_TRUE)
1127
 
    {
1128
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1129
 
    }
1130
 
 
1131
 
    /*if (checkLBAOutOfRange(pSataAdapter, pScb, MV_BIT28 - 2,
1132
 
                        LBA, 1) == MV_TRUE)
1133
 
    {
1134
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1135
 
    }*/
1136
 
    if (LBA & (MV_BIT31|MV_BIT30|MV_BIT29|MV_BIT28))
1137
 
    {
1138
 
 
1139
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Error LBA (0x%x) out of range.\n", LBA);
1140
 
 
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;
1146
 
#ifdef MV_LOGGER
1147
 
        reportScbCompletion(pSataAdapter, pScb);
1148
 
#endif
1149
 
        pScb->completionCallBack(pSataAdapter, pScb);
1150
 
        return MV_TRUE;
1151
 
    }
1152
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1153
 
 
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;
1170
 
 
1171
 
 
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);
1174
 
 
1175
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1176
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
1177
 
    {
1178
 
        checkQueueCommandResult(pScb, result);
1179
 
        /* shoudl complete the Scsi request here*/
1180
 
#ifdef MV_LOGGER
1181
 
        reportScbCompletion(pSataAdapter, pScb);
1182
 
#endif
1183
 
        pScb->completionCallBack(pSataAdapter, pScb);
1184
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1185
 
    }
1186
 
    /* update stats*/
1187
 
    pAdapterExt->totalAccumulatedOutstanding[pScb->bus] += mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1188
 
    pDriveData->stats.totalIOs++;
1189
 
 
1190
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
1191
 
}
1192
 
static MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaReadLong(IN MV_SATA_ADAPTER    *pSataAdapter,
1193
 
                                                     IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
1194
 
{
1195
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1196
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
1197
 
#else
1198
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
1199
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
1200
 
#endif
1201
 
    MV_QUEUE_COMMAND_RESULT result;
1202
 
    MV_U32                  LBA;
1203
 
    MV_U16                  eccBytes;
1204
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1205
 
    MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
1206
 
 
1207
 
    memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1208
 
 
1209
 
 
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);
1214
 
 
1215
 
    eccBytes = (MV_U16)pScb->ScsiCdb[8];
1216
 
 
1217
 
    if ((pScb->ScsiCdb[7] != 2) || ((eccBytes != 4) && (eccBytes != 8)))
1218
 
    {
1219
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCB;
1220
 
        pScb->dataTransfered = 0;
1221
 
        pScb->senseDataLength = 0;
1222
 
#ifdef MV_LOGGER
1223
 
        reportScbCompletion(pSataAdapter, pScb);
1224
 
#endif
1225
 
        pScb->completionCallBack(pSataAdapter, pScb);
1226
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1227
 
    }
1228
 
    if (checkLBAOutOfRange(pSataAdapter, pScb,
1229
 
                           pDriveData->identifyInfo.ATADiskSize,
1230
 
                           LBA, 1) == MV_TRUE)
1231
 
    {
1232
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1233
 
    }
1234
 
 
1235
 
    /*if (checkLBAOutOfRange(pSataAdapter, pScb, MV_BIT28 - 2,
1236
 
                        LBA, 1) == MV_TRUE)
1237
 
    {
1238
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1239
 
    }*/
1240
 
    if (LBA & (MV_BIT31|MV_BIT30|MV_BIT29|MV_BIT28))
1241
 
    {
1242
 
 
1243
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Error LBA (0x%x) out of range.\n", LBA);
1244
 
 
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;
1250
 
#ifdef MV_LOGGER
1251
 
        reportScbCompletion(pSataAdapter, pScb);
1252
 
#endif
1253
 
        pScb->completionCallBack(pSataAdapter, pScb);
1254
 
        return MV_TRUE;
1255
 
    }
1256
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1257
 
 
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;
1274
 
 
1275
 
 
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);
1278
 
 
1279
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1280
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
1281
 
    {
1282
 
        checkQueueCommandResult(pScb, result);
1283
 
        /* shoudl complete the Scsi request here*/
1284
 
#ifdef MV_LOGGER
1285
 
        reportScbCompletion(pSataAdapter, pScb);
1286
 
#endif
1287
 
        pScb->completionCallBack(pSataAdapter, pScb);
1288
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1289
 
    }
1290
 
    /* update stats*/
1291
 
    pAdapterExt->totalAccumulatedOutstanding[pScb->bus] += mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1292
 
    pDriveData->stats.totalIOs++;
1293
 
 
1294
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
1295
 
}
1296
 
#endif
1297
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaSendSyncCacheCommand(IN MV_SATA_ADAPTER    *pSataAdapter,
1298
 
                                                                      IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
1299
 
{
1300
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1301
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
1302
 
#else
1303
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
1304
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
1305
 
#endif
1306
 
    MV_QUEUE_COMMAND_RESULT result;
1307
 
    MV_U64                  LBA;
1308
 
    MV_U32                  sectors;
1309
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1310
 
    MV_SAL_ADAPTER_EXTENSION *pAdapterExt = pScb->pSalAdapterExtension;
1311
 
 
1312
 
    /* Check if IMMED bit is set, if so then return ILLEGAL REQUEST */
1313
 
    if (pScb->ScsiCdb[1] & MV_BIT1)
1314
 
    {
1315
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Synchronise cache completed with error:"
1316
 
                 " IMMED is set\n", pSataAdapter->adapterId,
1317
 
                 pScb->bus);
1318
 
 
1319
 
        setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB,
1320
 
                     0);
1321
 
        pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1322
 
        pScb->dataTransfered = 0;
1323
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1324
 
#ifdef MV_LOGGER
1325
 
        reportScbCompletion(pSataAdapter, pScb);
1326
 
#endif
1327
 
        pScb->completionCallBack(pSataAdapter, pScb);
1328
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1329
 
    }
1330
 
 
1331
 
    memset(pCommandInfo, 0, sizeof(MV_QUEUE_COMMAND_INFO));
1332
 
 
1333
 
    if(pScb->ScsiCdb[0] == SCSI_OPCODE_SYNCHRONIZE_CACHE10)
1334
 
    {
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);
1339
 
            
1340
 
            sectors = ((MV_U32) pScb->ScsiCdb[8]) |
1341
 
                    (((MV_U32) pScb->ScsiCdb[7]) << 8);
1342
 
    }
1343
 
    else
1344
 
    {
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);
1353
 
            
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);
1358
 
    }
1359
 
    if (checkLBAOutOfRange(pSataAdapter, pScb,
1360
 
                           pDriveData->identifyInfo.ATADiskSize,LBA, sectors)
1361
 
        == MV_TRUE)
1362
 
    {
1363
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1364
 
    }
1365
 
 
1366
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
1367
 
 
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);
1382
 
 
1383
 
    if (pDriveData->identifyInfo.LBA48Supported == MV_TRUE)
1384
 
    {
1385
 
        pScb->isExtended = MV_TRUE;
1386
 
        pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_FLUSH_CACHE_EXT;
1387
 
        pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_TRUE;
1388
 
    }
1389
 
    else
1390
 
    {
1391
 
        pScb->isExtended = MV_FALSE;
1392
 
        pCommandInfo->commandParams.NoneUdmaCommand.command = MV_ATA_COMMAND_FLUSH_CACHE;
1393
 
        pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
1394
 
 
1395
 
    }
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);
1399
 
 
1400
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1401
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
1402
 
    {
1403
 
        checkQueueCommandResult(pScb, result);
1404
 
        /* shoudl complete the Scsi request here*/
1405
 
#ifdef MV_LOGGER
1406
 
        reportScbCompletion(pSataAdapter, pScb);
1407
 
#endif
1408
 
        pScb->completionCallBack(pSataAdapter, pScb);
1409
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1410
 
    }
1411
 
    /* update stats*/
1412
 
    pAdapterExt->totalAccumulatedOutstanding[pScb->bus] += mvSataNumOfDmaCommands(pSataAdapter,pScb->bus);
1413
 
    pDriveData->stats.totalIOs++;
1414
 
 
1415
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
1416
 
}
1417
 
 
1418
 
/*******************************************************************************
1419
 
* mvScsiAtaGetRequestSenseData - Get the SCSI-3 Request Sense(03h) data
1420
 
*
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.
1423
 
*
1424
 
* INPUT:
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.
1428
 
*
1429
 
* OUTPUT:
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).
1435
 
*
1436
 
* RETURN:
1437
 
*   MV_TRUE on success, MV_FALSE on failure.
1438
 
*
1439
 
* COMMENTS:
1440
 
*   No sanity check is done for the parameters.
1441
 
*
1442
 
*******************************************************************************/
1443
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetRequestSenseData(IN MV_SATA_ADAPTER*    pSataAdapter,
1444
 
                                                                 IN MV_SATA_SCSI_CMD_BLOCK  *pScb)
1445
 
{
1446
 
    MV_SCSI_SENSE_DATA SenseData;
1447
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1448
 
 
1449
 
    memset(pScb->pDataBuffer, 0, pScb->dataBufferLength);
1450
 
 
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;
1457
 
 
1458
 
    pScb->senseDataLength = 0;
1459
 
    if (pDriveData->UAConditionPending == MV_TRUE)
1460
 
    {
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)
1464
 
        {
1465
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Report Bus Reset.\n");
1466
 
 
1467
 
            SenseData.AdditionalSenseCode = SCSI_ADSENSE_BUS_RESET;
1468
 
            SenseData.AdditionalSenseCodeQualifier = 2;
1469
 
            pDriveData->UAEvents &= ~MV_BIT0;
1470
 
        }
1471
 
        else if (pDriveData->UAEvents & MV_BIT1)
1472
 
        {
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;
1477
 
        }
1478
 
 
1479
 
        pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1480
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1481
 
        if (pDriveData->UAEvents == 0)
1482
 
        {
1483
 
            pDriveData->UAConditionPending = MV_FALSE;
1484
 
        }
1485
 
    }
1486
 
    else
1487
 
    {
1488
 
        pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1489
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1490
 
    }
1491
 
    if (pScb->dataBufferLength >= sizeof(MV_SCSI_SENSE_DATA))
1492
 
    {
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;*/
1497
 
    }
1498
 
    else
1499
 
    {
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;
1504
 
    }
1505
 
#ifdef MV_LOGGER
1506
 
    reportScbCompletion(pSataAdapter, pScb);
1507
 
#endif
1508
 
    pScb->completionCallBack(pSataAdapter, pScb);
1509
 
    return MV_SCSI_COMMAND_STATUS_COMPLETED;
1510
 
}
1511
 
 
1512
 
/*******************************************************************************
1513
 
* mvScsiAtaGetModeSenseData - Get the SCSI-3 Mode Sense data
1514
 
*
1515
 
* DESCRIPTION: This function issues ATA Identify command, in the command
1516
 
*       completion, the Mode Sense data will be filled according to the returned
1517
 
*       Identify Data.
1518
 
*
1519
 
* INPUT:
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.
1523
 
*
1524
 
* RETURN:
1525
 
*   MV_TRUE on success, MV_FALSE on failure.
1526
 
*
1527
 
* COMMENTS:
1528
 
*   No sanity check is done for the parameters.
1529
 
*
1530
 
*******************************************************************************/
1531
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaGetModeSenseData(IN MV_SATA_ADAPTER    *pSataAdapter,
1532
 
                                                              IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
1533
 
{
1534
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1535
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
1536
 
#else
1537
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
1538
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
1539
 
#endif
1540
 
    MV_QUEUE_COMMAND_RESULT result;
1541
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1542
 
 
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",
1556
 
             pScb->bus, pScb);
1557
 
 
1558
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
1559
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
1560
 
    {
1561
 
        checkQueueCommandResult(pScb, result);
1562
 
        /* shoudl complete the Scsi request here*/
1563
 
#ifdef MV_LOGGER
1564
 
        reportScbCompletion(pSataAdapter, pScb);
1565
 
#endif
1566
 
        pScb->completionCallBack(pSataAdapter, pScb);
1567
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1568
 
    }
1569
 
 
1570
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
1571
 
}
1572
 
static MV_BOOLEAN  mvScsiAtaGetModeSenseDataPhase2(IN MV_SATA_ADAPTER    *pSataAdapter,
1573
 
                                                   IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
1574
 
{
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];
1580
 
    MV_U32  offset;
1581
 
    MV_U32  pageLength;
1582
 
    MV_BOOLEAN  commandFailed = MV_FALSE;
1583
 
 
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]);
1589
 
 
1590
 
 
1591
 
    if (pageControl == 0x3)
1592
 
    {
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;
1597
 
    }
1598
 
    if (commandFailed != MV_TRUE)
1599
 
    {
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)
1607
 
        {
1608
 
            modeSenseResult[2] = MV_BIT4;
1609
 
        }
1610
 
 
1611
 
        /* Block descriptor length 0: no block descriptors*/
1612
 
 
1613
 
        /*2. Block descriptor(s): Empty list*/
1614
 
        /*3. Page(s)*/
1615
 
        offset = 4;
1616
 
 
1617
 
        switch (pageCode)
1618
 
        {
1619
 
        case 0x3f:
1620
 
        case 0x8: /*Caching page */
1621
 
            pageLength = mvModeSenseCachingPage(pScb,
1622
 
                                                modeSenseResult + offset,
1623
 
                                                pageControl);
1624
 
 
1625
 
            offset += pageLength;
1626
 
 
1627
 
            if (pageCode == 0x8)
1628
 
            {
1629
 
                break;
1630
 
            }
1631
 
        case 0xa:
1632
 
            pageLength = mvModeSenseControlPage(pSataAdapter,pScb,
1633
 
                                                modeSenseResult + offset,
1634
 
                                                pageControl);
1635
 
 
1636
 
            offset += pageLength;
1637
 
            break;
1638
 
        default:
1639
 
            AdditionalSenseCode = SCSI_ADSENSE_INVALID_CDB;
1640
 
            commandFailed = MV_TRUE;
1641
 
        }
1642
 
 
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);
1646
 
 
1647
 
        if (pScb->dataBufferLength < offset)
1648
 
        {
1649
 
            memcpy(pScb->pDataBuffer, modeSenseResult, pScb->dataBufferLength);
1650
 
            pScb->dataTransfered = pScb->dataBufferLength;
1651
 
        }
1652
 
        else
1653
 
        {
1654
 
            memcpy(pScb->pDataBuffer, modeSenseResult, offset);
1655
 
            pScb->dataTransfered = offset;
1656
 
        }
1657
 
    }
1658
 
 
1659
 
    if (commandFailed == MV_TRUE)
1660
 
    {
1661
 
        setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, AdditionalSenseCode, 0);
1662
 
 
1663
 
        pScb->dataTransfered = 0;
1664
 
        pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1665
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1666
 
    }
1667
 
    else
1668
 
    {
1669
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1670
 
        pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1671
 
    }
1672
 
    return MV_TRUE;
1673
 
}
1674
 
static MV_SCSI_COMMAND_STATUS_TYPE  mvScsiAtaModeSelect(IN MV_SATA_ADAPTER    *pSataAdapter,
1675
 
                                                        IN  MV_SATA_SCSI_CMD_BLOCK  *pScb)
1676
 
{
1677
 
    MV_U8 result;
1678
 
    MV_SCSI_COMMAND_STATUS_TYPE     commandStatus;
1679
 
    mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " MODE SELECT RECEIVED: cmd:");
1680
 
    {
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]);
1683
 
    }
1684
 
    result = modeSelect(pSataAdapter, pScb, &commandStatus);
1685
 
    if (result != 0x0)
1686
 
    {
1687
 
        if (result == 0x1)/*PARAMETER LIST LENGTH ERROR*/
1688
 
        {
1689
 
            setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, 0x1a, 0);
1690
 
 
1691
 
        }
1692
 
        else if (result == 0x2)
1693
 
        {
1694
 
            setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1695
 
                         SCSI_ADSENSE_INVALID_CDB, 0);
1696
 
 
1697
 
        }
1698
 
        else if (result == 0x3)
1699
 
        {
1700
 
            setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1701
 
                         SCSI_ADSENSE_INVALID_FIELD_IN_PARAMETER_LIST, 0);
1702
 
 
1703
 
        }
1704
 
        else
1705
 
        {
1706
 
            setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST,
1707
 
                         SCSI_ADSENSE_NO_SENSE, 0);
1708
 
 
1709
 
        }
1710
 
 
1711
 
        pScb->dataTransfered = 0;
1712
 
        pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
1713
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
1714
 
#ifdef MV_LOGGER
1715
 
        reportScbCompletion(pSataAdapter, pScb);
1716
 
#endif
1717
 
        pScb->completionCallBack(pSataAdapter, pScb);
1718
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
1719
 
    }
1720
 
    return commandStatus;
1721
 
}
1722
 
 
1723
 
static MV_U8
1724
 
modeSelect(IN MV_SATA_ADAPTER    *pSataAdapter,
1725
 
           IN  MV_SATA_SCSI_CMD_BLOCK  *pScb,
1726
 
           MV_SCSI_COMMAND_STATUS_TYPE *pCommandStatus)
1727
 
{
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;
1734
 
    MV_U32  offset;
1735
 
    MV_U32  cachePageOffset = 0;
1736
 
 
1737
 
    {
1738
 
        MV_U32 i;
1739
 
        for (i =0 ; i < length; i++)
1740
 
        {
1741
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %02x", list[i]);
1742
 
        }
1743
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "\n");
1744
 
    }
1745
 
    if (PF == 0)
1746
 
    {
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 */
1750
 
    }
1751
 
    if (SP == 1)
1752
 
    {
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 */
1756
 
    }
1757
 
    if (length == 0)
1758
 
    {
1759
 
        pScb->dataTransfered = 0;
1760
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1761
 
        pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1762
 
#ifdef MV_LOGGER
1763
 
        reportScbCompletion(pSataAdapter, pScb);
1764
 
#endif
1765
 
        pScb->completionCallBack(pSataAdapter, pScb);
1766
 
        *pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1767
 
        return 0;
1768
 
    }
1769
 
    if (length < 4)
1770
 
    {
1771
 
        return 0x1; /* PARAMETER LIST LENGTH ERROR */
1772
 
    }
1773
 
    if (list[0] || (list[1] != MV_SCSI_DIRECT_ACCESS_DEVICE) || list[2])
1774
 
    {
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 */
1778
 
    }
1779
 
    if (list[3])
1780
 
    {
1781
 
        if (list[3] != 8)
1782
 
        {
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 */
1787
 
        }
1788
 
        if (length < 12)
1789
 
        {
1790
 
            return 0x1; /* PARAMETER LIST LENGTH ERROR */
1791
 
        }
1792
 
        if (list[4] || list[5] || list[6] || list[7] || list[8] || list[9] ||
1793
 
            (list[10] != 0x2) || list[11])
1794
 
        {
1795
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: invalid field in parameter "
1796
 
                     "block descriptor list\n", pSataAdapter->adapterId,
1797
 
                     pScb->bus);
1798
 
            return 0x3; /* Invalid field in parameter list */
1799
 
        }
1800
 
    }
1801
 
    offset = 4 + list[3];/* skip the mode parameter block descriptor */
1802
 
 
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,
1806
 
             offset);
1807
 
    if (length == offset)
1808
 
    {
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;
1814
 
#ifdef MV_LOGGER
1815
 
        reportScbCompletion(pSataAdapter, pScb);
1816
 
#endif
1817
 
        pScb->completionCallBack(pSataAdapter, pScb);
1818
 
        *pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1819
 
        return 0;
1820
 
    }
1821
 
 
1822
 
    while ((offset + 2) < length)
1823
 
    {
1824
 
        switch (list[offset] & 0x3f)
1825
 
        {
1826
 
        case 0x8:
1827
 
            if (list[offset + 1] != 0x12)
1828
 
            {
1829
 
                mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d: Mode Select Error: bad length in caching mode "
1830
 
                         "page %d\n.",
1831
 
                         pSataAdapter->adapterId, pScb->bus, list[offset + 1]);
1832
 
                return 0x3; /* Invalid field in parameter list */
1833
 
            }
1834
 
            cachePageOffset = offset;
1835
 
            offset += list[offset + 1] + 2;
1836
 
            break;
1837
 
        case 0xa:
1838
 
            if ((list[offset] != 0xa) || (list[offset+1] != 0xa))
1839
 
            {
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]);
1844
 
                return 0x3;
1845
 
            }
1846
 
 
1847
 
            if (list[offset + 3] != MV_BIT4)
1848
 
            {
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,
1852
 
                         list[offset + 3]);
1853
 
                return 0x3;
1854
 
            }
1855
 
 
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])
1859
 
            {
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__);
1863
 
                return 0x3;
1864
 
            }
1865
 
            offset += list[offset + 1] + 2;
1866
 
            break;
1867
 
        default:
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],
1871
 
                     offset);
1872
 
            return 0x3; /* Invalid field in parameter list */
1873
 
        }
1874
 
    }
1875
 
 
1876
 
    if (length != offset)
1877
 
    {
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 */
1881
 
    }
1882
 
 
1883
 
    if (cachePageOffset)
1884
 
    {
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);
1887
 
    }
1888
 
    else
1889
 
    {
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;
1894
 
#ifdef MV_LOGGER
1895
 
        reportScbCompletion(pSataAdapter, pScb);
1896
 
#endif
1897
 
        pScb->completionCallBack(pSataAdapter, pScb);
1898
 
        *pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1899
 
        return 0;
1900
 
    }
1901
 
}
1902
 
 
1903
 
static MV_U8
1904
 
mvParseModeCachingPage(MV_SATA_ADAPTER *pSataAdapter,
1905
 
                       IN  MV_SATA_SCSI_CMD_BLOCK  *pScb,
1906
 
                       MV_U8 *buffer,
1907
 
                       MV_SCSI_COMMAND_STATUS_TYPE *pCommandStatus)
1908
 
{
1909
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
1910
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
1911
 
#else
1912
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
1913
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
1914
 
#endif
1915
 
    MV_QUEUE_COMMAND_RESULT result;
1916
 
    MV_U8                   index = 0;
1917
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
1918
 
 
1919
 
 
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++])
1929
 
    {
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,
1932
 
                 index);
1933
 
        return 0x3; /* Invalid field in parameter list */
1934
 
    }
1935
 
 
1936
 
    pScb->splitCount = 2;
1937
 
    pScb->sequenceNumber = 1;
1938
 
    if (buffer[12] & MV_BIT5) /* Disable Look Ahead*/
1939
 
    {
1940
 
        if (pDriveData->identifyInfo.readAheadSupported == MV_FALSE)
1941
 
        {
1942
 
            pScb->splitCount--;
1943
 
        }
1944
 
        pScb->LowLbaAddress = 0;
1945
 
    }
1946
 
    else
1947
 
    {
1948
 
        if (pDriveData->identifyInfo.readAheadSupported == MV_FALSE)
1949
 
        {
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 */
1954
 
        }
1955
 
        pScb->LowLbaAddress = 1;
1956
 
    }
1957
 
 
1958
 
    if (buffer[2] & MV_BIT2) /* enable write cache*/
1959
 
    {
1960
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Parse Caching Page: enable Write Cache\n");
1961
 
        if (pDriveData->identifyInfo.writeCacheSupported == MV_FALSE)
1962
 
        {
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 */
1967
 
        }
1968
 
        pCommandInfo->commandParams.NoneUdmaCommand.features = MV_ATA_SET_FEATURES_ENABLE_WCACHE;
1969
 
    }
1970
 
    else
1971
 
    {
1972
 
        if (pDriveData->identifyInfo.writeCacheSupported == MV_FALSE)
1973
 
        {
1974
 
            pScb->splitCount--;
1975
 
            if (pScb->splitCount == 1)
1976
 
            {
1977
 
                mvScsiAtaSendReadLookAhead(pSataAdapter, pScb);
1978
 
                *pCommandStatus = MV_SCSI_COMMAND_STATUS_QUEUED;
1979
 
                return 0;
1980
 
            }
1981
 
        }
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;
1984
 
    }
1985
 
 
1986
 
    if (pScb->splitCount == 0)
1987
 
    {
1988
 
        pScb->dataTransfered = 0;
1989
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
1990
 
        pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
1991
 
#ifdef MV_LOGGER
1992
 
        reportScbCompletion(pSataAdapter, pScb);
1993
 
#endif
1994
 
        pScb->completionCallBack(pSataAdapter, pScb);
1995
 
        *pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
1996
 
        return 0;
1997
 
    }
1998
 
 
1999
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2000
 
 
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;
2008
 
 
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);
2016
 
 
2017
 
    mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending SET FEATURES command: features %d\n",
2018
 
             pCommandInfo->commandParams.NoneUdmaCommand.features);
2019
 
 
2020
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
2021
 
 
2022
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
2023
 
    {
2024
 
        checkQueueCommandResult(pScb, result);
2025
 
#ifdef MV_LOGGER
2026
 
        reportScbCompletion(pSataAdapter, pScb);
2027
 
#endif
2028
 
        pScb->completionCallBack(pSataAdapter, pScb);
2029
 
        *pCommandStatus = MV_SCSI_COMMAND_STATUS_COMPLETED;
2030
 
 
2031
 
        return 0;
2032
 
    }
2033
 
    *pCommandStatus = MV_SCSI_COMMAND_STATUS_QUEUED;
2034
 
    return 0;
2035
 
}
2036
 
 
2037
 
static MV_U32
2038
 
mvModeSenseCachingPage(MV_SATA_SCSI_CMD_BLOCK  *pScb,
2039
 
                       MV_U8 *buffer,MV_U8 pageControl)
2040
 
{
2041
 
    MV_SATA_SCSI_DRIVE_DATA *pDriveData = &pScb->pSalAdapterExtension->ataDriveData[pScb->bus][pScb->target];
2042
 
 
2043
 
 
2044
 
    buffer[0] = 0x8; /* caching page*/
2045
 
    buffer[1] = 0x12; /* length = 2 + 0x12*/
2046
 
    buffer[2] = 0;
2047
 
    if (pageControl == 2) /*default values*/
2048
 
    {
2049
 
        if (pDriveData->identifyInfo.writeCacheSupported == MV_TRUE)
2050
 
        {
2051
 
            buffer[2] = MV_BIT2;
2052
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: writeCacheEnabledByDefault\n");
2053
 
        }
2054
 
    }
2055
 
    else if (pageControl == 0)  /* current values*/
2056
 
    {
2057
 
        if ((pDriveData->identifyInfo.writeCacheSupported == MV_TRUE) &&
2058
 
            (pDriveData->identifyBuffer[85] & MV_BIT5))
2059
 
        {
2060
 
            buffer[2] = MV_BIT2;
2061
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: writeCacheEnabled\n");
2062
 
        }
2063
 
    }
2064
 
    else if (pageControl == 1)  /* changeable values*/
2065
 
    {
2066
 
        if (pDriveData->identifyInfo.writeCacheSupported == MV_TRUE)
2067
 
        {
2068
 
            buffer[2] = MV_BIT2;
2069
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: writeCacheSupported\n");
2070
 
        }
2071
 
    }
2072
 
 
2073
 
    buffer[3] = 0;
2074
 
    if (pageControl != 1)
2075
 
    {
2076
 
        buffer[4] = 0xff;
2077
 
        buffer[5] = 0xff;
2078
 
        buffer[9] = 0x10;
2079
 
        buffer[11] = 0x10;
2080
 
    }
2081
 
    if (pageControl == 2) /*default values*/
2082
 
    {
2083
 
        if (pDriveData->identifyInfo.readAheadSupported == MV_FALSE)
2084
 
        {
2085
 
            buffer[12] = MV_BIT5;
2086
 
        }
2087
 
    }
2088
 
    else if (pageControl == 0)  /* current values*/
2089
 
    {
2090
 
        if ((pDriveData->identifyInfo.readAheadSupported == MV_TRUE) &&
2091
 
            (pDriveData->identifyBuffer[85] & MV_BIT6))
2092
 
        {
2093
 
            buffer[12] = 0;
2094
 
        }
2095
 
        else
2096
 
        {
2097
 
            buffer[12] = MV_BIT5;
2098
 
        }
2099
 
    }
2100
 
    else if (pageControl == 1)  /* changeable values*/
2101
 
    {
2102
 
        if (pDriveData->identifyInfo.readAheadSupported == MV_TRUE)
2103
 
        {
2104
 
            buffer[12] = MV_BIT5;
2105
 
        }
2106
 
    }
2107
 
    if (pageControl != 1)
2108
 
    {
2109
 
        buffer[13] = 0x01;
2110
 
        buffer[14] = 0xff;
2111
 
        buffer[15] = 0xff;
2112
 
    }
2113
 
 
2114
 
    {
2115
 
        MV_U32 i;
2116
 
 
2117
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Cache Page: \n");
2118
 
        for (i = 0; i < 0x14; i++)
2119
 
        {
2120
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "[%d] %x\n",i, buffer[i]);
2121
 
        }
2122
 
    }
2123
 
    return 0x14;
2124
 
}
2125
 
 
2126
 
static MV_U32
2127
 
mvModeSenseControlPage(MV_SATA_ADAPTER *pSataAdapter,
2128
 
                       MV_SATA_SCSI_CMD_BLOCK  *pScb,
2129
 
                       MV_U8 *buffer, MV_U8 pageControl)
2130
 
{
2131
 
    buffer[0] = 0xA;    /* control page */
2132
 
    buffer[1] = 0xA;    /* length 2 + 0xa*/
2133
 
    if (pageControl != 1)
2134
 
    {
2135
 
        buffer[3] = MV_BIT4/*Unrestricted reordering allowed*/;
2136
 
    }
2137
 
 
2138
 
    {
2139
 
        MV_U32 i;
2140
 
 
2141
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Control Page: \n");
2142
 
        for (i = 0; i < 0xc; i++)
2143
 
        {
2144
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "[%d] %x\n",i , buffer[i]);
2145
 
        }
2146
 
    }
2147
 
    return 0xc;
2148
 
}
2149
 
 
2150
 
static MV_BOOLEAN
2151
 
SALCommandCompletionCB(MV_SATA_ADAPTER *pSataAdapter,
2152
 
                       MV_U8 channelNum,
2153
 
                       MV_COMPLETION_TYPE comp_type,
2154
 
                       MV_VOID_PTR commandId,
2155
 
                       MV_U16 responseFlags,
2156
 
                       MV_U32 timeStamp,
2157
 
                       MV_STORAGE_DEVICE_REGISTERS *registerStruct)
2158
 
{
2159
 
    MV_SATA_SCSI_CMD_BLOCK  *pScb;
2160
 
    if (commandId == NULL)
2161
 
    {
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);
2164
 
        return MV_FALSE;
2165
 
    }
2166
 
 
2167
 
    pScb = commandId;
2168
 
    switch (comp_type)
2169
 
    {
2170
 
    case MV_COMPLETION_TYPE_NORMAL:
2171
 
        /* finish */
2172
 
#ifdef  MV_SUPPORT_ATAPI
2173
 
        if(pScb->commandType == MV_QUEUED_COMMAND_TYPE_PACKET)
2174
 
        {
2175
 
            if ((registerStruct->statusRegister & MV_ATA_ERROR_STATUS) ||
2176
 
               (registerStruct->statusRegister & MV_ATA_DEVICE_FAULT_STATUS))  
2177
 
            {
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);
2181
 
            }
2182
 
            else
2183
 
            {
2184
 
                pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
2185
 
            }
2186
 
            pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
2187
 
            pScb->dataTransfered = timeStamp;
2188
 
            break;
2189
 
        }
2190
 
#endif
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))
2197
 
        {
2198
 
            /* add the command to the list for post interrupt service*/
2199
 
            pScb->pNext = pScb->pSalAdapterExtension->pHead;
2200
 
            pScb->pSalAdapterExtension->pHead = pScb;
2201
 
            return MV_TRUE;
2202
 
        }
2203
 
        if (pScb->ScsiCdb[0] == SCSI_OPCODE_MODE_SENSE6)
2204
 
        {
2205
 
            mvScsiAtaGetModeSenseDataPhase2(pSataAdapter, pScb);
2206
 
        }
2207
 
        else
2208
 
        {
2209
 
            pScb->ScsiStatus = MV_SCSI_STATUS_GOOD;
2210
 
            pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_SUCCESS;
2211
 
        }
2212
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "command completed. pScb %p\n", pScb);
2213
 
 
2214
 
        break;
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]);
2221
 
 
2222
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_ABORTED;
2223
 
        pScb->dataTransfered = 0;
2224
 
        pScb->senseDataLength = 0;
2225
 
        mvCommandCompletionErrorHandler(pScb->pIalAdapterExtension, channelNum);
2226
 
        break;
2227
 
    case MV_COMPLETION_TYPE_ERROR:
2228
 
        pScb->dataTransfered = 0;
2229
 
        pScb->senseDataLength = 0;
2230
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_ATA_FAILED;
2231
 
 
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                                 */
2241
 
 
2242
 
        if (pScb->commandType == MV_QUEUED_COMMAND_TYPE_UDMA)
2243
 
        {
2244
 
            handleUdmaError(pScb, responseFlags, registerStruct);
2245
 
#ifdef MV_LOGGER
2246
 
            memcpy(&pScb->ATAregStruct, registerStruct,
2247
 
                   sizeof(pScb->ATAregStruct));
2248
 
#endif
2249
 
        }
2250
 
        else
2251
 
        {
2252
 
            handleNoneUdmaError(pScb, registerStruct);
2253
 
#ifdef MV_LOGGER
2254
 
            memcpy(&pScb->ATAregStruct, registerStruct,
2255
 
                   sizeof(pScb->ATAregStruct));
2256
 
#endif
2257
 
        }
2258
 
        mvCommandCompletionErrorHandler(pScb->pIalAdapterExtension, channelNum);
2259
 
        break;
2260
 
    default:
2261
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_FATAL_ERROR, " Unknown completion type (%d)\n", comp_type);
2262
 
        return MV_FALSE;
2263
 
    }
2264
 
#ifdef MV_LOGGER
2265
 
    reportScbCompletion(pSataAdapter, pScb);
2266
 
#endif
2267
 
 
2268
 
    pScb->completionCallBack(pSataAdapter, pScb);
2269
 
    return MV_TRUE;
2270
 
}
2271
 
MV_VOID
2272
 
handleNoneUdmaError(MV_SATA_SCSI_CMD_BLOCK  *pScb,
2273
 
                    MV_STORAGE_DEVICE_REGISTERS *registerStruct)
2274
 
{
2275
 
    MV_U8 errorReg = registerStruct->errorRegister;
2276
 
    MV_SCSI_SENSE_DATA SenseData;
2277
 
 
2278
 
    memset(&SenseData, 0, sizeof(MV_SCSI_SENSE_DATA));
2279
 
 
2280
 
    pScb->dataBufferLength = 0;
2281
 
 
2282
 
    /*if (pSrb->SenseInfoBufferLength < 13)
2283
 
    {
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;
2287
 
        return;
2288
 
    }*/
2289
 
    memset(pScb->pSenseBuffer, 0, pScb->senseBufferLength);
2290
 
    /*pScb->ScsiCommandCompletion = ;*/
2291
 
    pScb->ScsiStatus =  MV_SCSI_STATUS_CHECK_CONDITION;
2292
 
 
2293
 
    SenseData.ResponseCode = MV_SCSI_RESPONSE_CODE;
2294
 
//    SenseData.Valid = 0;
2295
 
 
2296
 
    SenseData.AdditionalSenseLength = 12;
2297
 
    SenseData.InformationDesc.type = 0;
2298
 
    SenseData.InformationDesc.AdditionalLength = 0xA;
2299
 
    SenseData.InformationDesc.valid = 1 << 7;
2300
 
 
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);
2309
 
 
2310
 
    /* If the command is synchronize cache */
2311
 
    if ((pScb->ScsiCdb[0] == SCSI_OPCODE_SYNCHRONIZE_CACHE10) || 
2312
 
        (pScb->ScsiCdb[0] == SCSI_OPCODE_SYNCHRONIZE_CACHE16))
2313
 
    {
2314
 
        if (!(registerStruct->errorRegister & ABRT_ERR))
2315
 
        {
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");
2318
 
        }
2319
 
        SenseData.SenseKey = SCSI_SENSE_MEDIUM_ERROR;
2320
 
        _fillSenseInformation(pScb, &SenseData, registerStruct);
2321
 
    }
2322
 
    else if ((pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY10) ||
2323
 
             (pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY6) ||
2324
 
             (pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY16))
2325
 
    {
2326
 
        if (errorReg & (NM_ERR | MC_ERR | MCR_ERR))
2327
 
        {
2328
 
            SenseData.SenseKey = SCSI_SENSE_UNIT_ATTENTION;
2329
 
        }
2330
 
        else if (errorReg & UNC_ERR)
2331
 
        {
2332
 
#if 0
2333
 
            MV_U32  LowLbaAddress = pScb->LowLbaAddress;
2334
 
#endif
2335
 
            SenseData.SenseKey = SCSI_SENSE_MEDIUM_ERROR;
2336
 
#if 0
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);
2344
 
#endif
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]
2353
 
                     );
2354
 
        }
2355
 
        /*else if (errorReg & IDNF_ERR)
2356
 
        {
2357
 
            SenseData.SenseKey = SCSI_SENSE_VOL_OVERFLOW;
2358
 
        }*/
2359
 
        else if ((errorReg & ABRT_ERR) || (errorReg & IDNF_ERR))
2360
 
        {
2361
 
            SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2362
 
            SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2363
 
        }
2364
 
        else
2365
 
        {
2366
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " in mapping ATA error to SCSI error\n");
2367
 
            SenseData.SenseKey = SCSI_SENSE_NO_SENSE;
2368
 
        }
2369
 
    }
2370
 
    else if (pScb->ScsiCdb[0] == SCSI_OPCODE_MODE_SELECT6)
2371
 
    {
2372
 
        /* MODE SELECT is only when enabling / disabling write cache */
2373
 
        if (errorReg & ABRT_ERR)
2374
 
        {
2375
 
            SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2376
 
            SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2377
 
        }
2378
 
        else
2379
 
        {
2380
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " in mapping ATA error to SCSI error\n");
2381
 
            SenseData.SenseKey = SCSI_SENSE_NO_SENSE;
2382
 
        }
2383
 
    }
2384
 
    pScb->senseDataLength = 20;
2385
 
    memcpy(pScb->pSenseBuffer, &SenseData,
2386
 
           (pScb->senseBufferLength > pScb->senseDataLength) ?
2387
 
           pScb->senseDataLength : pScb->senseBufferLength);
2388
 
}
2389
 
 
2390
 
 
2391
 
 
2392
 
static MV_VOID
2393
 
handleUdmaError(MV_SATA_SCSI_CMD_BLOCK  *pScb,
2394
 
                MV_U32 responseFlags,
2395
 
                MV_STORAGE_DEVICE_REGISTERS *registerStruct)
2396
 
{
2397
 
 
2398
 
    mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, "UDMA %s command failed\n", (pScb->udmaType == MV_UDMA_TYPE_READ) ?
2399
 
             "READ" : "WRITE");
2400
 
    if (responseFlags & (MV_BIT3))
2401
 
    {
2402
 
        /* prevent the error_handler from re-send any commands */
2403
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_DISCONNECT;
2404
 
    }
2405
 
    else if (responseFlags & MV_BIT2)           /* ATA error*/
2406
 
    {
2407
 
        MV_SCSI_SENSE_DATA SenseData;
2408
 
 
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;
2419
 
 
2420
 
 
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);
2429
 
 
2430
 
        if ((registerStruct->errorRegister & ICRC_ERR)||
2431
 
            (registerStruct->errorRegister == 0xC))/*error code injected by 88i8030*/
2432
 
        {
2433
 
            SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2434
 
            SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2435
 
        }
2436
 
        else if (registerStruct->errorRegister &
2437
 
                 (NM_ERR | MC_ERR | MCR_ERR))
2438
 
        {
2439
 
            SenseData.SenseKey = SCSI_SENSE_UNIT_ATTENTION;
2440
 
            SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_MEDIA_IN_DEVICE;
2441
 
        }
2442
 
        else if ((registerStruct->errorRegister & UNC_ERR) ||
2443
 
                 (registerStruct->errorRegister == 1))
2444
 
        {
2445
 
#if 0
2446
 
            MV_U32  LowLbaAddress = pScb->LowLbaAddress;
2447
 
 
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);
2453
 
#endif
2454
 
            _fillSenseInformation(pScb, &SenseData, registerStruct);
2455
 
            if (pScb->udmaType == MV_UDMA_TYPE_READ)
2456
 
            {
2457
 
                SenseData.SenseKey = SCSI_SENSE_MEDIUM_ERROR;
2458
 
                SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2459
 
 
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]
2467
 
                     );
2468
 
            }
2469
 
            else
2470
 
            {
2471
 
                SenseData.SenseKey = SCSI_SENSE_DATA_PROTECT;
2472
 
                SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2473
 
            }
2474
 
        }
2475
 
        else if ((registerStruct->errorRegister & IDNF_ERR) &&
2476
 
                 (!(registerStruct->errorRegister & ABRT_ERR)))
2477
 
        {
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;
2481
 
        }
2482
 
        else if (registerStruct->errorRegister & ABRT_ERR)
2483
 
        {
2484
 
            SenseData.SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2485
 
            SenseData.AdditionalSenseCode = SCSI_ADSENSE_NO_SENSE;
2486
 
        }
2487
 
        else
2488
 
        {
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;
2492
 
        }
2493
 
        pScb->senseDataLength = 20;
2494
 
        memcpy(pScb->pSenseBuffer, &SenseData,
2495
 
               (pScb->senseBufferLength > pScb->senseDataLength) ?
2496
 
               pScb->senseDataLength : pScb->senseBufferLength);
2497
 
    }
2498
 
    else if (responseFlags & (MV_BIT0 | MV_BIT1))
2499
 
    {
2500
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_PARITY_ERROR;
2501
 
        pScb->ScsiStatus =  MV_SCSI_STATUS_CHECK_CONDITION;
2502
 
        pScb->senseDataLength = 0;
2503
 
        pScb->dataTransfered = 0;
2504
 
    }
2505
 
    else if (responseFlags & (MV_BIT6|MV_BIT5))
2506
 
    {
2507
 
        if (responseFlags & MV_BIT6)
2508
 
        {
2509
 
            pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_UNDERRUN;
2510
 
        }
2511
 
        else
2512
 
        {
2513
 
            pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_OVERRUN;
2514
 
        }
2515
 
        pScb->dataTransfered = 0;
2516
 
 
2517
 
    }
2518
 
}
2519
 
 
2520
 
/*******************************************************************************
2521
 
* checkQueueCommandResult -
2522
 
*
2523
 
* DESCRIPTION:  set the scsi request completion status and the Scsi Status
2524
 
*       according to the result returned form the mvSataQueueCommand function
2525
 
*
2526
 
* INPUT:
2527
 
*
2528
 
* OUTPUT:
2529
 
*
2530
 
* RETURN:
2531
 
*
2532
 
* COMMENTS:
2533
 
*
2534
 
*
2535
 
*******************************************************************************/
2536
 
 
2537
 
/*static*/ MV_VOID  checkQueueCommandResult(MV_SATA_SCSI_CMD_BLOCK *pScb,
2538
 
                                            MV_QUEUE_COMMAND_RESULT  result)
2539
 
{
2540
 
    switch (result)
2541
 
    {
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;
2545
 
        break;
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;
2549
 
 
2550
 
        break;
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;
2555
 
        break;
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;
2559
 
        break;
2560
 
    default:
2561
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Bad result value (%d) from queue"
2562
 
                 " command\n", result);
2563
 
    }
2564
 
    mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " mvSataQueueUDmaCommand Failed\n");
2565
 
    pScb->dataTransfered = 0;
2566
 
    pScb->senseDataLength = 0;
2567
 
}
2568
 
#ifdef MV_LOGGER
2569
 
static MV_VOID reportScbCompletion(MV_SATA_ADAPTER*    pSataAdapter,
2570
 
                                   MV_SATA_SCSI_CMD_BLOCK *pScb)
2571
 
{
2572
 
    if (pScb->ScsiCommandCompletion != MV_SCSI_COMPLETION_SUCCESS)
2573
 
    {
2574
 
        MV_U8   buffer[100];
2575
 
        MV_U32  index = 0;
2576
 
        MV_BOOLEAN      printInfo = MV_TRUE;
2577
 
 
2578
 
        switch (pScb->ScsiCommandCompletion)
2579
 
        {
2580
 
        case MV_SCSI_COMPLETION_BAD_SCSI_COMMAND:
2581
 
            SAL_SPRINTF(buffer, "%s", "MV_SCSI_COMPLETION_BAD_SCSI_COMMAND");
2582
 
            break;
2583
 
        case MV_SCSI_COMPLETION_ATA_FAILED:
2584
 
            SAL_SPRINTF(buffer, "%s", "MV_SCSI_COMPLETION_ATA_FAILED");
2585
 
            break;
2586
 
        case MV_SCSI_COMPLETION_PARITY_ERROR:
2587
 
            SAL_SPRINTF(buffer, "%s", "MV_SCSI_COMPLETION_PARITY");
2588
 
            break;
2589
 
        default:
2590
 
            printInfo = MV_FALSE;
2591
 
        }
2592
 
 
2593
 
        if (printInfo == MV_TRUE)
2594
 
        {
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);
2598
 
        }
2599
 
        else
2600
 
        {
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);
2604
 
        }
2605
 
 
2606
 
        index = SAL_SPRINTF(buffer, "%s", "CDB:");
2607
 
        {
2608
 
            MV_U32  i;
2609
 
            for (i =0 ; i < pScb->ScsiCdbLength; i++)
2610
 
            {
2611
 
                index += SAL_SPRINTF(&buffer[index], "%x ",
2612
 
                                     pScb->ScsiCdb[i]);
2613
 
            }
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)
2619
 
            {
2620
 
                if ((pScb->pSenseBuffer != NULL) && (pScb->senseBufferLength > 0))
2621
 
                {
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++)
2626
 
                    {
2627
 
                        index += SAL_SPRINTF(buffer + index, "%x ",
2628
 
                                             pScb->pSenseBuffer[i]);
2629
 
                    }
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);
2634
 
                }
2635
 
            }
2636
 
        }
2637
 
        if (pScb->ScsiCommandCompletion == MV_SCSI_COMPLETION_ATA_FAILED)
2638
 
        {
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);
2647
 
        }
2648
 
    }
2649
 
    else
2650
 
    {
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);
2654
 
    }
2655
 
    
2656
 
}
2657
 
#endif
2658
 
static MV_VOID  mvScsiAtaSendSplittedVerifyCommand(IN MV_SATA_SCSI_CMD_BLOCK  *pScb)
2659
 
{
2660
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
2661
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
2662
 
#else
2663
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
2664
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
2665
 
#endif
2666
 
    MV_QUEUE_COMMAND_RESULT result;
2667
 
    MV_U8                  sectors = 0;/*256 sectors*/
2668
 
 
2669
 
    pScb->sequenceNumber++;
2670
 
    if (pScb->sequenceNumber == 1)/*for the first command*/
2671
 
    {
2672
 
        if (pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY6)
2673
 
        {
2674
 
            sectors = pScb->ScsiCdb[4];
2675
 
        }
2676
 
        else if (pScb->ScsiCdb[0] == SCSI_OPCODE_VERIFY10)
2677
 
        {
2678
 
            sectors = pScb->ScsiCdb[8];
2679
 
        }
2680
 
        else 
2681
 
        {
2682
 
            sectors = pScb->ScsiCdb[13];
2683
 
        }
2684
 
    }
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;
2692
 
 
2693
 
    pCommandInfo->commandParams.NoneUdmaCommand.features = 0;
2694
 
    pCommandInfo->commandParams.NoneUdmaCommand.isEXT = MV_FALSE;
2695
 
    pCommandInfo->commandParams.NoneUdmaCommand.protocolType = MV_NON_UDMA_PROTOCOL_NON_DATA;
2696
 
 
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));
2703
 
 
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,
2707
 
             pScb->target,
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,
2715
 
                                    pScb->bus), pScb);
2716
 
 
2717
 
    if (sectors)
2718
 
    {
2719
 
        pScb->LowLbaAddress += sectors;
2720
 
    }
2721
 
    else
2722
 
    {
2723
 
        pScb->LowLbaAddress += 0x100;
2724
 
    }
2725
 
 
2726
 
    result = mvSataQueueCommand(pScb->pSalAdapterExtension->pSataAdapter,
2727
 
                                pScb->bus, pCommandInfo);
2728
 
 
2729
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
2730
 
    {
2731
 
        checkQueueCommandResult(pScb, result);
2732
 
#ifdef MV_LOGGER
2733
 
        reportScbCompletion(pScb->pSalAdapterExtension->pSataAdapter, pScb);
2734
 
#endif
2735
 
 
2736
 
        return;
2737
 
    }
2738
 
 
2739
 
    /* update stats*/
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;
2744
 
 
2745
 
}
2746
 
static MV_VOID  mvScsiAtaSendReadLookAhead(IN MV_SATA_ADAPTER *pSataAdapter,
2747
 
                                           IN MV_SATA_SCSI_CMD_BLOCK  *pScb)
2748
 
{
2749
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
2750
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
2751
 
#else
2752
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
2753
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
2754
 
#endif
2755
 
    MV_QUEUE_COMMAND_RESULT result;
2756
 
 
2757
 
    if (pScb->LowLbaAddress == 0) /* Disable Look Ahead*/
2758
 
    {
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;
2761
 
    }
2762
 
    else
2763
 
    {
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;
2766
 
    }
2767
 
 
2768
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
2769
 
 
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;
2777
 
 
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);
2785
 
 
2786
 
    mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Sending SET FEATURES command: features %d\n",
2787
 
             pCommandInfo->commandParams.NoneUdmaCommand.features);
2788
 
 
2789
 
    pScb->sequenceNumber++;
2790
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
2791
 
 
2792
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
2793
 
    {
2794
 
        checkQueueCommandResult(pScb, result);
2795
 
#ifdef MV_LOGGER
2796
 
        reportScbCompletion(pSataAdapter, pScb);
2797
 
#endif
2798
 
        pScb->completionCallBack(pSataAdapter, pScb);
2799
 
        return;
2800
 
    }
2801
 
}
2802
 
 
2803
 
MV_VOID     mvSataScsiInitAdapterExt(MV_SAL_ADAPTER_EXTENSION *pAdapterExt,
2804
 
                                     MV_SATA_ADAPTER* pSataAdapter)
2805
 
{
2806
 
    MV_U8   channelIndex;
2807
 
    MV_U8   PMPort;
2808
 
    pAdapterExt->pSataAdapter = pSataAdapter;
2809
 
    pAdapterExt->pHead = NULL;
2810
 
    pAdapterExt->UAMask = 0xFF;
2811
 
    for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM; channelIndex++)
2812
 
    {
2813
 
        for (PMPort = 0; PMPort < MV_SATA_PM_MAX_PORTS; PMPort++)
2814
 
        {
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];
2820
 
        }
2821
 
    }
2822
 
}
2823
 
#ifdef MV_SUPPORT_ATAPI
2824
 
MV_SCSI_COMMAND_STATUS_TYPE mvScsiAtaSendATAPICommand(MV_SATA_ADAPTER *pSataAdapter, 
2825
 
                                                        MV_SATA_SCSI_CMD_BLOCK  *pScb)
2826
 
{
2827
 
#ifdef MV_SATA_STORE_COMMANDS_INFO_ON_IAL_STACK
2828
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = pScb->pCommandInfo;
2829
 
#else
2830
 
    MV_QUEUE_COMMAND_INFO   commandInfo;
2831
 
    MV_QUEUE_COMMAND_INFO   *pCommandInfo = &commandInfo;
2832
 
#endif
2833
 
    MV_QUEUE_COMMAND_RESULT result;
2834
 
 
2835
 
 
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,
2840
 
            pScb->pDataBuffer, 
2841
 
                pScb->dataBufferLength, pScb->ScsiCdb, pScb->ScsiCdbLength);
2842
 
 
2843
 
    pScb->commandType = MV_QUEUED_COMMAND_TYPE_PACKET;
2844
 
 
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;
2857
 
    
2858
 
    if((pScb->dataDirection == MV_SCSI_COMMAND_DATA_DIRECTION_IN) && (pScb->pDataBuffer == NULL))
2859
 
    {
2860
 
        pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_DMA;
2861
 
    }
2862
 
    else if((pScb->dataDirection == MV_SCSI_COMMAND_DATA_DIRECTION_OUT) && (pScb->pDataBuffer == NULL))
2863
 
    {
2864
 
        pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_DMA;
2865
 
        pCommandInfo->commandParams.packetCommand.flags = MV_BIT0;
2866
 
    }
2867
 
    else
2868
 
    {
2869
 
        switch(pScb->dataDirection)
2870
 
        {
2871
 
            case MV_SCSI_COMMAND_DATA_DIRECTION_IN:
2872
 
                pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_PIO_DATA_IN;
2873
 
                break;
2874
 
            case MV_SCSI_COMMAND_DATA_DIRECTION_OUT:
2875
 
                pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_PIO_DATA_OUT;
2876
 
                break;
2877
 
        default:
2878
 
                pCommandInfo->commandParams.packetCommand.protocolType = MV_NON_UDMA_PROTOCOL_PACKET_PIO_NON_DATA;
2879
 
        }
2880
 
    }
2881
 
    pScb->sequenceNumber = 0;
2882
 
    result = mvSataQueueCommand(pSataAdapter, pScb->bus, pCommandInfo);
2883
 
 
2884
 
    if (result != MV_QUEUE_COMMAND_RESULT_OK)
2885
 
    {
2886
 
        checkQueueCommandResult(pScb, result);
2887
 
#ifdef MV_LOGGER
2888
 
        reportScbCompletion(pSataAdapter, pScb);
2889
 
#endif
2890
 
        pScb->completionCallBack(pSataAdapter, pScb);
2891
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
2892
 
    }
2893
 
    return MV_SCSI_COMMAND_STATUS_QUEUED;
2894
 
}
2895
 
#endif
2896
 
MV_SCSI_COMMAND_STATUS_TYPE mvSataExecuteScsiCommand(MV_SATA_SCSI_CMD_BLOCK  *pScb)
2897
 
{
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;
2902
 
 
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);
2907
 
 
2908
 
#ifdef MV_LOGGER
2909
 
 
2910
 
    {
2911
 
        MV_U8 buffer[50];
2912
 
        MV_U32  i, index;
2913
 
 
2914
 
        index = SAL_SPRINTF(buffer, "%s", "CDB:");
2915
 
        for (i =0 ; i < pScb->ScsiCdbLength; i++)
2916
 
        {
2917
 
            index += SAL_SPRINTF(&buffer[index], "%x ",
2918
 
                                 pScb->ScsiCdb[i]);
2919
 
        }
2920
 
        buffer[index] = '\n';
2921
 
        buffer[index+1] = 0;
2922
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, buffer);
2923
 
    }
2924
 
#endif
2925
 
    pScb->dataTransfered = 0;
2926
 
    pScb->senseDataLength = 0;
2927
 
    pScb->ScsiStatus = 0;
2928
 
    if (pScb->bus >= pSataAdapter->numberOfChannels)
2929
 
    {
2930
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_INVALID_BUS;
2931
 
        pScb->dataTransfered = 0;
2932
 
#ifdef MV_LOGGER
2933
 
        reportScbCompletion(pSataAdapter, pScb);
2934
 
#endif
2935
 
        pScb->completionCallBack(pSataAdapter, pScb);
2936
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
2937
 
    }
2938
 
 
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)))
2942
 
    {
2943
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_NO_DEVICE;
2944
 
        pScb->dataTransfered = 0;
2945
 
#ifdef MV_LOGGER
2946
 
        reportScbCompletion(pSataAdapter, pScb);
2947
 
#endif
2948
 
        pScb->completionCallBack(pSataAdapter, pScb);
2949
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
2950
 
    }
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)
2954
 
    {
2955
 
        return mvScsiAtaSendATAPICommand(pSataAdapter, pScb);
2956
 
    }
2957
 
#endif
2958
 
    switch (cmd[0])
2959
 
    {
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:
2965
 
 
2966
 
#ifdef MV_SATA_SUPPORT_READ_WRITE_LONG
2967
 
    case SCSI_OPCODE_WRITE_LONG10:
2968
 
    case SCSI_OPCODE_READ_LONG10:
2969
 
#endif
2970
 
        if (cmd[1] & MV_BIT0) /* if related address*/
2971
 
        {
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);
2976
 
 
2977
 
        }
2978
 
    }
2979
 
    if (cmd[pScb->ScsiCdbLength - 1] != 0) /*if CONTROL is set*/
2980
 
    {
2981
 
        MV_BOOLEAN commandSupported = MV_TRUE;
2982
 
 
2983
 
        switch (cmd[0])
2984
 
        {
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:
3008
 
#endif
3009
 
 
3010
 
            break;
3011
 
        default:
3012
 
            commandSupported = MV_FALSE;
3013
 
        }
3014
 
        if (commandSupported == MV_TRUE)
3015
 
        {
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);
3020
 
        }
3021
 
    }
3022
 
 
3023
 
    if (pDriveData->UAConditionPending == MV_TRUE)
3024
 
    {
3025
 
        if (((cmd[0] != SCSI_OPCODE_INQUIRY) &&
3026
 
             (cmd[0] != SCSI_OPCODE_REPORT_LUNS) &&
3027
 
             (cmd[0] != SCSI_OPCODE_REQUEST_SENSE6)) || (invalidCDB == MV_TRUE))
3028
 
        {
3029
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " Unit Attention condition is pending.\n");
3030
 
 
3031
 
            if (pDriveData->UAEvents & MV_BIT0)
3032
 
            {
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
3036
 
                             , 2);
3037
 
                pDriveData->UAEvents &= ~MV_BIT0;
3038
 
            }
3039
 
            else if (pDriveData->UAEvents & MV_BIT1)
3040
 
            {
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;
3046
 
            }
3047
 
 
3048
 
            pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
3049
 
            pScb->dataTransfered = 0;
3050
 
#ifdef MV_LOGGER
3051
 
            reportScbCompletion(pSataAdapter, pScb);
3052
 
#endif
3053
 
            pScb->completionCallBack(pSataAdapter, pScb);
3054
 
            if (pDriveData->UAEvents == 0)
3055
 
            {
3056
 
                pDriveData->UAConditionPending = MV_FALSE;
3057
 
            }
3058
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
3059
 
        }
3060
 
    }
3061
 
    if (invalidCDB == MV_TRUE)
3062
 
    {
3063
 
        setSenseData(pScb, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_INVALID_CDB,
3064
 
                     0);
3065
 
        pScb->ScsiStatus = MV_SCSI_STATUS_CHECK_CONDITION;
3066
 
        pScb->dataTransfered = 0;
3067
 
        pScb->ScsiCommandCompletion = MV_SCSI_COMPLETION_BAD_SCSI_COMMAND;
3068
 
#ifdef MV_LOGGER
3069
 
        reportScbCompletion(pSataAdapter, pScb);
3070
 
#endif
3071
 
        pScb->completionCallBack(pSataAdapter, pScb);
3072
 
        return MV_SCSI_COMMAND_STATUS_COMPLETED;
3073
 
    }
3074
 
 
3075
 
    switch (cmd[0])
3076
 
    {
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);
3117
 
#endif
3118
 
 
3119
 
    default:
3120
 
        {
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;
3127
 
#ifdef MV_LOGGER
3128
 
            reportScbCompletion(pSataAdapter, pScb);
3129
 
#endif
3130
 
            pScb->completionCallBack(pSataAdapter, pScb);
3131
 
            return MV_SCSI_COMMAND_STATUS_COMPLETED;
3132
 
 
3133
 
        }
3134
 
    }
3135
 
 
3136
 
    return MV_SCSI_COMMAND_STATUS_FAILED;
3137
 
}
3138
 
 
3139
 
MV_VOID mvSataScsiPostIntService(MV_SAL_ADAPTER_EXTENSION *pAdapterExt)
3140
 
{
3141
 
    MV_SATA_SCSI_CMD_BLOCK  *pScb = pAdapterExt->pHead;
3142
 
    while (pScb)
3143
 
    {
3144
 
        mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, "Post Interrupt Service: pScb %p command %x\n", pScb,
3145
 
                 pScb->ScsiCdb[0]);
3146
 
        switch (pScb->ScsiCdb[0])
3147
 
        {
3148
 
        case    SCSI_OPCODE_VERIFY16:
3149
 
        case    SCSI_OPCODE_VERIFY10:
3150
 
        case    SCSI_OPCODE_VERIFY6:
3151
 
            mvScsiAtaSendSplittedVerifyCommand(pScb);
3152
 
            break;
3153
 
        case    SCSI_OPCODE_MODE_SELECT6:
3154
 
            mvScsiAtaSendReadLookAhead(pAdapterExt->pSataAdapter,
3155
 
                                       pScb);
3156
 
            break;
3157
 
        default:
3158
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG_ERROR, " Post Interrupt Service called for bad scsi"
3159
 
                     " command(%x)\n", pScb->ScsiCdb[0]);
3160
 
        }
3161
 
        pScb = pScb->pNext;
3162
 
    }
3163
 
    pAdapterExt->pHead = NULL;
3164
 
    return;
3165
 
}
3166
 
 
3167
 
MV_VOID     mvSataScsiSetDriveReady(MV_SAL_ADAPTER_EXTENSION *pAdapterExt,
3168
 
                                    MV_U8   channelIndex, MV_U8 PMPort,
3169
 
                                    MV_BOOLEAN  isReady)
3170
 
{
3171
 
    if (isReady == MV_TRUE)
3172
 
    {
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;
3179
 
    }
3180
 
    else
3181
 
    {
3182
 
        if (PMPort == 0xFF)
3183
 
        {
3184
 
            MV_U8   i;
3185
 
 
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++)
3189
 
            {
3190
 
                mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: SATA Drive is Removed.\n",
3191
 
                         pAdapterExt->pSataAdapter->adapterId, channelIndex,
3192
 
                         i);
3193
 
                pAdapterExt->ataDriveData[channelIndex][i].driveReady = MV_FALSE;
3194
 
            }
3195
 
 
3196
 
        }
3197
 
        else
3198
 
        {
3199
 
            mvLogMsg(MV_SAL_LOG_ID, MV_DEBUG, " %d %d %d: SATA Drive is Removed.\n",
3200
 
                     pAdapterExt->pSataAdapter->adapterId, channelIndex,
3201
 
                     PMPort);
3202
 
            pAdapterExt->ataDriveData[channelIndex][PMPort].driveReady = MV_FALSE;
3203
 
 
3204
 
        }
3205
 
    }
3206
 
}
3207
 
 
3208
 
 
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)
3212
 
{
3213
 
    pAdapterExt->ataDriveData[channelIndex][PMPort].UAConditionPending = MV_TRUE;
3214
 
    /* bit 0 - reset*/
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);
3221
 
}
3222