Ticket #12357: ahci-rework-v5.diff

File ahci-rework-v5.diff, 16.5 KB (added by kallisti5, 9 years ago)
  • src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h

    diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h
    index b9c8c03..1e942cb 100644
    a b  
    55#ifndef _AHCI_DEFS_H
    66#define _AHCI_DEFS_H
    77
     8#include <ata_types.h>
    89#include <bus/PCI.h>
    910#include <bus/SCSI.h>
    1011#include <PCI_x86.h>
    enum {  
    9798#define IPM_TRANSITIONS_TO_PARTIAL_DISABLED 0x1
    9899#define IPM_TRANSITIONS_TO_SLUMBER_DISABLED 0x2
    99100
     101// Device signatures
     102#define SATA_SIG_ATA            0x00000101 // SATA drive
     103#define SATA_SIG_ATAPI          0xEB140101 // ATAPI drive
     104#define SATA_SIG_SEMB           0xC33C0101 // Enclosure management bridge
     105#define SATA_SIG_PM             0x96690101 // Port multiplier
    100106
    101107typedef struct {
    102108    uint32      clb;            // Command List Base Address
    enum {  
    130136    PORT_CMD_ATAPI  = (1 << 24),    // Device is ATAPI
    131137    PORT_CMD_CR     = (1 << 15),    // Command List Running (DMA active)
    132138    PORT_CMD_FR     = (1 << 14),    // FIS Receive Running
    133     PORT_CMD_FER    = (1 << 4),     // FIS Receive Enable
     139    PORT_CMD_FRE    = (1 << 4),     // FIS Receive Enable
    134140    PORT_CMD_CLO    = (1 << 3),     // Command List Override
    135141    PORT_CMD_POD    = (1 << 2),     // Power On Device
    136142    PORT_CMD_SUD    = (1 << 1),     // Spin-up Device
    enum {  
    167173                            | PORT_INT_DS | PORT_INT_PS | PORT_INT_DHR)
    168174
    169175enum {
    170     ATA_BSY         = 0x80,
    171     ATA_DF          = 0x20,
    172     ATA_DRQ         = 0x08,
    173     ATA_ERR         = 0x01,
    174 };
    175 
    176 
    177 enum {
    178176    PORT_FBS_DWE_SHIFT      = 16,   // Device With Error
    179177    PORT_FBS_DWE_MASK       = 0xf,
    180178    PORT_FBS_ADO_SHIFT      = 12,   // Active Device Optimization
  • src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp

    diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
    index 1f8b149..a2ef29a 100644
    a b AHCIPort::AHCIPort(AHCIController* controller, int index)  
    5454    fSectorCount(0),
    5555    fIsATAPI(false),
    5656    fTestUnitReadyActive(false),
    57     fResetPort(false),
     57    fSoftReset(false),
    5858    fError(false),
    5959    fTrimSupported(false)
    6060{
    AHCIPort::Init1()  
    120120    fRegs->is = fRegs->is;
    121121
    122122    // clear error bits
    123     fRegs->serr = fRegs->serr;
     123    _ClearErrorRegister();
    124124
    125125    // power up device
    126126    fRegs->cmd |= PORT_CMD_POD;
    AHCIPort::Init1()  
    131131    // activate link
    132132    fRegs->cmd = (fRegs->cmd & ~PORT_CMD_ICC_MASK) | PORT_CMD_ICC_ACTIVE;
    133133
    134     // enable FIS receive
    135     fRegs->cmd |= PORT_CMD_FER;
     134    // enable FIS receive (enabled when fb set, only to be disabled when unset)
     135    fRegs->cmd |= PORT_CMD_FRE;
    136136
    137137    FlushPostedWrites();
    138138
    AHCIPort::Init2()  
    146146{
    147147    TRACE("AHCIPort::Init2 port %d\n", fIndex);
    148148
    149     // start DMA engine
    150     fRegs->cmd |= PORT_CMD_ST;
     149    // enable port
     150    Enable();
    151151
    152152    // enable interrupts
    153153    fRegs->ie = PORT_INT_MASK;
    154154
    155155    FlushPostedWrites();
    156156
    157     ResetPort(true);
     157    // reset port and probe info
     158    SoftReset();
    158159
    159160    TRACE("ie   0x%08" B_PRIx32 "\n", fRegs->ie);
    160161    TRACE("is   0x%08" B_PRIx32 "\n", fRegs->is);
    AHCIPort::Init2()  
    172173
    173174    fDevicePresent = (fRegs->ssts & 0xf) == 0x3;
    174175
     176    TRACE("%s: port %d, device %s\n", __func__, fIndex,
     177        fDevicePresent ? "present" : "absent");
     178
    175179    return B_OK;
    176180}
    177181
    AHCIPort::Uninit()  
    181185{
    182186    TRACE("AHCIPort::Uninit port %d\n", fIndex);
    183187
    184     // disable FIS receive
    185     fRegs->cmd &= ~PORT_CMD_FER;
     188    // Spec v1.3.1, §10.3.2 - Shut down port before unsetting FRE
    186189
    187     // wait for receive completion, up to 500ms
    188     if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK) {
    189         TRACE("AHCIPort::Uninit port %d error FIS rx still running\n", fIndex);
     190    // shutdown the port
     191    if (!Disable()) {
     192        ERROR("%s: port %d error, unable to shutdown before FRE clear!\n",
     193            __func__, fIndex);
     194        return;
    190195    }
    191196
    192     // stop DMA engine
    193     fRegs->cmd &= ~PORT_CMD_ST;
    194 
    195     // wait for DMA completion
    196     if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
    197         TRACE("AHCIPort::Uninit port %d error DMA engine still running\n",
    198             fIndex);
    199     }
     197    // Clear FRE and wait for completion
     198    fRegs->cmd &= ~PORT_CMD_FRE;
     199    if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK)
     200        ERROR("%s: port %d error FIS rx still running\n", __func__, fIndex);
    200201
    201202    // disable interrupts
    202203    fRegs->ie = 0;
    void  
    218219AHCIPort::ResetDevice()
    219220{
    220221    // perform a hard reset
    221     if (!_HardReset())
     222    if (PortReset() != B_OK) {
     223        ERROR("%s: port %d unable to hard reset device\n", __func__, fIndex);
    222224        return;
     225    }
    223226
    224227    if (wait_until_set(&fRegs->ssts, 0x1, 100000) < B_OK)
    225228        TRACE("AHCIPort::ResetDevice port %d no device detected\n", fIndex);
    AHCIPort::ResetDevice()  
    238241
    239242
    240243status_t
    241 AHCIPort::ResetPort(bool forceDeviceReset)
     244AHCIPort::SoftReset()
    242245{
    243     if (!fTestUnitReadyActive)
    244         TRACE("AHCIPort::ResetPort port %d\n", fIndex);
     246    TRACE("AHCIPort::SoftReset port %d\n", fIndex);
    245247
    246     // stop DMA engine
    247     fRegs->cmd &= ~PORT_CMD_ST;
    248     FlushPostedWrites();
     248    // Spec v1.3.1, §10.4.1 Software Reset
     249    // A single device on one port is reset, HBA and phy comm remain intact.
    249250
    250     if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
    251         TRACE("AHCIPort::ResetPort port %d error DMA engine doesn't stop\n",
    252             fIndex);
     251    // stop port, flush transactions
     252    if (!Disable()) {
     253        // If the port doesn't power off, move on to a stronger reset.
     254        ERROR("%s: port %d soft reset failed. Moving on to port reset.\n",
     255            __func__, fIndex);
     256        return PortReset();
    253257    }
    254258
    255     bool deviceBusy = fRegs->tfd & (ATA_BSY | ATA_DRQ);
     259    // TODO: If FBS Enable, clear PxFBS.EN prior to issuing sw reset
    256260
    257     if (!fTestUnitReadyActive) {
    258         TRACE("AHCIPort::ResetPort port %d, deviceBusy %d, "
    259             "forceDeviceReset %d\n", fIndex, deviceBusy, forceDeviceReset);
     261    if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
     262        1000000) < B_OK) {
     263        ERROR("%s: port %d still busy. Moving on to port reset.\n",
     264            __func__, fIndex);
     265        return PortReset();
    260266    }
    261267
    262     if (deviceBusy || forceDeviceReset)
    263         ResetDevice();
    264 
    265     // start DMA engine
    266     fRegs->cmd |= PORT_CMD_ST;
     268    cpu_status cpu = disable_interrupts();
     269    acquire_spinlock(&fSpinlock);
     270    // ATA Reset + clear busy
     271    fCommandList->r = 1;
     272    fCommandList->c = 1;
     273    // Issue Command
     274    fRegs->ci = 1;
    267275    FlushPostedWrites();
     276    release_spinlock(&fSpinlock);
     277    restore_interrupts(cpu);
     278
     279    if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
     280        1000000) < B_OK) {
     281        ERROR("%s: port %d software reset failed. Doing port reset...\n",
     282            __func__, fIndex);
     283        FinishTransfer();
     284        return PortReset();
     285    }
     286
     287    FinishTransfer();
     288
     289    // start port
     290    Enable();
    268291
    269292    return PostReset();
    270293}
    271294
    272295
    273296status_t
    274 AHCIPort::PostReset()
     297AHCIPort::PortReset()
    275298{
    276     if (!fTestUnitReadyActive)
    277         TRACE("AHCIPort::PostReset port %d\n", fIndex);
     299    TRACE("AHCIPort::PortReset port %d\n", fIndex);
    278300
    279     if ((fRegs->ssts & 0xf) != 0x3 || (fRegs->tfd & 0xff) == 0x7f) {
    280         TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
    281         return B_OK;
     301    // Spec v1.3.1, §10.4.2 Port Reset
     302    // Physical comm between HBA and port disabled. More Intrusive
     303    if (!Disable()) {
     304        ERROR("%s: port %d unable to reset!\n", __func__, fIndex);
     305        return B_ERROR;
    282306    }
    283307
     308    fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
     309        | DET_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
     310    FlushPostedWrites();
     311    spin(1100);
     312        // You must wait 1ms at minimum
     313    fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
     314        | DET_NO_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
     315    FlushPostedWrites();
     316
     317    if (wait_until_set(&fRegs->ssts, 0x3, 500000) < B_OK) {
     318        TRACE("AHCIPort::PortReset port %d device present but no phy "
     319            "communication\n", fIndex);
     320        return B_ERROR;
     321    }
     322
     323    //if ((fRegs->tfd & 0xff) == 0x7f) {
     324    //  TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
     325    //  return B_OK;
     326    //}
     327
     328    Enable();
     329
     330    return PostReset();
     331}
     332
     333
     334status_t
     335AHCIPort::PostReset()
     336{
    284337    if ((fRegs->tfd & 0xff) == 0xff)
    285338        snooze(200000);
    286339
    AHCIPort::PostReset()  
    290343        return B_ERROR;
    291344    }
    292345
    293     wait_until_clear(&fRegs->tfd, ATA_BSY, 31000000);
    294 
    295     fIsATAPI = fRegs->sig == 0xeb140101;
     346    wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY, 31000000);
    296347
     348    fIsATAPI = fRegs->sig == SATA_SIG_ATAPI;
    297349    if (fIsATAPI)
    298350        fRegs->cmd |= PORT_CMD_ATAPI;
    299351    else
    AHCIPort::PostReset()  
    302354
    303355    if (!fTestUnitReadyActive) {
    304356        TRACE("device signature 0x%08" B_PRIx32 " (%s)\n", fRegs->sig,
    305             fRegs->sig == 0xeb140101 ? "ATAPI" : fRegs->sig == 0x00000101
     357            fRegs->sig == SATA_SIG_ATAPI ? "ATAPI" : fRegs->sig == SATA_SIG_ATA
    306358                ? "ATA" : "unknown");
    307359    }
    308360
     361    _ClearErrorRegister();
     362
    309363    return B_OK;
    310364}
    311365
    AHCIPort::InterruptErrorHandler(uint32 is)  
    374428    }
    375429
    376430    // read and clear SError
    377     uint32 serr = fRegs->serr;
    378     fRegs->serr = serr;
     431    _ClearErrorRegister();
    379432
    380433    if (is & PORT_INT_TFE) {
    381434        if (!fTestUnitReadyActive)
    382435            TRACE("Task File Error\n");
    383436
    384         fResetPort = true;
     437        fSoftReset = true;
    385438        fError = true;
    386439    }
    387440    if (is & PORT_INT_HBF) {
    388441        TRACE("Host Bus Fatal Error\n");
    389         fResetPort = true;
     442        fSoftReset = true;
    390443        fError = true;
    391444    }
    392445    if (is & PORT_INT_HBD) {
    393446        TRACE("Host Bus Data Error\n");
    394         fResetPort = true;
     447        fSoftReset = true;
    395448        fError = true;
    396449    }
    397450    if (is & PORT_INT_IF) {
    398451        TRACE("Interface Fatal Error\n");
    399         fResetPort = true;
     452        fSoftReset = true;
    400453        fError = true;
    401454    }
    402455    if (is & PORT_INT_INF) {
    AHCIPort::InterruptErrorHandler(uint32 is)  
    404457    }
    405458    if (is & PORT_INT_OF) {
    406459        TRACE("Overflow\n");
    407         fResetPort = true;
     460        fSoftReset = true;
    408461        fError = true;
    409462    }
    410463    if (is & PORT_INT_IPM) {
    AHCIPort::InterruptErrorHandler(uint32 is)  
    412465    }
    413466    if (is & PORT_INT_PRC) {
    414467        TRACE("PhyReady Change\n");
    415 //      fResetPort = true;
     468//      fSoftReset = true;
    416469    }
    417470    if (is & PORT_INT_PC) {
    418471        TRACE("Port Connect Change\n");
    419472        // TODO: check if the COMINIT is actually unsolicited!
    420473        // Spec v1.3, §6.2.2.3 Recovery of Unsolicited COMINIT
     474        // Spec v1.3.1, §7.4 Interaction of command list and port change status
     475        // TODO: Issue COMRESET ?
     476        //PortReset();
     477        //HBAReset(); ???
    421478
    422         // perform a hard reset
    423 //      if (!_HardReset())
    424 //          return;
    425 //
    426 //      // clear error bits to clear PxSERR.DIAG.X
    427 //      _ClearErrorRegister();
     479        // clear error bits to clear PxSERR.DIAG.X
     480        _ClearErrorRegister();
    428481    }
    429482    if (is & PORT_INT_UF) {
    430483        TRACE("Unknown FIS\n");
    431         fResetPort = true;
     484        fSoftReset = true;
    432485    }
    433486
    434487    if (fError) {
    AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,  
    453506    status_t status = get_memory_map_etc(B_CURRENT_TEAM, data, dataSize,
    454507        entries, &entriesUsed);
    455508    if (status != B_OK) {
    456         TRACE("AHCIPort::FillPrdTable get_memory_map() failed: %s\n",
    457             strerror(status));
     509        TRACE("%s: get_memory_map() failed: %s\n", __func__, strerror(status));
    458510        return B_ERROR;
    459511    }
    460512
    AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,  
    501553        sgCount--;
    502554    }
    503555    if (*prdCount == 0) {
    504         TRACE("AHCIPort::FillPrdTable: count is 0\n");
     556        TRACE("%s: count is 0\n", __func__);
    505557        return B_ERROR;
    506558    }
    507559    if (dataSize > 0) {
    AHCIPort::ScsiInquiry(scsi_ccb* request)  
    664716    ExecuteSataRequest(&sreq);
    665717    sreq.WaitForCompletion();
    666718
    667     if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
     719    if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
    668720        ERROR("identify device failed\n");
    669721        request->subsys_status = SCSI_REQ_CMP_ERR;
    670722        gSCSI->finished(request, 1);
    for (uint32 i = 0; i < lbaRangeCount; i++) {  
    10061058        ExecuteSataRequest(&sreq);
    10071059        sreq.WaitForCompletion();
    10081060
    1009         if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
     1061        if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
    10101062            TRACE("trim failed (%" B_PRIu32 " ranges)!\n", lbaRangeCount);
    10111063            request->subsys_status = SCSI_REQ_CMP_ERR;
    10121064        } else
    AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)  
    10581110    fCommandList->prdtl = prdEntrys;
    10591111    fCommandList->prdbc = 0;
    10601112
    1061     if (wait_until_clear(&fRegs->tfd, ATA_BSY | ATA_DRQ, 1000000) < B_OK) {
     1113    if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
     1114            1000000) < B_OK) {
    10621115        TRACE("ExecuteAtaRequest port %d: device is busy\n", fIndex);
    1063         ResetPort();
     1116        SoftReset();
    10641117        FinishTransfer();
    10651118        request->Abort();
    10661119        return;
    AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)  
    10951148    TRACE("tfd  0x%08" B_PRIx32 "\n", fRegs->tfd);
    10961149*/
    10971150
    1098     if (fResetPort || status == B_TIMED_OUT) {
    1099         fResetPort = false;
    1100         ResetPort();
     1151    if (fSoftReset || status == B_TIMED_OUT) {
     1152        fSoftReset = false;
     1153        SoftReset();
    11011154    }
    11021155
    11031156    size_t bytesTransfered = fCommandList->prdbc;
    AHCIPort::ScsiGetRestrictions(bool* isATAPI, bool* noAutoSense,  
    13231376
    13241377
    13251378bool
    1326 AHCIPort::_HardReset()
     1379AHCIPort::Enable()
    13271380{
     1381    // Spec v1.3.1, §10.3.1 Start (PxCMD.ST)
     1382    TRACE("%s: port %d\n", __func__, fIndex);
    13281383    if ((fRegs->cmd & PORT_CMD_ST) != 0) {
    1329         // We shouldn't perform a reset, but at least document it
    1330         TRACE("AHCIPort::_HardReset() PORT_CMD_ST set, behaviour undefined\n");
     1384        TRACE("%s: Starting port already running!\n", __func__);
    13311385        return false;
    13321386    }
    13331387
    1334     fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
    1335         | DET_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
    1336     FlushPostedWrites();
    1337     spin(1100);
    1338         // You must wait 1ms at minimum
    1339     fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
    1340         | DET_NO_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
     1388    if ((fRegs->cmd & PORT_CMD_FRE) == 0) {
     1389        TRACE("%s: Unable to start port without FRE enabled!\n", __func__);
     1390        return false;
     1391    }
     1392
     1393    // Clear DMA engine and wait for completion
     1394    if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
     1395        TRACE("%s: port %d error DMA engine still running\n", __func__,
     1396            fIndex);
     1397        return false;
     1398    }
     1399    // Start port
     1400    fRegs->cmd |= PORT_CMD_ST;
    13411401    FlushPostedWrites();
     1402    return true;
     1403}
     1404
     1405
     1406bool
     1407AHCIPort::Disable()
     1408{
     1409    TRACE("%s: port %d\n", __func__, fIndex);
     1410
     1411    if ((fRegs->cmd & PORT_CMD_ST) == 0) {
     1412        // Port already disabled, carry on.
     1413        TRACE("%s: port %d attempting to disable stopped port.\n",
     1414            __func__, fIndex);
     1415    } else {
     1416        // Disable port
     1417        fRegs->cmd &= ~PORT_CMD_ST;
     1418        FlushPostedWrites();
     1419    }
     1420
     1421    // Spec v1.3.1, §10.4.2 Port Reset - assume hung after 500 mil.
     1422    // Clear DMA engine and wait for completion
     1423    if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
     1424        TRACE("%s: port %d error DMA engine still running\n", __func__,
     1425            fIndex);
     1426        return false;
     1427    }
    13421428
    13431429    return true;
    13441430}
  • src/add-ons/kernel/busses/scsi/ahci/ahci_port.h

    diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
    index 0bc4e67..deed571 100644
    a b private:  
    4848    void        ExecuteSataRequest(sata_request *request, bool isWrite = false);
    4949
    5050    void        ResetDevice();
    51     status_t    ResetPort(bool forceDeviceReset = false);
     51    status_t    SoftReset();
     52    status_t    PortReset();
    5253    status_t    PostReset();
     54
     55    bool        Enable();
     56    bool        Disable();
     57
    5358    void        FlushPostedWrites();
    5459    void        DumpD2HFis();
    5560
    private:  
    5762    status_t    WaitForTransfer(int *tfd, bigtime_t timeout);
    5863    void        FinishTransfer();
    5964
    60     inline  bool                _HardReset();
    6165    inline  void                _ClearErrorRegister();
    6266
    6367//  uint8 *     SetCommandFis(volatile command_list_entry *cmd, volatile fis *fis, const void *data, size_t dataSize);
    private:  
    7983    uint64                          fSectorCount;
    8084    bool                            fIsATAPI;
    8185    bool                            fTestUnitReadyActive;
    82     bool                            fResetPort;
     86    bool                            fSoftReset;
    8387    bool                            fError;
    8488    bool                            fTrimSupported;
    8589    uint32                          fMaxTrimRangeBlocks;
  • src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp

    diff --git a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp
    index 6a53fcf..9e06dce 100644
    a b sata_request::SetATAPICommand(size_t transferLength)  
    121121void
    122122sata_request::Finish(int tfd, size_t bytesTransfered)
    123123{
    124     if ((tfd & (ATA_ERR | ATA_DF)) != 0) {
     124    if ((tfd & (ATA_STATUS_ERROR | ATA_STATUS_DEVICE_FAULT)) != 0) {
    125125        uint8 status = tfd & 0xff;
    126126        uint8 error = (tfd >> 8) & 0xff;
    127127
    sata_request::Finish(int tfd, size_t bytesTransfered)  
    135135        fCcb->data_resid = fCcb->data_length - bytesTransfered;
    136136        fCcb->device_status = SCSI_STATUS_GOOD;
    137137        fCcb->subsys_status = SCSI_REQ_CMP;
    138         if (tfd & (ATA_ERR | ATA_DF)) {
     138        if (tfd & (ATA_STATUS_ERROR | ATA_STATUS_DEVICE_FAULT)) {
    139139            fCcb->subsys_status = SCSI_REQ_CMP_ERR;
    140140            if (fIsATAPI) {
    141141                if (!IsTestUnitReady()) {
    sata_request::Abort()  
    187187        gSCSI->finished(fCcb, 1);
    188188        delete this;
    189189    } else {
    190         fCompletionStatus = ATA_ERR;
     190        fCompletionStatus = ATA_STATUS_ERROR;
    191191        release_sem(fCompletionSem);
    192192    }
    193193}