VirtualBox

Changeset 23467 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Oct 1, 2009 10:15:35 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53076
Message:

AHCI: Bring CD/DVD support into a workable state again. Passthrough and runtime media changes are not working yet

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r23149 r23467  
    207207/** Pointer to a pointer of a scatter gather list entry. */
    208208typedef PAHCIPORTTASKSTATESGENTRY *PPAHCIPORTTASKSTATESGENTRY;
     209/** Pointer to a task state. */
     210typedef struct AHCIPORTTASKSTATE *PAHCIPORTTASKSTATE;
     211
     212/**
     213 * Data processing callback
     214 *
     215 * @returns VBox status.
     216 * @param   pAhciPortTaskState    The task state.
     217 */
     218typedef DECLCALLBACK(int)   FNAHCIPOSTPROCESS(PAHCIPORTTASKSTATE pAhciPortTaskState);
     219/** Pointer to a FNAHCIPOSTPROCESS() function. */
     220typedef FNAHCIPOSTPROCESS *PFNAHCIPOSTPROCESS;
    209221
    210222/**
     
    235247    /** ATA status register */
    236248    uint8_t                    uATARegStatus;
     249    /** How many entries would fit into the sg list. */
     250    uint32_t                   cSGListSize;
     251    /** Number of used SG list entries. */
     252    uint32_t                   cSGListUsed;
     253    /** Pointer to the first entry of the scatter gather list. */
     254    PPDMDATASEG                pSGListHead;
    237255    /** Number of scatter gather list entries. */
    238256    uint32_t                   cSGEntries;
    239     /** How many entries would fit into the sg list. */
    240     uint32_t                   cSGListSize;
    241     /** Pointer to the first entry of the scatter gather list. */
    242     PPDMDATASEG                pSGListHead;
     257    /** Total number of bytes the guest reserved for this request.
     258     * Sum of all SG entries. */
     259    uint32_t                   cbSGBuffers;
    243260    /** Pointer to the first mapping information entry. */
    244261    PAHCIPORTTASKSTATESGENTRY  paSGEntries;
     
    249266    /** Number of times in a row the scatter gather list was too big. */
    250267    uint32_t                   cSGListTooBig;
    251 } AHCIPORTTASKSTATE, *PAHCIPORTTASKSTATE;
     268    /** Post processing callback.
     269     * If this is set we will use a buffer for the data
     270     * and the callback copies the data to the destination. */
     271    PFNAHCIPOSTPROCESS         pfnPostProcess;
     272} AHCIPORTTASKSTATE;
    252273
    253274/**
     
    810831static void ahciCopyFromBufferIntoSGList(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo);
    811832static void ahciCopyFromSGListIntoBuffer(PPDMDEVINS pDevIns, PAHCIPORTTASKSTATESGENTRY pSGInfo);
     833static void ahciScatterGatherListGetTotalBufferSize(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState);
     834static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState,
     835                                           bool fReadonly, unsigned cSGEntriesProcessed);
    812836#endif
    813837RT_C_DECLS_END
     
    29102934
    29112935    /* Copy the buffer in to the scatter gather list. */
    2912     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&p[0], sizeof(p));
    2913     *pcbData = sizeof(p);
     2936    *pcbData =  ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&p[0], sizeof(p));
    29142937
    29152938    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    29252948
    29262949    /* Copy the buffer in to the scatter gather list. */
    2927     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    2928     *pcbData = sizeof(aBuf);
     2950    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    29292951
    29302952    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    29532975
    29542976    /* Copy the buffer in to the scatter gather list. */
    2955     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    2956     *pcbData = sizeof(aBuf);
     2977    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    29572978
    29582979    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    29843005
    29853006    /* Copy the buffer in to the scatter gather list. */
    2986     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    2987     *pcbData = sizeof(aBuf);
     3007    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    29883008
    29893009    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    30203040
    30213041    /* Copy the buffer in to the scatter gather list. */
    3022     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3023     *pcbData = sizeof(aBuf);
     3042    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    30243043
    30253044    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    30453064
    30463065    /* Copy the buffer in to the scatter gather list. */
    3047     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3048     *pcbData = sizeof(aBuf);
     3066    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    30493067
    30503068    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    30753093
    30763094    /* Copy the buffer in to the scatter gather list. */
    3077     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3078     *pcbData = sizeof(aBuf);
     3095    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    30793096
    30803097    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    31263143
    31273144    /* Copy the buffer in to the scatter gather list. */
    3128     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3129     *pcbData = sizeof(aBuf);
     3145    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    31303146
    31313147    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    31453161
    31463162    /* Copy the buffer in to the scatter gather list. */
    3147     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3148     *pcbData = sizeof(aBuf);
     3163    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    31493164
    31503165    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    31663181
    31673182    /* Copy the buffer in to the scatter gather list. */
    3168     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3169     *pcbData = sizeof(aBuf);
     3183    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    31703184
    31713185    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    32293243
    32303244    /* Copy the buffer in to the scatter gather list. */
    3231     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize);
    3232     *pcbData = cbSize;
     3245    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize);
    32333246
    32343247    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    32633276
    32643277    /* Copy the buffer in to the scatter gather list. */
    3265     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    3266     *pcbData = sizeof(aBuf);
     3278    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], sizeof(aBuf));
    32673279
    32683280    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    33523364
    33533365    /* Copy the buffer in to the scatter gather list. */
    3354     ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize);
    3355     *pcbData = cbSize;
     3366    *pcbData = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, (void *)&aBuf[0], cbSize);
    33563367
    33573368    atapiCmdOK(pAhciPort, pAhciPortTaskState);
     
    33643375    int rc, rcSourceSink;
    33653376
    3366     /* Create scatter gather list. */
    3367     rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, false);
    3368     if (RT_FAILURE(rc))
    3369         AssertMsgFailed(("Getting number of list elements failed rc=%Rrc\n", rc));
     3377    /*
     3378     * Create scatter gather list. We use a safe mapping here because it is
     3379     * possible that the buffer is not a multiple of 512. The normal
     3380     * creator would assert later here.
     3381     */
     3382    ahciScatterGatherListGetTotalBufferSize(pAhciPort, pAhciPortTaskState);
     3383    rc = ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, false, 0);
     3384    AssertRC(rc);
    33703385
    33713386    rcSourceSink = g_apfnAtapiFuncs[iSourceSink](pAhciPortTaskState, pAhciPort, &cbTransfered);
     
    33743389
    33753390    rc = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState);
    3376     if (RT_FAILURE(rc))
    3377         AssertMsgFailed(("Destroying list failed rc=%Rrc\n", rc));
     3391    AssertRC(rc);
    33783392
    33793393    /* Write updated command header into memory of the guest. */
     
    33813395
    33823396    return rcSourceSink;
     3397}
     3398
     3399static int atapiReadSectors2352PostProcess(PAHCIPORTTASKSTATE pAhciPortTaskState)
     3400{
     3401    uint32_t cSectors  = pAhciPortTaskState->cbTransfer / 2048;
     3402    uint32_t iATAPILBA = pAhciPortTaskState->uOffset / 2048;
     3403    uint8_t *pbBufDst  = (uint8_t *)pAhciPortTaskState->pvBufferUnaligned;
     3404    uint8_t *pbBufSrc  = (uint8_t *)pAhciPortTaskState->pSGListHead[0].pvSeg;
     3405
     3406    for (uint32_t i = iATAPILBA; i < iATAPILBA + cSectors; i++)
     3407    {
     3408        /* sync bytes */
     3409        *pbBufDst++ = 0x00;
     3410        memset(pbBufDst, 0xff, 11);
     3411        pbBufDst += 11;
     3412        /* MSF */
     3413        ataLBA2MSF(pbBufDst, i);
     3414        pbBufDst += 3;
     3415        *pbBufDst++ = 0x01; /* mode 1 data */
     3416        /* data */
     3417        memcpy(pbBufDst, pbBufSrc, 2048);
     3418        pbBufDst += 2048;
     3419        pbBufSrc += 2048;
     3420        /* ECC */
     3421        memset(pbBufDst, 0, 288);
     3422        pbBufDst += 288;
     3423    }
     3424
     3425    return VINF_SUCCESS;
    33833426}
    33843427
     
    33943437            break;
    33953438        case 2352:
    3396             {
    3397                 AssertMsgFailed(("2352 read\n"));
    3398                 /* @todo: This is quite difficult as the data transfer is not handled here
    3399                           We need to add the sync bytes etc. here and modify the pointers
    3400                           and size of the sg entries.  */
    3401 #if 0
    3402                 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
    3403 
    3404                 for (uint32_t i = s->iATAPILBA; i < s->iATAPILBA + cSectors; i++)
    3405                 {
    3406                     /* sync bytes */
    3407                     *pbBuf++ = 0x00;
    3408                     memset(pbBuf, 0xff, 11);
    3409                     pbBuf += 11;
    3410                     /* MSF */
    3411                     ataLBA2MSF(pbBuf, i);
    3412                     pbBuf += 3;
    3413                     *pbBuf++ = 0x01; /* mode 1 data */
    3414                     /* data */
    3415                     rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)i * 2048, pbBuf, 2048);
    3416                     if (RT_FAILURE(rc))
    3417                         break;
    3418                     pbBuf += 2048;
    3419                     /* ECC */
    3420                     memset(pbBuf, 0, 288);
    3421                     pbBuf += 288;
    3422                 }
    3423 #endif
    3424                 pAhciPortTaskState->uOffset = iATAPILBA * 2048;
    3425                 pAhciPortTaskState->cbTransfer = cSectors * 2048;
    3426             }
     3439        {
     3440            pAhciPortTaskState->pfnPostProcess = atapiReadSectors2352PostProcess;
     3441            pAhciPortTaskState->uOffset = iATAPILBA * 2048;
     3442            pAhciPortTaskState->cbTransfer = cSectors * 2048;
    34273443            break;
     3444        }
    34283445        default:
    34293446            AssertMsgFailed(("Unsupported sectors size\n"));
     
    39964013}
    39974014
     4015static void ahciScatterGatherListGetTotalBufferSize(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState)
     4016{
     4017    CmdHdr    *pCmdHdr = &pAhciPortTaskState->cmdHdr;
     4018    PPDMDEVINS pDevIns = pAhciPort->CTX_SUFF(pDevIns);
     4019    unsigned   cActualSGEntry;
     4020    SGLEntry   aSGLEntry[32];                  /* Holds read sg entries from guest. Biggest seen number of entries a guest set up. */
     4021    unsigned   cSGLEntriesGCRead;
     4022    unsigned   cSGLEntriesGCLeft;              /* Available scatter gather list entries in GC */
     4023    RTGCPHYS   GCPhysAddrPRDTLEntryStart;      /* Start address to read the entries from. */
     4024    uint32_t   cbSGBuffers = 0;                /* Total number of bytes reserved for this request. */
     4025
     4026    /* Retrieve the total number of bytes reserved for this request. */
     4027    cSGLEntriesGCLeft = AHCI_CMDHDR_PRDTL_ENTRIES(pCmdHdr->u32DescInf);
     4028    ahciLog(("%s: cSGEntriesGC=%u\n", __FUNCTION__, cSGLEntriesGCLeft));
     4029
     4030    /* Set start address of the entries. */
     4031    GCPhysAddrPRDTLEntryStart = AHCI_RTGCPHYS_FROM_U32(pCmdHdr->u32CmdTblAddrUp, pCmdHdr->u32CmdTblAddr) + AHCI_CMDHDR_PRDT_OFFSET;
     4032
     4033    do
     4034    {
     4035        cSGLEntriesGCRead = (cSGLEntriesGCLeft < RT_ELEMENTS(aSGLEntry)) ? cSGLEntriesGCLeft : RT_ELEMENTS(aSGLEntry);
     4036        cSGLEntriesGCLeft -= cSGLEntriesGCRead;
     4037
     4038        /* Read the SG entries. */
     4039        PDMDevHlpPhysRead(pDevIns, GCPhysAddrPRDTLEntryStart, &aSGLEntry[0], cSGLEntriesGCRead * sizeof(SGLEntry));
     4040
     4041        for (cActualSGEntry = 0; cActualSGEntry < cSGLEntriesGCRead; cActualSGEntry++)
     4042            cbSGBuffers += (aSGLEntry[cActualSGEntry].u32DescInf & SGLENTRY_DESCINF_DBC) + 1;
     4043
     4044        /* Set address to the next entries to read. */
     4045        GCPhysAddrPRDTLEntryStart += cSGLEntriesGCRead * sizeof(SGLEntry);
     4046
     4047    } while (cSGLEntriesGCLeft);
     4048
     4049    pAhciPortTaskState->cbSGBuffers = cbSGBuffers;
     4050}
     4051
    39984052static int ahciScatterGatherListAllocate(PAHCIPORTTASKSTATE pAhciPortTaskState, uint32_t cSGList, uint32_t cbUnaligned)
    39994053{
     
    40694123 * Fallback scatter gather list creator.
    40704124 * Used if the normal one fails in PDMDevHlpPhysGCPhys2CCPtr() or
    4071  * PDMDevHlpPhysGCPhys2CCPtrReadonly()
     4125 * PDMDevHlpPhysGCPhys2CCPtrReadonly() or post processing
     4126 * is used.
    40724127 *
    40734128 * returns VBox status code.
     
    40874142    PAHCIPORTTASKSTATESGENTRY  pSGInfoCurr  = pAhciPortTaskState->paSGEntries;
    40884143
    4089     AssertPtr(pAhciPortTaskState->pSGListHead);
    4090     AssertPtr(pAhciPortTaskState->paSGEntries);
     4144    Assert(VALID_PTR(pAhciPortTaskState->pSGListHead) || !cSGEntriesProcessed);
     4145    Assert(VALID_PTR(pAhciPortTaskState->paSGEntries) || !cSGEntriesProcessed);
    40914146
    40924147    for (unsigned cSGEntryCurr = 0; cSGEntryCurr < cSGEntriesProcessed; cSGEntryCurr++)
     
    41034158
    41044159    if (pAhciPortTaskState->pvBufferUnaligned)
     4160    {
    41054161        RTMemFree(pAhciPortTaskState->pvBufferUnaligned);
    4106 
    4107     pAhciPortTaskState->cSGListTooBig     = 0;
    4108 
    4109     RTMemFree(pAhciPortTaskState->pSGListHead);
    4110     RTMemFree(pAhciPortTaskState->paSGEntries);
    4111     pAhciPortTaskState->cSGEntries = 1;
    4112     pAhciPortTaskState->cSGListSize = 1;
    4113     pAhciPortTaskState->cbBufferUnaligned = pAhciPortTaskState->cbTransfer;
     4162        pAhciPortTaskState->pvBufferUnaligned = NULL;
     4163    }
     4164    if (pAhciPortTaskState->pSGListHead)
     4165    {
     4166        RTMemFree(pAhciPortTaskState->pSGListHead);
     4167        pAhciPortTaskState->pSGListHead = NULL;
     4168    }
     4169    if (pAhciPortTaskState->paSGEntries)
     4170    {
     4171        RTMemFree(pAhciPortTaskState->paSGEntries);
     4172        pAhciPortTaskState->paSGEntries = NULL;
     4173    }
     4174    pAhciPortTaskState->cSGListTooBig = 0;
     4175    pAhciPortTaskState->cSGEntries    = 1;
     4176    pAhciPortTaskState->cSGListUsed   = 1;
     4177    pAhciPortTaskState->cSGListSize   = 1;
     4178    pAhciPortTaskState->cbBufferUnaligned = pAhciPortTaskState->cbSGBuffers;
    41144179
    41154180    /* Allocate new buffers and SG lists. */
    4116     pAhciPortTaskState->pvBufferUnaligned = RTMemAlloc(pAhciPortTaskState->cbTransfer);
     4181    pAhciPortTaskState->pvBufferUnaligned = RTMemAlloc(pAhciPortTaskState->cbSGBuffers);
    41174182    if (!pAhciPortTaskState->pvBufferUnaligned)
    41184183        return VERR_NO_MEMORY;
     
    41344199
    41354200    /* Set pointers. */
    4136     pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbTransfer;
    4137     pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned;
     4201    if (pAhciPortTaskState->cbTransfer)
     4202    {
     4203        pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbTransfer;
     4204
     4205        /* Allocate a separate buffer if we have to do post processing . */
     4206        if (pAhciPortTaskState->pfnPostProcess)
     4207        {
     4208            pAhciPortTaskState->pSGListHead[0].pvSeg = RTMemAlloc(pAhciPortTaskState->cbTransfer);
     4209            if (!pAhciPortTaskState->pSGListHead[0].pvSeg)
     4210            {
     4211                RTMemFree(pAhciPortTaskState->paSGEntries);
     4212                RTMemFree(pAhciPortTaskState->pvBufferUnaligned);
     4213                RTMemFree(pAhciPortTaskState->pSGListHead);
     4214                return VERR_NO_MEMORY;
     4215            }
     4216        }
     4217        else
     4218            pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned;
     4219    }
     4220    else
     4221    {
     4222        pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbBufferUnaligned;
     4223        pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned;
     4224    }
    41384225
    41394226    pAhciPortTaskState->paSGEntries[0].fGuestMemory = false;
     
    41744261    uint32_t   cUnaligned;
    41754262    bool       fDoMapping = false;
     4263    uint32_t   cbSGBuffers = 0;                /* Total number of bytes reserved for this request. */
    41764264    RTGCPHYS   GCPhysAddrPRDTLUnalignedStart = NIL_RTGCPHYS;
    41774265    PAHCIPORTTASKSTATESGENTRY  pSGInfoCurr  = NULL;
     
    41844272
    41854273    STAM_PROFILE_START(&pAhciPort->StatProfileMapIntoR3, a);
     4274
     4275    pAhciPortTaskState->cbSGBuffers = 0;
     4276
     4277    /*
     4278     * Create a safe mapping when doing post processing because the size of the
     4279     * data to transfer and the amount of guest memory reserved can differ
     4280     */
     4281    if (pAhciPortTaskState->pfnPostProcess)
     4282    {
     4283        ahciLog(("%s: Request with post processing.\n"));
     4284
     4285        ahciScatterGatherListGetTotalBufferSize(pAhciPort, pAhciPortTaskState);
     4286
     4287        return ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, fReadonly, 0);
     4288    }
    41864289
    41874290    /*
     
    42204323            pSGInfoCurr->fGuestMemory= false;
    42214324            pu8BufferUnalignedPos = (uint8_t *)pAhciPortTaskState->pvBufferUnaligned;
     4325            pAhciPortTaskState->cSGListUsed = 0;
     4326            pAhciPortTaskState->cbSGBuffers = cbSGBuffers;
    42224327        }
    42234328
     
    42394344                cbDataToTransfer = (aSGLEntry[cActualSGEntry].u32DescInf & SGLENTRY_DESCINF_DBC) + 1;
    42404345                ahciLog(("%s: cbDataToTransfer=%u\n", __FUNCTION__, cbDataToTransfer));
     4346                cbSGBuffers += cbDataToTransfer;
    42414347
    42424348                /* Check if the buffer is sector aligned. */
     
    43014407                                pSGInfoCurr++;
    43024408                                pSGEntryCurr++;
     4409                                pAhciPortTaskState->cSGListUsed++;
    43034410                                cSGEntriesProcessed++;
    43044411                            }
     
    44154522                                            pSGEntryPrev = pSGEntryCurr;
    44164523                                            pSGEntryCurr++;
     4524                                            pAhciPortTaskState->cSGListUsed++;
    44174525                                        }
    44184526
     
    44904598                                        pSGEntryPrev = pSGEntryCurr;
    44914599                                        pSGEntryCurr++;
     4600                                        pAhciPortTaskState->cSGListUsed++;
    44924601                                    }
    44934602
     
    45304639        pSGEntryCurr->pvSeg    = pu8BufferUnalignedPos;
    45314640        pSGEntryCurr->cbSeg    = cbUnaligned;
     4641        pAhciPortTaskState->cSGListUsed++;
    45324642
    45334643        /*
     
    45574667
    45584668    STAM_PROFILE_START(&pAhciPort->StatProfileDestroyScatterGatherList, a);
     4669
     4670    if (pAhciPortTaskState->pfnPostProcess)
     4671    {
     4672        int rc;
     4673        rc = pAhciPortTaskState->pfnPostProcess(pAhciPortTaskState);
     4674        AssertRC(rc);
     4675
     4676        pAhciPortTaskState->pfnPostProcess = NULL;
     4677
     4678        /* Free the buffer holding the unprocessed data. They are not needed anymore. */
     4679        RTMemFree(pAhciPortTaskState->pSGListHead[0].pvSeg);
     4680    }
    45594681
    45604682    for (unsigned cActualSGEntry = 0; cActualSGEntry < pAhciPortTaskState->cSGEntries; cActualSGEntry++)
     
    46824804 * Copy the content of a buffer to a scatter gather list.
    46834805 *
    4684  * @returns VBox status code.
     4806 * @returns Number of bytes transfered.
    46854807 * @param   pAhciPortTaskState    The task state which contains the S/G list entries.
    46864808 * @param   pvBuf                 Pointer to the buffer which should be copied.
     
    46904812{
    46914813    unsigned cSGEntry = 0;
     4814    int cbCopied = 0;
    46924815    PPDMDATASEG pSGEntry = &pAhciPortTaskState->pSGListHead[cSGEntry];
    46934816    uint8_t *pu8Buf = (uint8_t *)pvBuf;
     
    46954818    while (cSGEntry < pAhciPortTaskState->cSGEntries)
    46964819    {
    4697         size_t cbToCopy = (cbBuf < pSGEntry->cbSeg) ? cbBuf : pSGEntry->cbSeg;
     4820        size_t cbToCopy = RT_MIN(cbBuf, pSGEntry->cbSeg);
    46984821
    46994822        memcpy(pSGEntry->pvSeg, pu8Buf, cbToCopy);
    47004823
    47014824        cbBuf -= cbToCopy;
     4825        cbCopied += cbToCopy;
     4826
    47024827        /* We finished. */
    47034828        if (!cbBuf)
     
    47124837    }
    47134838
    4714 #if 0
    4715     if (!pAhciPort->fATAPI)
    4716         AssertMsg(!cbBuf, ("There is still data in the buffer\n"));
    4717 #endif
    4718     return VINF_SUCCESS;
     4839    LogFlow(("%s: Copied %d bytes\n", __FUNCTION__, cbCopied));
     4840    return cbCopied;
    47194841}
    47204842
     
    48104932    AssertMsg(pCmdFis[AHCI_CMDFIS_TYPE] == AHCI_CMDFIS_TYPE_H2D, ("FIS is not a host to device Fis!!\n"));
    48114933
     4934    pAhciPortTaskState->cbTransfer = 0;
     4935
    48124936    switch (pCmdFis[AHCI_CMDFIS_CMD])
    48134937    {
     
    48274951
    48284952                    /* Copy the buffer. */
    4829                     rc = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, &u16Temp[0], sizeof(u16Temp));
    4830                     if (RT_FAILURE(rc))
    4831                         AssertMsgFailed(("Copying failed rc=%Rrc\n", rc));
     4953                    pCmdHdr->u32PRDBC = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, &u16Temp[0], sizeof(u16Temp));
    48324954
    48334955                    /* Destroy list. */
     
    48384960                    pAhciPortTaskState->uATARegError = 0;
    48394961                    pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
    4840                     pCmdHdr->u32PRDBC = sizeof(u16Temp);
    48414962
    48424963                    /* Write updated command header into memory of the guest. */
     
    51875308                pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1;
    51885309                rc = pAhciPort->pDrvBlockAsync->pfnStartRead(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset,
    5189                                                              pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGEntries,
     5310                                                             pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed,
    51905311                                                             pAhciPortTaskState->cbTransfer,
    51915312                                                             pAhciPortTaskState);
     
    51955316                pAhciPort->Led.Asserted.s.fWriting = pAhciPort->Led.Actual.s.fWriting = 1;
    51965317                rc = pAhciPort->pDrvBlockAsync->pfnStartWrite(pAhciPort->pDrvBlockAsync, pAhciPortTaskState->uOffset,
    5197                                                               pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGEntries,
     5318                                                              pAhciPortTaskState->pSGListHead, pAhciPortTaskState->cSGListUsed,
    51985319                                                              pAhciPortTaskState->cbTransfer,
    51995320                                                              pAhciPortTaskState);
     
    54025523                    STAM_PROFILE_START(&pAhciPort->StatProfileReadWrite, a);
    54035524
    5404                     while(cbTransfer)
     5525                    while (cbTransfer)
    54055526                    {
    54065527                        size_t cbProcess = (cbTransfer < pSegCurr->cbSeg) ? cbTransfer : pSegCurr->cbSeg;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette