~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Devices/Storage/ATAController.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: ATAController.cpp $ */
 
1
/* $Id: ATAController.cpp 35595 2011-01-17 20:05:15Z vboxsync $ */
2
2
/** @file
3
3
 * DevATA, DevAHCI - Shared ATA/ATAPI controller code (disk and cdrom).
4
4
 *
21
21
*   Header Files                                                               *
22
22
*******************************************************************************/
23
23
#define LOG_GROUP LOG_GROUP_DEV_IDE
24
 
#include <VBox/pdmdev.h>
 
24
#include <VBox/vmm/pdmdev.h>
25
25
#include <iprt/assert.h>
26
26
#include <iprt/string.h>
27
27
#ifdef IN_RING3
33
33
#endif /* IN_RING3 */
34
34
#include <iprt/critsect.h>
35
35
#include <iprt/asm.h>
36
 
#include <VBox/stam.h>
37
 
#include <VBox/mm.h>
38
 
#include <VBox/pgm.h>
 
36
#include <VBox/vmm/stam.h>
 
37
#include <VBox/vmm/mm.h>
 
38
#include <VBox/vmm/pgm.h>
39
39
 
40
40
#include <VBox/scsi.h>
41
41
 
355
355
    int rc;
356
356
    bool fIdle;
357
357
 
 
358
    if (pCtl->AsyncIORequestMutex == NIL_RTSEMMUTEX)
 
359
        return true;
 
360
 
358
361
    rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
359
362
    AssertRC(rc);
360
363
    fIdle = pCtl->fRedoIdle;
465
468
            pCtl->BmDma.u8Status |= BM_STATUS_INT;
466
469
        /* Only actually set the IRQ line if updating the currently selected drive. */
467
470
        if (s == &pCtl->aIfs[pCtl->iSelectedIf])
468
 
            PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
 
471
            PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
469
472
    }
470
473
    s->fIrqPending = true;
471
474
}
482
485
        Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN));
483
486
        /* Only actually unset the IRQ line if updating the currently selected drive. */
484
487
        if (s == &pCtl->aIfs[pCtl->iSelectedIf])
485
 
            PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
 
488
            PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
486
489
    }
487
490
    s->fIrqPending = false;
488
491
}
1535
1538
            uint8_t u8Cmd = s->aATAPICmd[0];
1536
1539
            do
