VirtualBox

Changeset 43642 in vbox


Ignore:
Timestamp:
Oct 15, 2012 1:35:04 PM (12 years ago)
Author:
vboxsync
Message:

DevBusLogic: Added ISA compatible port I/O and a few commands.

File:
1 edited

Legend:

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

    r43472 r43642  
    1616 */
    1717
    18 /* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]).
    19  * See also: http://www.drdobbs.com/184410111
    20  */
     18/* Based on the Multi-Master Ultra SCSI Systems Technical Reference Manual */
    2119
    2220/*******************************************************************************
    2321*   Header Files                                                               *
    2422*******************************************************************************/
    25 //#define DEBUG
     23
    2624#define LOG_GROUP LOG_GROUP_DEV_BUSLOGIC
    2725#include <VBox/vmm/pdmdev.h>
     
    6967#define BUSLOGIC_SAVED_STATE_MINOR_PRE_ERROR_HANDLING 1
    7068
    71 /** The duration of software-initiated reset. Not documented, set to 500 us. */
    72 #define BUSLOGIC_RESET_DURATION_NS      (500*1000)
     69/** The duration of software-initiated reset. Not documented, set to 2 ms. */
     70#define BUSLOGIC_RESET_DURATION_NS      (2000*1000)
    7371
    7472/**
     
    270268AssertCompileSize(HostAdapterLocalRam, 256);
    271269
     270/* Compatible ISA base I/O port addresses. Disabled if zero. */
     271#define NUM_ISA_BASES       8
     272#define MAX_ISA_BASE        (NUM_ISA_BASES - 1)
     273#define ISA_BASE_DISABLED   6
     274
     275static uint16_t     aISABases[NUM_ISA_BASES] = {
     276    0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0, 0
     277};
     278
    272279/** Pointer to a task state structure. */
    273280typedef struct BUSLOGICTASKSTATE *PBUSLOGICTASKSTATE;
     
    338345    bool                            fIRQEnabled;
    339346    /** Flag whether the ISA I/O port range is disabled
    340      * to prevent the BIOs to access the device. */
    341     bool                            fISAEnabled;
     347     * to prevent the BIOS to access the device. */
     348    bool                            fISAEnabled;    //@todo: unused, to be removed
    342349    /** Flag whether 24-bit mailboxes are in use (default is 32-bit). */
    343350    bool                            fMbxIs24Bit;    //@todo: save?
    344351    /** ISA I/O port base (encoded in FW-compatible format). */
    345     uint8_t                         uISABaseCode;   //@todo: save?
    346 
     352    uint8_t                         uISABaseCode;
     353
     354    /** ISA I/O port base (disabled if zero). */
     355    RTIOPORT                        IOISABase;     //@todo: recalculate when restoring state
    347356    /** Default ISA I/O port base in FW-compatible format. */
    348357    uint8_t                         uDefaultISABaseCode;
    349 
    350     /** ISA I/O port base (disabled if zero). */
    351     uint16_t                        uISABase;       //@todo: recalculate when restoring state
    352358
    353359    /** Number of mailboxes the guest set up. */
     
    795801#define PDMILEDPORTS_2_PBUSLOGIC(pInterface)       ( (PBUSLOGIC)((uintptr_t)(pInterface) - RT_OFFSETOF(BUSLOGIC, ILeds)) )
    796802
     803static int buslogicRegisterISARange(PBUSLOGIC pBusLogic, uint8_t uBaseCode);
     804
    797805/**
    798806 * Assert IRQ line of the BusLogic adapter.
     
    899907 * @returns VBox status code.
    900908 * @param   pBusLogic Pointer to the BusLogic device instance.
    901  */
    902 static int buslogicHwReset(PBUSLOGIC pBusLogic)
     909 * @param   fResetIO  Flag determining whether ISA I/O should be reset.
     910 */
     911static int buslogicHwReset(PBUSLOGIC pBusLogic, bool fResetIO)
    903912{
    904913    LogFlowFunc(("pBusLogic=%#p\n", pBusLogic));
     
    913922    pBusLogic->cbCommandParametersLeft = 0;
    914923    pBusLogic->fIRQEnabled = true;
    915     pBusLogic->fISAEnabled = true;
    916924    pBusLogic->uMailboxOutgoingPositionCurrent = 0;
    917925    pBusLogic->uMailboxIncomingPositionCurrent = 0;
    918926
     927    /* Guest-initiated HBA reset does not affect ISA port I/O. */
     928    if (fResetIO)
     929    {
     930        buslogicRegisterISARange(pBusLogic, pBusLogic->uDefaultISABaseCode);
     931    }
    919932    buslogicInitializeLocalRam(pBusLogic);
    920933    vboxscsiInitialize(&pBusLogic->VBoxSCSI);
     
    965978    pBusLogic->u64ResetTime = PDMDevHlpTMTimeVirtGetNano(pBusLogic->CTX_SUFF(pDevIns));
    966979
    967     buslogicHwReset(pBusLogic);
     980    buslogicHwReset(pBusLogic, false);
    968981
    969982    /* We set the diagnostic active in the status register. */
     
    13611374            /* It seems VMware does not provide valid information here too, lets do the same :) */
    13621375            pReply->InformationIsValid = 0;
    1363             pReply->IsaIOPort = 0xff; /* Make it invalid. */
     1376            pReply->IsaIOPort = pBusLogic->uISABaseCode;
    13641377            pReply->IRQ = PCIDevGetInterruptLine(&pBusLogic->dev);
    13651378            pBusLogic->cbReplyParametersLeft = sizeof(ReplyInquirePCIHostAdapterInformation);
     
    13681381        case BUSLOGICCOMMAND_MODIFY_IO_ADDRESS:
    13691382        {
     1383            /* Modify the ISA-compatible I/O port base. Note that this technically
     1384             * violates the PCI spec, as this address is not reported through PCI.
     1385             * However, it is required for compatibility with old drivers.
     1386             */
     1387#ifdef IN_RING3
     1388            Log(("ISA I/O for PCI (code %x)\n", pBusLogic->aCommandBuffer[0]));
     1389            buslogicRegisterISARange(pBusLogic, pBusLogic->aCommandBuffer[0]);
    13701390            pBusLogic->cbReplyParametersLeft = 0;
    1371             if (pBusLogic->aCommandBuffer[0] == 0x06)
    1372             {
    1373                 Log(("Disabling ISA I/O ports.\n"));
    1374                 pBusLogic->fISAEnabled = false;
    1375             }
    13761391            fSuppressIrq = true;
    13771392            break;
     1393#else
     1394            AssertMsgFailed(("Must never get here!\n"));
     1395#endif
    13781396        }
    13791397        case BUSLOGICCOMMAND_INQUIRE_BOARD_ID:
     
    14101428                /* First pass - set the number of following parameter bytes. */
    14111429                pBusLogic->cbCommandParametersLeft = pBusLogic->aCommandBuffer[0];
    1412                 Log(("Set HA options: %u bytes follow\n", pBusLogic->aCommandBuffer[0]));
     1430                Log(("Set HA options: %u bytes follow\n", pBusLogic->cbCommandParametersLeft));
    14131431            }
    14141432            else
     
    14471465            //@todo: What should the DMA channel be?
    14481466            pReply->fDmaChannel6  = 1;
    1449             /* The IRQ is not necessarily representable in this structure. */
     1467            /* The PCI IRQ is not necessarily representable in this structure.
     1468             * If that is the case, the guest likely won't function correctly,
     1469             * therefore we log a warning.
     1470             */
    14501471            switch (uPciIrq) {
    14511472            case 9:     pReply->fIrqChannel9  = 1; break;
     
    14561477            case 15:    pReply->fIrqChannel15 = 1; break;
    14571478            default:
    1458                 Log(("Inquire configuration: PCI IRQ %d cannot be represented\n", uPciIrq));
     1479                LogRel(("Warning: PCI IRQ %d cannot be represented as ISA!\n", uPciIrq));
    14591480                break;
    14601481            }
     
    14631484        case BUSLOGICCOMMAND_INQUIRE_EXTENDED_SETUP_INFORMATION:
    14641485        {
     1486            /* Some Adaptec AHA-154x drivers (e.g. OS/2) execute this command and expect
     1487             * it to fail. If it succeeds, the drivers refuse to load. However, some newer
     1488             * Adaptec 154x models supposedly support it too??
     1489             */
     1490
    14651491            /* The reply length is set by the guest and is found in the first byte of the command buffer. */
    14661492            pBusLogic->cbReplyParametersLeft = pBusLogic->aCommandBuffer[0];
     
    14861512            PReplyInquireSetupInformation pReply = (PReplyInquireSetupInformation)pBusLogic->aReplyBuffer;
    14871513            memset(pReply, 0, sizeof(ReplyInquireSetupInformation));
     1514            pReply->cMailbox = pBusLogic->cMailbox;
     1515            pReply->uSignature = 'B';
     1516            /* The 'D' signature prevents Adaptec's OS/2 drivers from getting too
     1517             * friendly with BusLogic hardware and upsetting the HBA state.
     1518             */
     1519            pReply->uCharacterD = 'D';      /* BusLogic model. */
     1520            pReply->uHostBusType = 'F';     /* PCI bus. */
    14881521            break;
    14891522        }
     
    15561589            pBusLogic->cbReplyParametersLeft = 8;
    15571590            break;
     1591        case BUSLOGICCOMMAND_INQUIRE_INSTALLED_DEVICES_ID_8_TO_15:
     1592            /* See note about cheating above. */
     1593            memset(pBusLogic->aReplyBuffer, 0, 8);
     1594            for (int i = 0; i < 8; ++i)
     1595            {
     1596                if (pBusLogic->aDeviceStates[i + 8].fPresent)
     1597                    pBusLogic->aReplyBuffer[i] = 1;
     1598            }
     1599            pBusLogic->cbReplyParametersLeft = 8;
     1600            break;
    15581601        case BUSLOGICCOMMAND_INQUIRE_TARGET_DEVICES:
    15591602        {
     
    16081651            pBusLogic->LocalRam.structured.autoSCSIData.uBusOffDelay = pBusLogic->aCommandBuffer[0];
    16091652            Log(("Bus-off time: %d\n", pBusLogic->aCommandBuffer[0]));
     1653            break;
     1654        }
     1655        case BUSLOGICCOMMAND_SET_BUS_TRANSFER_RATE:
     1656        {
     1657            pBusLogic->cbReplyParametersLeft = 0;
     1658            pBusLogic->LocalRam.structured.autoSCSIData.uDMATransferRate = pBusLogic->aCommandBuffer[0];
     1659            Log(("Bus transfer rate: %02X\n", pBusLogic->aCommandBuffer[0]));
    16101660            break;
    16111661        }
     
    18171867                    case BUSLOGICCOMMAND_SET_PREEMPT_TIME_ON_BUS:
    18181868                    case BUSLOGICCOMMAND_SET_TIME_OFF_BUS:
     1869                    case BUSLOGICCOMMAND_SET_BUS_TRANSFER_RATE:
    18191870                        pBusLogic->cbCommandParametersLeft = 1;
    18201871                        break;
     
    18411892            else
    18421893            {
     1894#ifndef IN_RING3
     1895                /* This command must be executed in R3 as it rehooks the ISA I/O port. */
     1896                if (pBusLogic->uOperationCode == BUSLOGICCOMMAND_MODIFY_IO_ADDRESS)
     1897                {
     1898                    rc = VINF_IOM_R3_IOPORT_WRITE;
     1899                    break;
     1900                }
     1901#endif
    18431902                /*
    18441903                 * The real adapter would set the Command register busy bit in the status register.
     
    19321991                                       RTIOPORT Port, uint32_t *pu32, unsigned cb)
    19331992{
    1934     PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);;
     1993    PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    19351994    unsigned iRegister = Port % 4;
    19361995
     
    19702029
    19712030#ifdef IN_RING3
    1972 /**
    1973  * Port I/O Handler for IN operations - legacy port.
     2031
     2032static int buslogicPrepareBIOSSCSIRequest(PBUSLOGIC pBusLogic)
     2033{
     2034    int rc;
     2035    PBUSLOGICTASKSTATE pTaskState;
     2036    uint32_t           uTargetDevice;
     2037
     2038    rc = RTMemCacheAllocEx(pBusLogic->hTaskCache, (void **)&pTaskState);
     2039    AssertMsgRCReturn(rc, ("Getting task from cache failed rc=%Rrc\n", rc), rc);
     2040
     2041    pTaskState->fBIOS = true;
     2042
     2043    rc = vboxscsiSetupRequest(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest, &uTargetDevice);
     2044    AssertMsgRCReturn(rc, ("Setting up SCSI request failed rc=%Rrc\n", rc), rc);
     2045
     2046    pTaskState->PDMScsiRequest.pvUser = pTaskState;
     2047
     2048    pTaskState->CTX_SUFF(pTargetDevice) = &pBusLogic->aDeviceStates[uTargetDevice];
     2049
     2050    if (!pTaskState->CTX_SUFF(pTargetDevice)->fPresent)
     2051    {
     2052        /* Device is not present. */
     2053        AssertMsg(pTaskState->PDMScsiRequest.pbCDB[0] == SCSI_INQUIRY,
     2054                    ("Device is not present but command is not inquiry\n"));
     2055
     2056        SCSIINQUIRYDATA ScsiInquiryData;
     2057
     2058        memset(&ScsiInquiryData, 0, sizeof(SCSIINQUIRYDATA));
     2059        ScsiInquiryData.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN;
     2060        ScsiInquiryData.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED;
     2061
     2062        memcpy(pBusLogic->VBoxSCSI.pBuf, &ScsiInquiryData, 5);
     2063
     2064        rc = vboxscsiRequestFinished(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest);
     2065        AssertMsgRCReturn(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc), rc);
     2066
     2067        RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     2068    }
     2069    else
     2070    {
     2071        LogFlowFunc(("before increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests));
     2072        ASMAtomicIncU32(&pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests);
     2073        LogFlowFunc(("after increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests));
     2074
     2075        rc = pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector->pfnSCSIRequestSend(pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector,
     2076                                                                                        &pTaskState->PDMScsiRequest);
     2077        AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc));
     2078    }
     2079
     2080    return rc;
     2081}
     2082
     2083
     2084/**
     2085 * Port I/O Handler for IN operations - BIOS port.
    19742086 *
    19752087 * @returns VBox status code.
     
    19812093 * @param   cb          Number of bytes read.
    19822094 */
    1983 static int  buslogicBIOSIOPortRead (PPDMDEVINS pDevIns, void *pvUser,
     2095static int  buslogicBIOSIOPortRead(PPDMDEVINS pDevIns, void *pvUser,
    19842096                                   RTIOPORT Port, uint32_t *pu32, unsigned cb)
    19852097{
     
    19892101    Assert(cb == 1);
    19902102
    1991     if (!pBusLogic->fISAEnabled)
    1992         return VINF_SUCCESS;
    1993 
    19942103    rc = vboxscsiReadRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), pu32);
    19952104
     
    19972106    //      __FUNCTION__, pu32, 1, pu32, (Port - BUSLOGIC_BIOS_IO_PORT), rc));
    19982107
     2108    return rc;
     2109}
     2110
     2111/**
     2112 * Port I/O Handler for OUT operations - BIOS port.
     2113 *
     2114 * @returns VBox status code.
     2115 *
     2116 * @param   pDevIns     The device instance.
     2117 * @param   pvUser      User argument.
     2118 * @param   uPort       Port number used for the IN operation.
     2119 * @param   u32         The value to output.
     2120 * @param   cb          The value size in bytes.
     2121 */
     2122static int buslogicBIOSIOPortWrite(PPDMDEVINS pDevIns, void *pvUser,
     2123                                   RTIOPORT Port, uint32_t u32, unsigned cb)
     2124{
     2125    int rc;
     2126    PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     2127
     2128    Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x Port=%#x\n",
     2129          pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, Port));
     2130
     2131    Assert(cb == 1);
     2132
     2133    rc = vboxscsiWriteRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), (uint8_t)u32);
     2134    if (rc == VERR_MORE_DATA)
     2135    {
     2136        rc = buslogicPrepareBIOSSCSIRequest(pBusLogic);
     2137        AssertRC(rc);
     2138    }
     2139    else if (RT_FAILURE(rc))
     2140        AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));
     2141
     2142    return VINF_SUCCESS;
     2143}
     2144
     2145/**
     2146 * Port I/O Handler for primary port range OUT string operations.
     2147 * @see FNIOMIOPORTOUTSTRING for details.
     2148 */
     2149static DECLCALLBACK(int) buslogicBIOSIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
     2150{
     2151    PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     2152    int rc;
     2153
     2154    Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
     2155          pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
     2156
     2157    rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),
     2158                             pGCPtrSrc, pcTransfer, cb);
     2159    if (rc == VERR_MORE_DATA)
     2160    {
     2161        rc = buslogicPrepareBIOSSCSIRequest(pBusLogic);
     2162        AssertRC(rc);
     2163    }
     2164    else if (RT_FAILURE(rc))
     2165        AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));
     2166
     2167    return rc;
     2168}
     2169
     2170/**
     2171 * Port I/O Handler for primary port range IN string operations.
     2172 * @see FNIOMIOPORTINSTRING for details.
     2173 */
     2174static DECLCALLBACK(int) buslogicBIOSIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
     2175{
     2176    PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     2177
     2178    LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
     2179                 pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
     2180
     2181    return vboxscsiReadString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),
     2182                              pGCPtrDst, pcTransfer, cb);
     2183}
     2184
     2185/**
     2186 * Update the ISA I/O range.
     2187 *
     2188 * @returns nothing.
     2189 * @param   pBusLogic       Pointer to the BusLogic device instance.
     2190 * @param   uBaseCode       Encoded ISA I/O base; only low 3 bits are used.
     2191 */
     2192static int buslogicRegisterISARange(PBUSLOGIC pBusLogic, uint8_t uBaseCode)
     2193{
     2194    uint8_t     uCode = uBaseCode & MAX_ISA_BASE;
     2195    uint16_t    uNewBase = aISABases[uCode];
     2196    int         rc = VINF_SUCCESS;
     2197
     2198    LogFlowFunc(("ISA I/O code %02X, new base %X\n", uBaseCode, uNewBase));
     2199
     2200    /* Check if the same port range is already registered. */
     2201    if (uNewBase != pBusLogic->IOISABase)
     2202    {
     2203        /* Unregister the old range, if any. */
     2204        if (pBusLogic->IOISABase)
     2205            rc = PDMDevHlpIOPortDeregister(pBusLogic->CTX_SUFF(pDevIns), pBusLogic->IOISABase, 4);
     2206
     2207        if (RT_SUCCESS(rc))
     2208        {
     2209            pBusLogic->IOISABase = 0;   /* First mark as unregistered. */
     2210            pBusLogic->uISABaseCode = ISA_BASE_DISABLED;
     2211
     2212            if (uNewBase)
     2213            {
     2214                /* Register the new range if requested. */
     2215                rc = PDMDevHlpIOPortRegister(pBusLogic->CTX_SUFF(pDevIns), uNewBase, 4, NULL,
     2216                                             buslogicIOPortWrite, buslogicIOPortRead,
     2217                                             NULL, NULL,
     2218                                             "BusLogic ISA");
     2219                if (RT_SUCCESS(rc))
     2220                {
     2221                    pBusLogic->IOISABase = uNewBase;
     2222                    pBusLogic->uISABaseCode = uCode;
     2223                }
     2224            }
     2225        }
     2226        if (RT_SUCCESS(rc))
     2227        {
     2228            if (uNewBase)
     2229            {
     2230                Log(("ISA I/O base: %x\n", uNewBase));
     2231                LogRel(("buslogic: ISA I/O base: %x\n", uNewBase));
     2232            }
     2233            else
     2234            {
     2235                Log(("Disabling ISA I/O ports.\n"));
     2236                LogRel(("buslogic: ISA I/O disabled\n"));
     2237            }
     2238        }
     2239
     2240    }
    19992241    return rc;
    20002242}
     
    20522294}
    20532295
    2054 
    2055 static int buslogicPrepareBIOSSCSIRequest(PBUSLOGIC pBusLogic)
    2056 {
    2057     int rc;
    2058     PBUSLOGICTASKSTATE pTaskState;
    2059     uint32_t           uTargetDevice;
    2060 
    2061     rc = RTMemCacheAllocEx(pBusLogic->hTaskCache, (void **)&pTaskState);
    2062     AssertMsgRCReturn(rc, ("Getting task from cache failed rc=%Rrc\n", rc), rc);
    2063 
    2064     pTaskState->fBIOS = true;
    2065 
    2066     rc = vboxscsiSetupRequest(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest, &uTargetDevice);
    2067     AssertMsgRCReturn(rc, ("Setting up SCSI request failed rc=%Rrc\n", rc), rc);
    2068 
    2069     pTaskState->PDMScsiRequest.pvUser = pTaskState;
    2070 
    2071     pTaskState->CTX_SUFF(pTargetDevice) = &pBusLogic->aDeviceStates[uTargetDevice];
    2072 
    2073     if (!pTaskState->CTX_SUFF(pTargetDevice)->fPresent)
    2074     {
    2075         /* Device is not present. */
    2076         AssertMsg(pTaskState->PDMScsiRequest.pbCDB[0] == SCSI_INQUIRY,
    2077                     ("Device is not present but command is not inquiry\n"));
    2078 
    2079         SCSIINQUIRYDATA ScsiInquiryData;
    2080 
    2081         memset(&ScsiInquiryData, 0, sizeof(SCSIINQUIRYDATA));
    2082         ScsiInquiryData.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN;
    2083         ScsiInquiryData.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED;
    2084 
    2085         memcpy(pBusLogic->VBoxSCSI.pBuf, &ScsiInquiryData, 5);
    2086 
    2087         rc = vboxscsiRequestFinished(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest);
    2088         AssertMsgRCReturn(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc), rc);
    2089 
    2090         RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
    2091     }
    2092     else
    2093     {
    2094         LogFlowFunc(("before increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests));
    2095         ASMAtomicIncU32(&pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests);
    2096         LogFlowFunc(("after increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests));
    2097 
    2098         rc = pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector->pfnSCSIRequestSend(pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector,
    2099                                                                                         &pTaskState->PDMScsiRequest);
    2100         AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc));
    2101     }
    2102 
    2103     return rc;
    2104 }
    2105 
    2106 /**
    2107  * Port I/O Handler for OUT operations - legacy port.
    2108  *
    2109  * @returns VBox status code.
    2110  *
    2111  * @param   pDevIns     The device instance.
    2112  * @param   pvUser      User argument.
    2113  * @param   uPort       Port number used for the IN operation.
    2114  * @param   u32         The value to output.
    2115  * @param   cb          The value size in bytes.
    2116  */
    2117 static int buslogicBIOSIOPortWrite (PPDMDEVINS pDevIns, void *pvUser,
    2118                                    RTIOPORT Port, uint32_t u32, unsigned cb)
    2119 {
    2120     int rc;
    2121     PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2122 
    2123     Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x Port=%#x\n",
    2124           pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, Port));
    2125 
    2126     Assert(cb == 1);
    2127 
    2128     if (!pBusLogic->fISAEnabled)
    2129         return VINF_SUCCESS;
    2130 
    2131     rc = vboxscsiWriteRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), (uint8_t)u32);
    2132     if (rc == VERR_MORE_DATA)
    2133     {
    2134         rc = buslogicPrepareBIOSSCSIRequest(pBusLogic);
    2135         AssertRC(rc);
    2136     }
    2137     else if (RT_FAILURE(rc))
    2138         AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));
    2139 
    2140     return VINF_SUCCESS;
    2141 }
    2142 
    2143 /**
    2144  * Port I/O Handler for primary port range OUT string operations.
    2145  * @see FNIOMIOPORTOUTSTRING for details.
    2146  */
    2147 static DECLCALLBACK(int) buslogicBIOSIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
    2148 {
    2149     PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2150     int rc;
    2151 
    2152     Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
    2153           pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
    2154 
    2155     rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),
    2156                              pGCPtrSrc, pcTransfer, cb);
    2157     if (rc == VERR_MORE_DATA)
    2158     {
    2159         rc = buslogicPrepareBIOSSCSIRequest(pBusLogic);
    2160         AssertRC(rc);
    2161     }
    2162     else if (RT_FAILURE(rc))
    2163         AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));
    2164 
    2165     return rc;
    2166 }
    2167 
    2168 /**
    2169  * Port I/O Handler for primary port range IN string operations.
    2170  * @see FNIOMIOPORTINSTRING for details.
    2171  */
    2172 static DECLCALLBACK(int) buslogicBIOSIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
    2173 {
    2174     PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2175 
    2176     LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",
    2177                  pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
    2178 
    2179     return vboxscsiReadString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),
    2180                               pGCPtrDst, pcTransfer, cb);
    2181 }
    21822296
    21832297static DECLCALLBACK(int) buslogicMMIOMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
     
    26112725    SSMR3PutU8    (pSSM, pBusLogic->cbReplyParametersLeft);
    26122726    SSMR3PutBool  (pSSM, pBusLogic->fIRQEnabled);
    2613     SSMR3PutBool  (pSSM, pBusLogic->fISAEnabled);
     2727    SSMR3PutU8    (pSSM, pBusLogic->uISABaseCode);
    26142728    SSMR3PutU32   (pSSM, pBusLogic->cMailbox);
    26152729    SSMR3PutGCPhys(pSSM, pBusLogic->GCPhysAddrMailboxOutgoingBase);
     
    26692783    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    26702784
     2785    buslogicRegisterISARange(pThis, pThis->uISABaseCode);
    26712786    buslogicKick(pThis);
    26722787    return VINF_SUCCESS;
     
    27162831    SSMR3GetU8    (pSSM, &pBusLogic->cbReplyParametersLeft);
    27172832    SSMR3GetBool  (pSSM, &pBusLogic->fIRQEnabled);
    2718     SSMR3GetBool  (pSSM, &pBusLogic->fISAEnabled);
     2833    SSMR3GetU8    (pSSM, &pBusLogic->uISABaseCode);
    27192834    SSMR3GetU32   (pSSM, &pBusLogic->cMailbox);
    27202835    SSMR3GetGCPhys(pSSM, &pBusLogic->GCPhysAddrMailboxOutgoingBase);
     
    30653180    ASMAtomicWriteBool(&pThis->fSignalIdle, false);
    30663181
    3067     buslogicHwReset(pThis);
     3182    buslogicHwReset(pThis, true);
    30683183    return true;
    30693184}
     
    30823197    {
    30833198        ASMAtomicWriteBool(&pThis->fSignalIdle, false);
    3084         buslogicHwReset(pThis);
     3199        buslogicHwReset(pThis, true);
    30853200    }
    30863201}
     
    31663281    int        rc = VINF_SUCCESS;
    31673282    bool       fBootable = true;
     3283    char       achISACompat[16];
    31683284    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    31693285
     
    31743290                              "GCEnabled\0"
    31753291                              "R0Enabled\0"
    3176                               "Bootable\0"))
     3292                              "Bootable\0"
     3293                              "ISACompat\0"))
    31773294        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    31783295                                N_("BusLogic configuration error: unknown option specified"));
     
    31943311                                N_("BusLogic configuration error: failed to read Bootable as boolean"));
    31953312    Log(("%s: fBootable=%RTbool\n", __FUNCTION__, fBootable));
     3313    rc = CFGMR3QueryStringDef(pCfg, "ISACompat", achISACompat, sizeof(achISACompat), "Alternate");
     3314    if (RT_FAILURE(rc))
     3315        return PDMDEV_SET_ERROR(pDevIns, rc,
     3316                                N_("BusLogic configuration error: failed to read ISACompat as string"));
     3317    Log(("%s: ISACompat=%s\n", __FUNCTION__, achISACompat));
     3318
     3319    /* Grok the ISACompat setting. */
     3320    if (!strcmp(achISACompat, "Disabled"))
     3321        pThis->uDefaultISABaseCode = ISA_BASE_DISABLED;
     3322    else if (!strcmp(achISACompat, "Primary"))
     3323        pThis->uDefaultISABaseCode = 0;     /* I/O base at 330h. */
     3324    else if (!strcmp(achISACompat, "Alternate"))
     3325        pThis->uDefaultISABaseCode = 1;     /* I/O base at 334h. */
     3326    else
     3327        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     3328                                N_("BusLogic configuration error: invalid ISACompat setting"));
    31963329
    31973330    pThis->pDevInsR3 = pDevIns;
     
    32163349
    32173350    /*
    3218      * Register the PCI device, it's I/O regions.
     3351     * Register the PCI device and its I/O regions.
    32193352     */
    32203353    rc = PDMDevHlpPCIRegister (pDevIns, &pThis->dev);
     
    32323365    if (fBootable)
    32333366    {
    3234         /* Register I/O port space in ISA region for BIOS access. */
     3367        /* Register I/O port space for BIOS access. */
    32353368        rc = PDMDevHlpIOPortRegister(pDevIns, BUSLOGIC_BIOS_IO_PORT, 3, NULL,
    32363369                                     buslogicBIOSIOPortWrite, buslogicBIOSIOPortRead,
     
    32383371                                     "BusLogic BIOS");
    32393372        if (RT_FAILURE(rc))
    3240             return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register legacy I/O handlers"));
    3241     }
     3373            return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register BIOS I/O handlers"));
     3374    }
     3375
     3376    /* Set up the compatibility I/O range. */
     3377    rc = buslogicRegisterISARange(pThis, pThis->uDefaultISABaseCode);
     3378    if (RT_FAILURE(rc))
     3379        return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register ISA I/O handlers"));
    32423380
    32433381    /* Initialize task cache. */
     
    33243462        return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register save state handlers"));
    33253463
    3326     rc = buslogicHwReset(pThis);
     3464    rc = buslogicHwReset(pThis, true);
    33273465    AssertMsgRC(rc, ("hardware reset of BusLogic host adapter failed rc=%Rrc\n", rc));
    33283466
     
    33893527#endif /* IN_RING3 */
    33903528#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    3391 
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