VirtualBox

Changeset 57979 in vbox


Ignore:
Timestamp:
Oct 1, 2015 8:25:21 AM (9 years ago)
Author:
vboxsync
Message:

Parallel ports: Several fixes for multiple parallel ports. Make the second parallel port visible to the guest through ACPI if enabled (and don't expose the first port if it is not enabled), increase the maximum instanbce count to 2 and make it possible to enable a parallel port without having it connected to a host device to make it behave like it is not connected to anything.

Location:
trunk/src/VBox
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r57358 r57979  
    183183    SYSTEM_INFO_INDEX_SERIAL1_IOBASE    = 24,
    184184    SYSTEM_INFO_INDEX_SERIAL1_IRQ       = 25,
    185     SYSTEM_INFO_INDEX_END               = 26,
     185    SYSTEM_INFO_INDEX_PARALLEL0_IOBASE  = 26,
     186    SYSTEM_INFO_INDEX_PARALLEL0_IRQ     = 27,
     187    SYSTEM_INFO_INDEX_PARALLEL1_IOBASE  = 28,
     188    SYSTEM_INFO_INDEX_PARALLEL1_IRQ     = 29,
     189    SYSTEM_INFO_INDEX_END               = 30,
    186190    SYSTEM_INFO_INDEX_INVALID           = 0x80,
    187191    SYSTEM_INFO_INDEX_VALID             = 0x200
     
    313317    /** Serial 1 IO port base */
    314318    RTIOPORT            uSerial1IoPortBase;
     319
     320    /** @name Parallel port config bits
     321     * @{ */
     322    /** Parallel 0 IRQ number */
     323    uint8_t             uParallel0Irq;
     324    /** Parallel 1 IRQ number */
     325    uint8_t             uParallel1Irq;
     326    /** Parallel 0 IO port base */
     327    RTIOPORT            uParallel0IoPortBase;
     328    /** Parallel 1 IO port base */
     329    RTIOPORT            uParallel1IoPortBase;
     330    /** @} */
     331
     332    uint32_t            u32Alignment1;
     333
    315334    /** ACPI port base interface. */
    316335    PDMIBASE            IBase;
     
    322341    PPDMDEVINSRC        pDevInsRC;
    323342
    324     uint32_t            Alignment1;
     343    uint32_t            Alignment2;
    325344    /** Pointer to the driver base interface. */
    326345    R3PTRTYPE(PPDMIBASE) pDrvBase;
     
    345364    /** ACPI custom OEM Rev */
    346365    uint32_t            u32OemRevision;
    347     uint32_t            Alignment2;
     366    uint32_t            Alignment3;
    348367
    349368    /** The custom table binary data. */
     
    13191338            break;
    13201339
     1340        case SYSTEM_INFO_INDEX_PARALLEL0_IOBASE:
     1341            *pu32 = pThis->uParallel0IoPortBase;
     1342            break;
     1343
     1344        case SYSTEM_INFO_INDEX_PARALLEL0_IRQ:
     1345            *pu32 = pThis->uParallel0Irq;
     1346            break;
     1347
     1348        case SYSTEM_INFO_INDEX_PARALLEL1_IOBASE:
     1349            *pu32 = pThis->uParallel1IoPortBase;
     1350            break;
     1351
     1352        case SYSTEM_INFO_INDEX_PARALLEL1_IRQ:
     1353            *pu32 = pThis->uParallel1Irq;
     1354            break;
     1355
    13211356        case SYSTEM_INFO_INDEX_END:
    13221357            /** @todo why isn't this setting any output value?  */
     
    30573092                              "CustomTable\0"
    30583093                              "SLICTable\0"
     3094                              "Parallel0IoPortBase\0"
     3095                              "Parallel1IoPortBase\0"
     3096                              "Parallel0Irq\0"
     3097                              "Parallel1Irq\0"
    30593098                              ))
    30603099        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     
    31943233        return PDMDEV_SET_ERROR(pDevIns, rc,
    31953234                                N_("Configuration error: Failed to read \"Serial1IoPortBase\""));
     3235
     3236    /*
     3237     * Query settings for both parallel ports, if the CFGM keys don't exist pretend that
     3238     * the corresponding parallel port is not enabled.
     3239     */
     3240    rc = CFGMR3QueryU8Def(pCfg, "Parallel0Irq", &pThis->uSerial0Irq, 0);
     3241    if (RT_FAILURE(rc))
     3242        return PDMDEV_SET_ERROR(pDevIns, rc,
     3243                                N_("Configuration error: Failed to read \"Parallel0Irq\""));
     3244
     3245    rc = CFGMR3QueryU16Def(pCfg, "Parallel0IoPortBase", &pThis->uParallel0IoPortBase, 0);
     3246    if (RT_FAILURE(rc))
     3247        return PDMDEV_SET_ERROR(pDevIns, rc,
     3248                                N_("Configuration error: Failed to read \"Parallel0IoPortBase\""));
     3249
     3250    rc = CFGMR3QueryU8Def(pCfg, "Parallel1Irq", &pThis->uParallel1Irq, 0);
     3251    if (RT_FAILURE(rc))
     3252        return PDMDEV_SET_ERROR(pDevIns, rc,
     3253                                N_("Configuration error: Failed to read \"Parallel1Irq\""));
     3254
     3255    rc = CFGMR3QueryU16Def(pCfg, "Parallel1IoPortBase", &pThis->uParallel1IoPortBase, 0);
     3256    if (RT_FAILURE(rc))
     3257        return PDMDEV_SET_ERROR(pDevIns, rc,
     3258                                N_("Configuration error: Failed to read \"Parallel1IoPortBase\""));
    31963259
    31973260    /* Try to attach the other CPUs */
  • trunk/src/VBox/Devices/PC/vbox.dsl

    r56292 r57979  
    154154        SL1B,  32, // Serial1 base IO address 
    155155        SL1I,  32, // Serial1 IRQ
     156        PP0B,  32, // Parallel0 base IO address 
     157        PP0I,  32, // Parallel0 IRQ
     158        PP1B,  32, // Parallel1 base IO address 
     159        PP1I,  32, // Parallel1 IRQ
    156160        Offset (0x80),
    157161        ININ, 32,
     
    667671                }
    668672
    669                 // Parallel port
    670                 Device (LPT)
     673                // Parallel port 0
     674                Device (^LPT0)
    671675                {
    672676                    Name (_HID, EisaId ("PNP0400"))
     677                    Name (_UID, 0x01)
    673678                    Method (_STA, 0, NotSerialized)
    674679                    {
    675                         Return (0x0F)
    676                     }
    677                     Name (_CRS, ResourceTemplate ()
    678                     {
    679                         IO (Decode16, 0x0378, 0x0378, 0x08, 0x08)
    680                         IO (Decode16, 0x0778, 0x0778, 0x08, 0x08)
    681                         IRQNoFlags () {7}
     680                        If (LEqual (PP0B, Zero))
     681                        {
     682                            Return (0x00)
     683                        }
     684                        Else
     685                        {
     686                            Return (0x0F)
     687                        }
     688                    }
     689                    Name (CRS, ResourceTemplate ()
     690                    {
     691                        IO (Decode16, 0x0378, 0x0378, 0x08, 0x08, _Y18)
     692                        IRQNoFlags (_Y19) {7}
    682693                    })
    683                 }
     694                    Method (_CRS, 0, NotSerialized)
     695                    {
     696                        CreateWordField (CRS, \_SB.PCI0.LPT0._Y18._MIN, PMI0)
     697                        CreateWordField (CRS, \_SB.PCI0.LPT0._Y18._MAX, PMA0)
     698                        CreateWordField (CRS, \_SB.PCI0.LPT0._Y19._INT, PIQ0)
     699                        Store (PP0B, PMI0)
     700                        Store (PP0B, PMA0)
     701                        ShiftLeft (0x01, PP0I, PIQ0)
     702                        Return (CRS)
     703                    }
     704                }
     705
     706                // Parallel port 1
     707                Device (^LPT1)
     708                {
     709                    Name (_HID, EisaId ("PNP0400"))
     710                    Name (_UID, 0x02)
     711                    Method (_STA, 0, NotSerialized)
     712                    {
     713                        If (LEqual (PP1B, Zero))
     714                        {
     715                            Return (0x00)
     716                        }
     717                        Else
     718                        {
     719                            Return (0x0F)
     720                        }
     721                    }
     722                    Name (CRS, ResourceTemplate ()
     723                    {
     724                        IO (Decode16, 0x0278, 0x0278, 0x08, 0x08, _Y20)
     725                        IRQNoFlags (_Y21) {5}
     726                    })
     727                    Method (_CRS, 0, NotSerialized)
     728                    {
     729                        CreateWordField (CRS, \_SB.PCI0.LPT1._Y20._MIN, PMI1)
     730                        CreateWordField (CRS, \_SB.PCI0.LPT1._Y20._MAX, PMA1)
     731                        CreateWordField (CRS, \_SB.PCI0.LPT1._Y21._INT, PIQ1)
     732                        Store (PP1B, PMI1)
     733                        Store (PP1B, PMA1)
     734                        ShiftLeft (0x01, PP1I, PIQ1)
     735                        Return (CRS)
     736                    }
     737                }
     738
    684739
    685740                // Serial port 0
  • trunk/src/VBox/Devices/Parallel/DevParallel.cpp

    r57358 r57979  
    357357                    return VINF_IOM_R3_IOPORT_WRITE;
    358358#else
    359                     /* Set data direction. */
    360                     if (u8 & LPT_CONTROL_ENABLE_BIDIRECT)
    361                         rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, false /* fForward */);
     359                    if (RT_LIKELY(pThis->pDrvHostParallelConnector))
     360                    {
     361                        /* Set data direction. */
     362                        if (u8 & LPT_CONTROL_ENABLE_BIDIRECT)
     363                            rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, false /* fForward */);
     364                        else
     365                            rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, true /* fForward */);
     366                        AssertRC(rc);
     367
     368                        u8 &= ~LPT_CONTROL_ENABLE_BIDIRECT; /* Clear bit. */
     369
     370                        rc = pThis->pDrvHostParallelConnector->pfnWriteControl(pThis->pDrvHostParallelConnector, u8);
     371                        AssertRC(rc);
     372                    }
    362373                    else
    363                         rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, true /* fForward */);
    364                     AssertRC(rc);
    365                     u8 &= ~LPT_CONTROL_ENABLE_BIDIRECT; /* Clear bit. */
    366 
    367                     rc = pThis->pDrvHostParallelConnector->pfnWriteControl(pThis->pDrvHostParallelConnector, u8);
    368                     AssertRC(rc);
     374                        u8 &= ~LPT_CONTROL_ENABLE_BIDIRECT; /* Clear bit. */
     375
    369376                    pThis->regControl = u8;
    370377#endif
     
    462469            case 2:
    463470#ifndef IN_RING3
    464                  rc = VINF_IOM_R3_IOPORT_READ;
     471                rc = VINF_IOM_R3_IOPORT_READ;
    465472#else
    466                  rc = pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
    467                  AssertRC(rc);
    468                  pThis->regControl |= LPT_CONTROL_BIT6 | LPT_CONTROL_BIT7;
     473                if (RT_LIKELY(pThis->pDrvHostParallelConnector))
     474                {
     475                    rc = pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
     476                    AssertRC(rc);
     477                    pThis->regControl |= LPT_CONTROL_BIT6 | LPT_CONTROL_BIT7;
     478                }
     479
    469480                *pu32 = pThis->regControl;
    470481#endif
     
    766777    {
    767778        pThis->pDrvHostParallelConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIHOSTPARALLELCONNECTOR);
     779
     780        /* Set compatibility mode */
     781        //pThis->pDrvHostParallelConnector->pfnSetMode(pThis->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT);
     782        /* Get status of control register */
     783        pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
     784
    768785        AssertMsgReturn(pThis->pDrvHostParallelConnector,
    769786                        ("Configuration error: instance %d has no host parallel interface!\n", iInstance),
     
    782799                                   N_("Parallel device %d cannot attach to host driver"), iInstance);
    783800    }
    784 
    785     /* Set compatibility mode */
    786     //pThis->pDrvHostParallelConnector->pfnSetMode(pThis->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT);
    787     /* Get status of control register */
    788     pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
    789801
    790802    return VINF_SUCCESS;
     
    811823    PDM_DEVREG_CLASS_PARALLEL,
    812824    /* cMaxInstances */
    813     1,
     825    2,
    814826    /* cbInstance */
    815827    sizeof(PARALLELPORT),
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r57524 r57979  
    1725517255        Host parallel device name. If this parallel port is enabled, setting a
    1725617256        @c null or an empty string as this attribute's value will result in
    17257         an error.
     17257        the parallel port behaving as if not connected to any device.
    1725817258      </desc>
    1725917259    </attribute>
  • trunk/src/VBox/Main/include/ParallelPortImpl.h

    r49871 r57979  
    5151    void i_commit();
    5252    void i_copyFrom(ParallelPort *aThat);
     53    void i_applyDefaults();
    5354
    5455private:
     
    6566    HRESULT setPath(const com::Utf8Str &aPath);
    6667
    67     HRESULT i_checkSetPath(const Utf8Str &str);
    68 
    6968    struct Data;
    7069    Data *m;
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r57809 r57979  
    26412641         * Parallel (LPT) Ports
    26422642         */
     2643        /* parallel enabled mask to be passed to dev ACPI */
     2644        uint16_t auParallelIoPortBase[SchemaDefs::ParallelPortCount] = {0};
     2645        uint8_t auParallelIrq[SchemaDefs::ParallelPortCount] = {0};
    26432646        InsertConfigNode(pDevices, "parallel", &pDev);
    26442647        for (ULONG ulInstance = 0; ulInstance < SchemaDefs::ParallelPortCount; ++ulInstance)
     
    26602663            hrc = parallelPort->COMGETTER(IRQ)(&ulIRQ);                                     H();
    26612664            InsertConfigInteger(pCfg, "IRQ", ulIRQ);
     2665            auParallelIrq[ulInstance] = (uint8_t)ulIRQ;
    26622666            ULONG ulIOBase;
    26632667            hrc = parallelPort->COMGETTER(IOBase)(&ulIOBase);                               H();
    26642668            InsertConfigInteger(pCfg,   "IOBase", ulIOBase);
    2665             InsertConfigNode(pInst,     "LUN#0", &pLunL0);
    2666             InsertConfigString(pLunL0,  "Driver", "HostParallel");
    2667             InsertConfigNode(pLunL0,    "Config", &pLunL1);
     2669            auParallelIoPortBase[ulInstance] = (uint16_t)ulIOBase;
     2670
    26682671            hrc = parallelPort->COMGETTER(Path)(bstr.asOutParam());                         H();
    2669             InsertConfigString(pLunL1,  "DevicePath", bstr);
     2672            if (!bstr.isEmpty())
     2673            {
     2674                InsertConfigNode(pInst,     "LUN#0", &pLunL0);
     2675                InsertConfigString(pLunL0,  "Driver", "HostParallel");
     2676                InsertConfigNode(pLunL0,    "Config", &pLunL1);
     2677                InsertConfigString(pLunL1,  "DevicePath", bstr);
     2678            }
    26702679        }
    26712680
     
    30913100            InsertConfigInteger(pCfg,  "Serial1IoPortBase", auSerialIoPortBase[1]);
    30923101            InsertConfigInteger(pCfg,  "Serial1Irq", auSerialIrq[1]);
     3102
     3103            InsertConfigInteger(pCfg,  "Parallel0IoPortBase", auParallelIoPortBase[0]);
     3104            InsertConfigInteger(pCfg,  "Parallel0Irq", auParallelIrq[0]);
     3105
     3106            InsertConfigInteger(pCfg,  "Parallel1IoPortBase", auParallelIoPortBase[1]);
     3107            InsertConfigInteger(pCfg,  "Parallel1Irq", auParallelIrq[1]);
    30933108
    30943109            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r57832 r57979  
    353353            for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)
    354354                mSerialPorts[slot]->i_applyDefaults(aOsType);
     355
     356            /* Apply parallel port defaults */
     357            for (ULONG slot = 0; slot < RT_ELEMENTS(mParallelPorts); ++slot)
     358                mParallelPorts[slot]->i_applyDefaults();
    355359
    356360            /* Let the OS type select 64-bit ness. */
  • trunk/src/VBox/Main/src-server/ParallelPortImpl.cpp

    r54971 r57979  
    215215    if (m->bd->fEnabled != !!aEnabled)
    216216    {
    217         if (aEnabled &&
    218             m->bd->strPath.isEmpty())
    219             return setError(E_INVALIDARG,
    220                             tr("Cannot enable the parallel port %d because the port path is empty or null"),
    221                             m->bd->ulSlot);
    222 
    223217        m->bd.backup();
    224218        m->bd->fEnabled = !!aEnabled;
     
    352346    if (aPath != m->bd->strPath)
    353347    {
    354         HRESULT rc = i_checkSetPath(aPath);
    355         if (FAILED(rc)) return rc;
    356 
    357348        m->bd.backup();
    358349        m->bd->strPath = aPath;
     
    498489
    499490/**
    500  *  Validates COMSETTER(Path) arguments.
    501  */
    502 HRESULT ParallelPort::i_checkSetPath(const Utf8Str &str)
    503 {
    504     AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
    505 
    506     if (    m->bd->fEnabled
    507          && str.isEmpty()
    508        )
    509         return setError(E_INVALIDARG,
    510                         tr("Path of the parallel port %d may not be empty or null "
    511                            "when the port is enabled"),
    512                         m->bd->ulSlot);
    513 
    514     return S_OK;
    515 }
    516 
     491 * Applies the defaults for the given parallel port.
     492 */
     493void ParallelPort::i_applyDefaults()
     494{
     495    /* sanity */
     496    AutoCaller autoCaller(this);
     497    AssertComRCReturnVoid (autoCaller.rc());
     498
     499    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     500
     501    /* Set some more defaults based on the slot. */
     502    switch (m->bd->ulSlot)
     503    {
     504        case 0:
     505        {
     506            m->bd->ulIOBase = 0x378;
     507            m->bd->ulIRQ = 7;
     508            break;
     509        }
     510        case 1:
     511        {
     512            m->bd->ulIOBase = 0x278;
     513            m->bd->ulIRQ = 5;
     514            break;
     515        }
     516        default: break;
     517    }
     518}
    517519
    518520/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracChangeset for help on using the changeset viewer.

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