1537
1540
            {
1538
 
                /* don't log superflous errors */
 
1541
                /* don't log superfluous errors */
1539
1542
                if (    rc == VERR_DEV_IO_ERROR
1540
1543
                    && (   u8Cmd == SCSI_TEST_UNIT_READY
1541
1544
                        || u8Cmd == SCSI_READ_CAPACITY
1690
1693
                /* mount */
1691
1694
                ataH2BE_U16(pbBuf + 0, 6);
1692
1695
                pbBuf[2] = 0x04; /* media */
1693
 
                pbBuf[3] = 0x5e; /* suppored = busy|media|external|power|operational */
 
1696
                pbBuf[3] = 0x5e; /* supported = busy|media|external|power|operational */
1694
1697
                pbBuf[4] = 0x02; /* new medium */
1695
1698
                pbBuf[5] = 0x02; /* medium present / door closed */
1696
1699
                pbBuf[6] = 0x00;
1702
1705
                /* umount */
1703
1706
                ataH2BE_U16(pbBuf + 0, 6);
1704
1707
                pbBuf[2] = 0x04; /* media */
1705
 
                pbBuf[3] = 0x5e; /* suppored = busy|media|external|power|operational */
 
1708
                pbBuf[3] = 0x5e; /* supported = busy|media|external|power|operational */
1706
1709
                pbBuf[4] = 0x03; /* media removal */
1707
1710
                pbBuf[5] = 0x00; /* medium absent / door closed */
1708
1711
                pbBuf[6] = 0x00;
1725
1728
            default:
1726
1729
                ataH2BE_U16(pbBuf + 0, 6);
1727
1730
                pbBuf[2] = 0x01; /* operational change request / notification */
1728
 
                pbBuf[3] = 0x5e; /* suppored = busy|media|external|power|operational */
 
1731
                pbBuf[3] = 0x5e; /* supported = busy|media|external|power|operational */
1729
1732
                pbBuf[4] = 0x00;
1730
1733
                pbBuf[5] = 0x00;
1731
1734
                pbBuf[6] = 0x00;
2284
2287
 
2285
2288
                        PDMCritSectLeave(&pCtl->lock);
2286
2289
                        rc = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
2287
 
                                             (PFNRT)s->pDrvMount->pfnUnmount, 2, s->pDrvMount, false);
 
2290
                                             (PFNRT)s->pDrvMount->pfnUnmount, 3, s->pDrvMount,
 
2291
                                             false /*=fForce*/, true /*=fEeject*/);
2288
2292
                        AssertReleaseRC(rc);
2289
2293
                        {
2290
2294
                            STAM_PROFILE_START(&pCtl->StatLockWait, a);
2917
2921
            s->fLBA48 = true;
2918
2922
        case ATA_READ_SECTORS:
2919
2923
        case ATA_READ_SECTORS_WITHOUT_RETRIES:
2920
 
            if (!s->pDrvBlock)
 
2924
            if (!s->pDrvBlock || s->fATAPI)
2921
2925
                goto abort_cmd;
2922
2926
            s->cSectorsPerIRQ = 1;
2923
2927
            ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2926
2930
            s->fLBA48 = true;
2927
2931
        case ATA_WRITE_SECTORS:
2928
2932
        case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
 
2933
            if (!s->pDrvBlock || s->fATAPI)
 
2934
                goto abort_cmd;
2929
2935
            s->cSectorsPerIRQ = 1;
2930
2936
            ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2931
2937
            break;
2932
2938
        case ATA_READ_MULTIPLE_EXT:
2933
2939
            s->fLBA48 = true;
2934
2940
        case ATA_READ_MULTIPLE:
2935
 
            if (!s->cMultSectors)
 
2941
            if (!s->pDrvBlock || !s->cMultSectors || s->fATAPI)
2936
2942
                goto abort_cmd;
2937
2943
            s->cSectorsPerIRQ = s->cMultSectors;
2938
2944
            ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2940
2946
        case ATA_WRITE_MULTIPLE_EXT:
2941
2947
            s->fLBA48 = true;
2942
2948
        case ATA_WRITE_MULTIPLE:
2943
 
            if (!s->cMultSectors)
 
2949
            if (!s->pDrvBlock || !s->cMultSectors || s->fATAPI)
2944
2950
                goto abort_cmd;
2945
2951
            s->cSectorsPerIRQ = s->cMultSectors;
2946
2952
            ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2949
2955
            s->fLBA48 = true;
2950
2956
        case ATA_READ_DMA:
2951
2957
        case ATA_READ_DMA_WITHOUT_RETRIES:
2952
 
            if (!s->pDrvBlock)
 
2958
            if (!s->pDrvBlock || s->fATAPI)
2953
2959
                goto abort_cmd;
2954
2960
            s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
2955
2961
            s->fDMA = true;
2959
2965
            s->fLBA48 = true;
2960
2966
        case ATA_WRITE_DMA:
2961
2967
        case ATA_WRITE_DMA_WITHOUT_RETRIES:
2962
 
            if (!s->pDrvBlock)
 
2968
            if (!s->pDrvBlock || s->fATAPI)
2963
2969
                goto abort_cmd;
2964
2970
            s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
2965
2971
            s->fDMA = true;
3224
3230
                         * for a rising edge. */
3225
3231
                        pCtl->BmDma.u8Status |= BM_STATUS_INT;
3226
3232
                        if (pCtl->irq == 16)
3227
 
                            PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
 
3233
                            PDMDevHlpPCISetIrq(pDevIns, 0, 1);
3228
3234
                        else
3229
 
                            PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
 
3235
                            PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
3230
3236
                    }
3231
3237
                    else
3232
3238
                    {
3233
3239
                        Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3234
3240
                        if (pCtl->irq == 16)
3235
 
                            PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
 
3241
                            PDMDevHlpPCISetIrq(pDevIns, 0, 0);
3236
3242
                        else
3237
 
                            PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
 
3243
                            PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
3238
3244
                    }
3239
3245
                }
3240
3246
            }
3472
3478
             * edge. */
3473
3479
            pCtl->BmDma.u8Status |= BM_STATUS_INT;
3474
3480
            if (pCtl->irq == 16)
3475
 
                PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 1);
 
3481
                PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 1);
3476
3482
            else
3477
 
                PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
 
3483
                PDMDevHlpISASetIrq(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
3478
3484
        }
3479
3485
        else
3480
3486
        {
3481
3487
            Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3482
3488
            if (pCtl->irq == 16)
3483
 
                PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 0);
 
3489
                PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 0);
3484
3490
            else
3485
 
                PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
 
3491
                PDMDevHlpISASetIrq(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
3486
3492
        }
3487
3493
    }
3488
3494
 
3881
3887
}
3882
3888
 
3883
3889
 
3884
 
/** Asynch I/O thread for an interface. Once upon a time this was readable
 
3890
/** Async I/O thread for an interface. Once upon a time this was readable
3885
3891
 * code with several loops and a different semaphore for each purpose. But
3886
3892
 * then came the "how can one save the state in the middle of a PIO transfer"
3887
3893
 * question. The solution was to use an ASM, which is what's there now. */
4562
4568
#endif
4563
4569
 
4564
4570
/**
4565
 
 * Reset the controller to an intial state.
 
4571
 * Reset the controller to an initial state.
4566
4572
 *
4567
4573
 * @returns VBox status.
4568
4574
 * @param   pDevIns     The device instance data.
4705
4711
 
4706
4712
        PPDMDEVINS pDevIns = pCtl->CTX_SUFF(pDevIns);
4707
4713
        rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
 
4714
#ifndef IN_RING3
 
4715
        /* Paranoia. */
 
4716
        if (RT_FAILURE(rc))
 
4717
        {
 
4718
            PDMCritSectLeave(&pCtl->lock);
 
4719
            AssertFailed();
 
4720
            return VINF_IOM_HC_IOPORT_READ;
 
4721
        }
 
4722
#else
4708
4723
        Assert(rc == VINF_SUCCESS);
 
4724
#endif
4709
4725
 
4710
4726
        if (cbTransfer)
4711
4727
            Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4757
4773
 
4758
4774
        PPDMDEVINS pDevIns = pCtl->CTX_SUFF(pDevIns);
4759
4775
        rc = PGMPhysSimpleReadGCPtr(PDMDevHlpGetVMCPU(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
 
4776
#ifndef IN_RING3
 
4777
        /* Paranoia. */
 
4778
        if (RT_FAILURE(rc))
 
4779
        {
 
4780
            PDMCritSectLeave(&pCtl->lock);
 
4781
            AssertFailed();
 
4782
            return VINF_IOM_HC_IOPORT_WRITE;
 
4783
        }
 
4784
#else
4760
4785
        Assert(rc == VINF_SUCCESS);
 
4786
#endif
4761
4787
 
4762
4788
        if (cbTransfer)
4763
4789
            Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5258
5284
        SSMR3PutMem(pSSM, &pCtl->aIfs[j].abATAPISense, sizeof(pCtl->aIfs[j].abATAPISense));
5259
5285
        SSMR3PutU8(pSSM, pCtl->aIfs[j].cNotifiedMediaChange);
5260
5286
        SSMR3PutU32(pSSM, pCtl->aIfs[j].MediaEventStatus);
5261
 
        SSMR3PutMem(pSSM, pCtl->aIfs[j].pLed, sizeof(PDMLED));
 
5287
 
 
5288
        PDMLED Led;
 
5289
        memset(&Led, 0, sizeof(PDMLED));
 
5290
        SSMR3PutMem(pSSM, &Led, sizeof(PDMLED));
5262
5291
        SSMR3PutU32(pSSM, pCtl->aIfs[j].cbIOBuffer);
5263
5292
        if (pCtl->aIfs[j].cbIOBuffer)
5264
5293
            SSMR3PutMem(pSSM, pCtl->aIfs[j].CTX_SUFF(pbIOBuffer), pCtl->aIfs[j].cbIOBuffer);
5416
5445
    return VINF_SUCCESS;
5417
5446
}
5418
5447
 
5419
 
DECLCALLBACK(int) ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
5420
 
                                    unsigned iLUNMaster, PPDMIBASE pDrvBaseMaster,
5421
 
                                    unsigned iLUNSlave, PPDMIBASE pDrvBaseSlave,
5422
 
                                    uint32_t *pcbSSMState, const char *szName, PPDMLED pLed,
5423
 
                                    PSTAMCOUNTER pStatBytesRead, PSTAMCOUNTER pStatBytesWritten)
 
5448
int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
 
5449
                      unsigned iLUNMaster, PPDMIBASE pDrvBaseMaster, PPDMLED pLedMaster,
 
5450
                      PSTAMCOUNTER pStatBytesReadMaster, PSTAMCOUNTER pStatBytesWrittenMaster,
 
5451
                      unsigned iLUNSlave, PPDMIBASE pDrvBaseSlave, PPDMLED pLedSlave,
 
5452
                      PSTAMCOUNTER pStatBytesReadSlave, PSTAMCOUNTER pStatBytesWrittenSlave,
 
5453
                      uint32_t *pcbSSMState, const char *szName)
5424
5454
{
5425
5455
    int      rc;
5426
5456
 
5443
5473
        pCtl->aIfs[j].pControllerR3     = pCtl;
5444
5474
        pCtl->aIfs[j].pControllerR0     = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), pCtl);
5445
5475
        pCtl->aIfs[j].pControllerRC     = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pCtl);
5446
 
        pCtl->aIfs[j].pLed              = pLed;
5447
 
        pCtl->aIfs[j].pStatBytesRead    = pStatBytesRead;
5448
 
        pCtl->aIfs[j].pStatBytesWritten = pStatBytesWritten;
 
5476
        pCtl->aIfs[j].pLed              = j == 0 ? pLedMaster : pLedSlave;
 
5477
        pCtl->aIfs[j].pStatBytesRead    = j == 0 ? pStatBytesReadMaster : pStatBytesReadSlave;
 
5478
        pCtl->aIfs[j].pStatBytesWritten = j == 0 ? pStatBytesWrittenMaster : pStatBytesWrittenSlave;
5449
5479
    }
5450
5480
 
5451
5481
    /* Initialize per-controller critical section */