Ticket #12357: ahci-rework-v6.diff

File ahci-rework-v6.diff, 16.8 KB (added by kallisti5, 5 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..c69c4a4 100644
    a b  
    22 * Copyright 2008-2015 Haiku, Inc. All rights reserved.
    33 * Copyright 2007-2009, Marcus Overhagen. All rights reserved.
    44 * Distributed under the terms of the MIT License.
     5 *
     6 * Authors:
     7 *      Axel Dörfler, axeld@pinc-software.de
     8 *      Michael Lotz, mmlr@mlotz.ch
     9 *      Alexander von Gluck IV, kallisti5@unixzen.com
    510 */
    611
    712
    AHCIPort::AHCIPort(AHCIController* controller, int index)  
    5459    fSectorCount(0),
    5560    fIsATAPI(false),
    5661    fTestUnitReadyActive(false),
    57     fResetPort(false),
     62    fSoftReset(false),
    5863    fError(false),
    5964    fTrimSupported(false)
    6065{
    AHCIPort::Init1()  
    120125    fRegs->is = fRegs->is;
    121126
    122127    // clear error bits
    123     fRegs->serr = fRegs->serr;
     128    _ClearErrorRegister();
    124129
    125130    // power up device
    126131    fRegs->cmd |= PORT_CMD_POD;
    AHCIPort::Init1()  
    131136    // activate link
    132137    fRegs->cmd = (fRegs->cmd & ~PORT_CMD_ICC_MASK) | PORT_CMD_ICC_ACTIVE;
    133138
    134     // enable FIS receive
    135     fRegs->cmd |= PORT_CMD_FER;
     139    // enable FIS receive (enabled when fb set, only to be disabled when unset)
     140    fRegs->cmd |= PORT_CMD_FRE;
    136141
    137142    FlushPostedWrites();
    138143
    AHCIPort::Init2()  
    146151{
    147152    TRACE("AHCIPort::Init2 port %d\n", fIndex);
    148153
    149     // start DMA engine
    150     fRegs->cmd |= PORT_CMD_ST;
     154    // enable port
     155    Enable();
    151156
    152157    // enable interrupts
    153158    fRegs->ie = PORT_INT_MASK;
    154159
    155160    FlushPostedWrites();
    156161
    157     ResetPort(true);
     162    // reset port and probe info
     163    SoftReset();
    158164
    159165    TRACE("ie   0x%08" B_PRIx32 "\n", fRegs->ie);
    160166    TRACE("is   0x%08" B_PRIx32 "\n", fRegs->is);
    AHCIPort::Init2()  
    172178
    173179    fDevicePresent = (fRegs->ssts & 0xf) == 0x3;
    174180
     181    TRACE("%s: port %d, device %s\n", __func__, fIndex,
     182        fDevicePresent ? "present" : "absent");
     183
    175184    return B_OK;
    176185}
    177186
    AHCIPort::Uninit()  
    181190{
    182191    TRACE("AHCIPort::Uninit port %d\n", fIndex);
    183192
    184     // disable FIS receive
    185     fRegs->cmd &= ~PORT_CMD_FER;
     193    // Spec v1.3.1, §10.3.2 - Shut down port before unsetting FRE
    186194
    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);
     195    // shutdown the port
     196    if (!Disable()) {
     197        ERROR("%s: port %d error, unable to shutdown before FRE clear!\n",
     198            __func__, fIndex);
     199        return;
    190200    }
    191201
    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     }
     202    // Clear FRE and wait for completion
     203    fRegs->cmd &= ~PORT_CMD_FRE;
     204    if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK)
     205        ERROR("%s: port %d error FIS rx still running\n", __func__, fIndex);
    200206
    201207    // disable interrupts
    202208    fRegs->ie = 0;
    void  
    218224AHCIPort::ResetDevice()
    219225{
    220226    // perform a hard reset
    221     if (!_HardReset())
     227    if (PortReset() != B_OK) {
     228        ERROR("%s: port %d unable to hard reset device\n", __func__, fIndex);
    222229        return;
     230    }
    223231
    224232    if (wait_until_set(&fRegs->ssts, 0x1, 100000) < B_OK)
    225233        TRACE("AHCIPort::ResetDevice port %d no device detected\n", fIndex);
    AHCIPort::ResetDevice()  
    238246
    239247
    240248status_t
    241 AHCIPort::ResetPort(bool forceDeviceReset)
     249AHCIPort::SoftReset()
    242250{
    243     if (!fTestUnitReadyActive)
    244         TRACE("AHCIPort::ResetPort port %d\n", fIndex);
     251    TRACE("AHCIPort::SoftReset port %d\n", fIndex);
    245252
    246     // stop DMA engine
    247     fRegs->cmd &= ~PORT_CMD_ST;
    248     FlushPostedWrites();
     253    // Spec v1.3.1, §10.4.1 Software Reset
     254    // A single device on one port is reset, HBA and phy comm remain intact.
    249255
    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);
     256    // stop port, flush transactions
     257    if (!Disable()) {
     258        // If the port doesn't power off, move on to a stronger reset.
     259        ERROR("%s: port %d soft reset failed. Moving on to port reset.\n",
     260            __func__, fIndex);
     261        return PortReset();
    253262    }
    254263
    255     bool deviceBusy = fRegs->tfd & (ATA_BSY | ATA_DRQ);
     264    // start port
     265    Enable();
    256266
    257     if (!fTestUnitReadyActive) {
    258         TRACE("AHCIPort::ResetPort port %d, deviceBusy %d, "
    259             "forceDeviceReset %d\n", fIndex, deviceBusy, forceDeviceReset);
    260     }
     267    // TODO: If FBS Enable, clear PxFBS.EN prior to issuing sw reset
    261268
    262     if (deviceBusy || forceDeviceReset)
    263         ResetDevice();
     269    if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
     270        1000000) < B_OK) {
     271        ERROR("%s: port %d still busy. Moving on to port reset.\n",
     272            __func__, fIndex);
     273        return PortReset();
     274    }
    264275
    265     // start DMA engine
    266     fRegs->cmd |= PORT_CMD_ST;
     276    // TODO: This needs... work.
     277    #if 0
     278    cpu_status cpu = disable_interrupts();
     279    acquire_spinlock(&fSpinlock);
     280    // ATA Reset + clear busy
     281    fCommandList->r = 1;
     282    fCommandList->c = 1;
     283    // Issue Command
     284    fRegs->ci = 1;
    267285    FlushPostedWrites();
     286    release_spinlock(&fSpinlock);
     287    restore_interrupts(cpu);
     288
     289    if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
     290        1000000) < B_OK) {
     291        ERROR("%s: port %d software reset failed. Doing port reset...\n",
     292            __func__, fIndex);
     293        return PortReset();
     294    }
     295    #endif
    268296
    269297    return PostReset();
    270298}
    271299
    272300
    273301status_t
    274 AHCIPort::PostReset()
     302AHCIPort::PortReset()
    275303{
    276     if (!fTestUnitReadyActive)
    277         TRACE("AHCIPort::PostReset port %d\n", fIndex);
     304    TRACE("AHCIPort::PortReset port %d\n", fIndex);
     305
     306    // Spec v1.3.1, §10.4.2 Port Reset
     307    // Physical comm between HBA and port disabled. More Intrusive
     308    if (!Disable()) {
     309        ERROR("%s: port %d unable to reset!\n", __func__, fIndex);
     310        return B_ERROR;
     311    }
     312
     313    fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
     314        | DET_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
     315    FlushPostedWrites();
     316    spin(1100);
     317        // You must wait 1ms at minimum
     318    fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
     319        | DET_NO_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
     320    FlushPostedWrites();
    278321
    279     if ((fRegs->ssts & 0xf) != 0x3 || (fRegs->tfd & 0xff) == 0x7f) {
    280         TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
    281         return B_OK;
     322    if (wait_until_set(&fRegs->ssts, 0x3, 500000) < B_OK) {
     323        TRACE("AHCIPort::PortReset port %d device present but no phy "
     324            "communication\n", fIndex);
     325        return B_ERROR;
    282326    }
    283327
     328    //if ((fRegs->tfd & 0xff) == 0x7f) {
     329    //  TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
     330    //  return B_OK;
     331    //}
     332
     333    Enable();
     334
     335    return PostReset();
     336}
     337
     338
     339status_t
     340AHCIPort::PostReset()
     341{
    284342    if ((fRegs->tfd & 0xff) == 0xff)
    285343        snooze(200000);
    286344
    AHCIPort::PostReset()  
    290348        return B_ERROR;
    291349    }
    292350
    293     wait_until_clear(&fRegs->tfd, ATA_BSY, 31000000);
    294 
    295     fIsATAPI = fRegs->sig == 0xeb140101;
     351    wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY, 31000000);
    296352
     353    fIsATAPI = fRegs->sig == SATA_SIG_ATAPI;
    297354    if (fIsATAPI)
    298355        fRegs->cmd |= PORT_CMD_ATAPI;
    299356    else
    AHCIPort::PostReset()  
    302359
    303360    if (!fTestUnitReadyActive) {
    304361        TRACE("device signature 0x%08" B_PRIx32 " (%s)\n", fRegs->sig,
    305             fRegs->sig == 0xeb140101 ? "ATAPI" : fRegs->sig == 0x00000101
     362            fRegs->sig == SATA_SIG_ATAPI ? "ATAPI" : fRegs->sig == SATA_SIG_ATA
    306363                ? "ATA" : "unknown");
    307364    }
    308365
     366    _ClearErrorRegister();
     367
    309368    return B_OK;
    310369}
    311370
    AHCIPort::InterruptErrorHandler(uint32 is)  
    374433    }
    375434
    376435    // read and clear SError
    377     uint32 serr = fRegs->serr;
    378     fRegs->serr = serr;
     436    _ClearErrorRegister();
    379437
    380438    if (is & PORT_INT_TFE) {
    381439        if (!fTestUnitReadyActive)
    382440            TRACE("Task File Error\n");
    383441
    384         fResetPort = true;
     442        fSoftReset = true;
    385443        fError = true;
    386444    }
    387445    if (is & PORT_INT_HBF) {
    388446        TRACE("Host Bus Fatal Error\n");
    389         fResetPort = true;
     447        fSoftReset = true;
    390448        fError = true;
    391449    }
    392450    if (is & PORT_INT_HBD) {
    393451        TRACE("Host Bus Data Error\n");
    394         fResetPort = true;
     452        fSoftReset = true;
    395453        fError = true;
    396454    }
    397455    if (is & PORT_INT_IF) {
    398456        TRACE("Interface Fatal Error\n");
    399         fResetPort = true;
     457        fSoftReset = true;
    400458        fError = true;
    401459    }
    402460    if (is & PORT_INT_INF) {
    AHCIPort::InterruptErrorHandler(uint32 is)  
    404462    }
    405463    if (is & PORT_INT_OF) {
    406464        TRACE("Overflow\n");
    407         fResetPort = true;
     465        fSoftReset = true;
    408466        fError = true;
    409467    }
    410468    if (is & PORT_INT_IPM) {
    AHCIPort::InterruptErrorHandler(uint32 is)  
    412470    }
    413471    if (is & PORT_INT_PRC) {
    414472        TRACE("PhyReady Change\n");
    415 //      fResetPort = true;
     473//      fSoftReset = true;
    416474    }
    417475    if (is & PORT_INT_PC) {
    418476        TRACE("Port Connect Change\n");
    419477        // TODO: check if the COMINIT is actually unsolicited!
    420478        // Spec v1.3, §6.2.2.3 Recovery of Unsolicited COMINIT
     479        // Spec v1.3.1, §7.4 Interaction of command list and port change status
     480        // TODO: Issue COMRESET ?
     481        //PortReset();
     482        //HBAReset(); ???
    421483
    422         // perform a hard reset
    423 //      if (!_HardReset())
    424 //          return;
    425 //
    426 //      // clear error bits to clear PxSERR.DIAG.X
    427 //      _ClearErrorRegister();
     484        // clear error bits to clear PxSERR.DIAG.X
     485        _ClearErrorRegister();
    428486    }
    429487    if (is & PORT_INT_UF) {
    430488        TRACE("Unknown FIS\n");
    431         fResetPort = true;
     489        fSoftReset = true;
    432490    }
    433491
    434492    if (fError) {
    AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,  
    453511    status_t status = get_memory_map_etc(B_CURRENT_TEAM, data, dataSize,
    454512        entries, &entriesUsed);
    455513    if (status != B_OK) {
    456         TRACE("AHCIPort::FillPrdTable get_memory_map() failed: %s\n",
    457             strerror(status));
     514        TRACE("%s: get_memory_map() failed: %s\n", __func__, strerror(status));
    458515        return B_ERROR;
    459516    }
    460517
    AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,  
    501558        sgCount--;
    502559    }
    503560    if (*prdCount == 0) {
    504         TRACE("AHCIPort::FillPrdTable: count is 0\n");
     561        TRACE("%s: count is 0\n", __func__);
    505562        return B_ERROR;
    506563    }
    507564    if (dataSize > 0) {
    AHCIPort::ScsiInquiry(scsi_ccb* request)  
    664721    ExecuteSataRequest(&sreq);
    665722    sreq.WaitForCompletion();
    666723
    667     if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
     724    if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
    668725        ERROR("identify device failed\n");
    669726        request->subsys_status = SCSI_REQ_CMP_ERR;
    670727        gSCSI->finished(request, 1);
    for (uint32 i = 0; i < lbaRangeCount; i++) {  
    10061063        ExecuteSataRequest(&sreq);
    10071064        sreq.WaitForCompletion();
    10081065
    1009         if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
     1066        if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
    10101067            TRACE("trim failed (%" B_PRIu32 " ranges)!\n", lbaRangeCount);
    10111068            request->subsys_status = SCSI_REQ_CMP_ERR;
    10121069        } else
    AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)  
    10581115    fCommandList->prdtl = prdEntrys;
    10591116    fCommandList->prdbc = 0;
    10601117
    1061     if (wait_until_clear(&fRegs->tfd, ATA_BSY | ATA_DRQ, 1000000) < B_OK) {
     1118    if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
     1119            1000000) < B_OK) {
    10621120        TRACE("ExecuteAtaRequest port %d: device is busy\n", fIndex);
    1063         ResetPort();
     1121        SoftReset();
    10641122        FinishTransfer();
    10651123        request->Abort();
    10661124        return;
    AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)  
    10951153    TRACE("tfd  0x%08" B_PRIx32 "\n", fRegs->tfd);
    10961154*/
    10971155
    1098     if (fResetPort || status == B_TIMED_OUT) {
    1099         fResetPort = false;
    1100         ResetPort();
     1156    if (fSoftReset || status == B_TIMED_OUT) {
     1157        fSoftReset = false;
     1158        SoftReset();
    11011159    }
    11021160
    11031161    size_t bytesTransfered = fCommandList->prdbc;
    AHCIPort::ScsiGetRestrictions(bool* isATAPI, bool* noAutoSense,  
    13231381
    13241382
    13251383bool
    1326 AHCIPort::_HardReset()
     1384AHCIPort::Enable()
    13271385{
     1386    // Spec v1.3.1, §10.3.1 Start (PxCMD.ST)
     1387    TRACE("%s: port %d\n", __func__, fIndex);
    13281388    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");
     1389        TRACE("%s: Starting port already running!\n", __func__);
    13311390        return false;
    13321391    }
    13331392
    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;
     1393    if ((fRegs->cmd & PORT_CMD_FRE) == 0) {
     1394        TRACE("%s: Unable to start port without FRE enabled!\n", __func__);
     1395        return false;
     1396    }
     1397
     1398    // Clear DMA engine and wait for completion
     1399    if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
     1400        TRACE("%s: port %d error DMA engine still running\n", __func__,
     1401            fIndex);
     1402        return false;
     1403    }
     1404    // Start port
     1405    fRegs->cmd |= PORT_CMD_ST;
    13411406    FlushPostedWrites();
     1407    return true;
     1408}
     1409
     1410
     1411bool
     1412AHCIPort::Disable()
     1413{
     1414    TRACE("%s: port %d\n", __func__, fIndex);
     1415
     1416    if ((fRegs->cmd & PORT_CMD_ST) == 0) {
     1417        // Port already disabled, carry on.
     1418        TRACE("%s: port %d attempting to disable stopped port.\n",
     1419            __func__, fIndex);
     1420    } else {
     1421        // Disable port
     1422        fRegs->cmd &= ~PORT_CMD_ST;
     1423        FlushPostedWrites();
     1424    }
     1425
     1426    // Spec v1.3.1, §10.4.2 Port Reset - assume hung after 500 mil.
     1427    // Clear DMA engine and wait for completion
     1428    if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
     1429        TRACE("%s: port %d error DMA engine still running\n", __func__,
     1430            fIndex);
     1431        return false;
     1432    }
    13421433
    13431434    return true;
    13441435}
  • 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}