VirtualBox

Changeset 44207 in vbox for trunk/src


Ignore:
Timestamp:
Dec 27, 2012 2:52:09 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
82974
Message:

BusLogic: Added 24-bit mailbox support.

File:
1 edited

Legend:

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

    r44206 r44207  
    6262
    6363/** State saved version. */
    64 #define BUSLOGIC_SAVED_STATE_MINOR_VERSION 2
     64#define BUSLOGIC_SAVED_STATE_MINOR_VERSION 3
    6565
    6666/** Saved state version before the suspend on error feature was implemented. */
    6767#define BUSLOGIC_SAVED_STATE_MINOR_PRE_ERROR_HANDLING 1
    68 
    69 /** The duration of software-initiated reset. Not documented, set to 500 ms. */
    70 #define BUSLOGIC_RESET_DURATION_NS      (500*1000*1000UL)
     68/** Saved state version before 24-bit mailbox support was implemented. */
     69#define BUSLOGIC_SAVED_STATE_MINOR_PRE_24BIT_MBOX     2
     70
     71/** The duration of software-initiated reset. Not documented, set to 50 ms. */
     72#define BUSLOGIC_RESET_DURATION_NS      (50*1000*1000UL)
    7173
    7274/**
     
    268270AssertCompileSize(HostAdapterLocalRam, 256);
    269271
     272
     273/* Ugly 24-bit big-endian addressing. */
     274typedef struct {
     275    uint8_t hi;
     276    uint8_t mid;
     277    uint8_t lo;
     278} Addr24, Len24;
     279AssertCompileSize(Addr24, 3);
     280
     281#define ADDR_TO_U32(x)      (((x).hi << 16) | ((x).mid << 8) | (x).lo)
     282#define LEN_TO_U32          ADDR_TO_U32
     283#define U32_TO_ADDR(a, x)   do {(a).hi = (x) >> 16; (a).mid = (x) >> 8; (a).lo = (x);} while(0)
     284#define U32_TO_LEN          U32_TO_ADDR
     285
    270286/* Compatible ISA base I/O port addresses. Disabled if zero. */
    271287#define NUM_ISA_BASES       8
     
    526542    uint8_t uTimeOffBus;
    527543    uint8_t cMailbox;
    528     uint8_t MailboxAddress[3];
     544    Addr24  MailboxAddress;
    529545    ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8];
    530546    uint8_t uDisconnectPermittedId0To7;
     
    579595#pragma pack()
    580596
     597/* Structure for the INITIALIZE MAILBOX request. */
     598typedef struct
     599{
     600    /** Number of mailboxes to set up. */
     601    uint8_t     cMailbox;
     602    /** Physical address of the first mailbox. */
     603    Addr24      aMailboxBaseAddr;
     604} RequestInitMbx, *PRequestInitMbx;
     605AssertCompileSize(RequestInitMbx, 4);
     606
    581607/*
    582608 * Structure of a mailbox in guest memory.
     
    589615 * We use one structure for both types.
    590616 */
    591 #pragma pack(1)
    592 typedef struct Mailbox
     617typedef struct Mailbox32
    593618{
    594619    /** Physical address of the CCB structure in the guest memory. */
     
    618643        } in;
    619644    } u;
    620 } Mailbox, *PMailbox;
    621 AssertCompileSize(Mailbox, 8);
    622 #pragma pack()
     645} Mailbox32, *PMailbox32;
     646AssertCompileSize(Mailbox32, 8);
     647
     648/* Old style 24-bit mailbox entry. */
     649typedef struct Mailbox24
     650{
     651    /** Mailbox command (incoming) or state (outgoing). */
     652    uint8_t     uCmdState;
     653    /** Physical address of the CCB structure in the guest memory. */
     654    Addr24      aPhysAddrCCB;
     655} Mailbox24, *PMailbox24;
     656AssertCompileSize(Mailbox24, 4);
    623657
    624658/*
     
    714748 * The command control block for a SCSI request.
    715749 */
    716 #pragma pack(1)
    717 typedef struct CommandControlBlock
     750typedef struct CCB32
    718751{
    719752    /** Opcode. */
     
    757790    /** Sense data pointer. */
    758791    uint32_t      u32PhysAddrSenseData;
    759 } CommandControlBlock, *PCommandControlBlock;
    760 AssertCompileSize(CommandControlBlock, 40);
    761 #pragma pack()
    762 
    763 #pragma pack(1)
    764 typedef struct ScatterGatherEntry
     792} CCB32, *PCCB32;
     793AssertCompileSize(CCB32, 40);
     794
     795
     796/*
     797 * The 24-bit command control block.
     798 */
     799typedef struct CCB24
     800{
     801    /** Opcode. */
     802    uint8_t         uOpcode;
     803    /** The LUN in the device. */
     804    unsigned char   uLogicalUnit:   3;
     805    /** Data direction for the request. */
     806    unsigned char   uDataDirection: 2;
     807    /** The target device ID. */
     808    unsigned char   uTargetId:      3;
     809    /** Length of the SCSI CDB. */
     810    uint8_t         cbCDB;
     811    /** Sense data length. */
     812    uint8_t         cbSenseData;
     813    /** Data length. */
     814    Len24           acbData;
     815    /** Data pointer.
     816     *  This points to the data region or a scatter gather list based on the opc
     817     */
     818    Addr24          aPhysAddrData;
     819    /** Pointer to next CCB for linked commands. */
     820    Addr24          aPhysAddrLink;
     821    /** Command linking identifier. */
     822    uint8_t         uLinkId;
     823    /** Host adapter status. */
     824    uint8_t         uHostAdapterStatus;
     825    /** Device adapter status. */
     826    uint8_t         uDeviceStatus;
     827    /** Two unused bytes. */
     828    uint8_t         aReserved[2];
     829    /** The SCSI CDB. */
     830    uint8_t         aCDB[12]; /* A CDB can be 12 bytes long. */
     831} CCB24, *PCCB24;
     832AssertCompileSize(CCB24, 30);
     833
     834/*
     835 * The common 24-bit/32-bit command control block. The 32-bit CCB is laid out
     836 * such that many fields are in the same location as in the older 24-bit CCB.
     837 */
     838typedef struct CCBC
     839{
     840    /** Opcode. */
     841    uint8_t         uOpcode;
     842    /** The LUN in the device. */
     843    unsigned char   uPad1:          3;
     844    /** Data direction for the request. */
     845    unsigned char   uDataDirection: 2;
     846    /** The target device ID. */
     847    unsigned char   uPad2:          3;
     848    /** Length of the SCSI CDB. */
     849    uint8_t         cbCDB;
     850    /** Sense data length. */
     851    uint8_t         cbSenseData;
     852    uint8_t         aPad1[10];
     853    /** Host adapter status. */
     854    uint8_t         uHostAdapterStatus;
     855    /** Device adapter status. */
     856    uint8_t         uDeviceStatus;
     857    uint8_t         aPad2[2];
     858    /** The SCSI CDB (up to 12 bytes). */
     859    uint8_t         aCDB[12];
     860} CCBC, *PCCBC;
     861AssertCompileSize(CCB24, 30);
     862
     863/* Make sure that the 24-bit/32-bit/common CCB offsets match. */
     864AssertCompileMemberOffset(CCBC,  cbCDB, 2);
     865AssertCompileMemberOffset(CCB24, cbCDB, 2);
     866AssertCompileMemberOffset(CCB32, cbCDB, 2);
     867AssertCompileMemberOffset(CCBC,  uHostAdapterStatus, 14);
     868AssertCompileMemberOffset(CCB24, uHostAdapterStatus, 14);
     869AssertCompileMemberOffset(CCB32, uHostAdapterStatus, 14);
     870AssertCompileMemberOffset(CCBC,  aCDB, 18);
     871AssertCompileMemberOffset(CCB24, aCDB, 18);
     872AssertCompileMemberOffset(CCB32, aCDB, 18);
     873
     874/* A union of all CCB types (24-bit/32-bit/common). */
     875typedef union CCBU {
     876    CCB32    n;     /* New 32-bit CCB. */
     877    CCB24    o;     /* Old 24-bit CCB. */
     878    CCBC     c;     /* Common CCB subset. */
     879} CCBU, *PCCBU;
     880
     881/* 32-bit scatter-gather list entry. */
     882typedef struct SGE32
    765883{
    766884    uint32_t   cbSegment;
    767885    uint32_t   u32PhysAddrSegmentBase;
    768 } ScatterGatherEntry, *PScatterGatherEntry;
    769 AssertCompileSize(ScatterGatherEntry, 8);
    770 #pragma pack()
     886} SGE32, *PSGE32;
     887AssertCompileSize(SGE32, 8);
     888
     889/* 24-bit scatter-gather list entry. */
     890typedef struct SGE24
     891{
     892    Len24       acbSegment;
     893    Addr24      aPhysAddrSegmentBase;
     894} SGE24, *PSGE24;
     895AssertCompileSize(SGE24, 6);
     896
     897/*
     898 * The structure for the "Execute SCSI Command" command.
     899 */
     900typedef struct ESCMD
     901{
     902    /** Data length. */
     903    uint32_t        cbData;
     904    /** Data pointer. */
     905    uint32_t        u32PhysAddrData;
     906    /** The device the request is sent to. */
     907    uint8_t         uTargetId;
     908    /** The LUN in the device. */
     909    uint8_t         uLogicalUnit;
     910    /** Reserved */
     911    unsigned char   uReserved1:     3;
     912    /** Data direction for the request. */
     913    unsigned char   uDataDirection: 2;
     914    /** Reserved */
     915    unsigned char   uReserved2:     3;
     916    /** Length of the SCSI CDB. */
     917    uint8_t         cbCDB;
     918    /** The SCSI CDB. */
     919    uint8_t         aCDB[12]; /* A CDB can be 12 bytes long. */
     920} ESCMD, *PESCMD;
     921AssertCompileSize(ESCMD, 24);
    771922
    772923/*
     
    780931    R3PTRTYPE(PBUSLOGICDEVICE)     pTargetDeviceR3;
    781932    /** The command control block from the guest. */
    782     CommandControlBlock CommandControlBlockGuest;
     933    CCBU                CommandControlBlockGuest;
    783934    /** Mailbox read from guest memory. */
    784     Mailbox             MailboxGuest;
     935    Mailbox32           MailboxGuest;
    785936    /** The SCSI request we pass to the underlying SCSI engine. */
    786937    PDMSCSIREQUEST      PDMScsiRequest;
     
    791942    /** Flag whether this is a request from the BIOS. */
    792943    bool                fBIOS;
     944    /** 24-bit request flag (default is 32-bit). */
     945    bool                fIs24Bit;
     946    /** S/G entry size (depends on the above flag). */
     947    uint8_t             cbSGEntry;
    793948} BUSLOGICTASKSTATE;
    794949
     
    8631018{
    8641019    pBusLogic->uMailboxOutgoingPositionCurrent = (pBusLogic->uMailboxOutgoingPositionCurrent + 1) % pBusLogic->cMailbox;
    865 }
    866 
    867 /**
    868  * Returns the physical address of the next outgoing mailbox to process.
    869  */
    870 DECLINLINE(RTGCPHYS) buslogicOutgoingMailboxGetGCPhys(PBUSLOGIC pBusLogic)
    871 {
    872     return pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox));
    8731020}
    8741021
     
    9761123    LogFlowFunc(("pBusLogic=%#p fHardReset=%d\n", pBusLogic, fHardReset));
    9771124
    978     buslogicHwReset(pBusLogic, fHardReset);
     1125    buslogicHwReset(pBusLogic, false);
    9791126
    9801127    if (fHardReset)
     
    10091156    int rc = PDMCritSectEnter(&pBusLogic->CritSectIntr, VINF_SUCCESS);
    10101157    AssertRC(rc);
    1011     RTGCPHYS GCPhysAddrMailboxIncoming = pBusLogic->GCPhysAddrMailboxIncomingBase + (pBusLogic->uMailboxIncomingPositionCurrent * sizeof(Mailbox));
    1012     RTGCPHYS GCPhysAddrCCB = (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB;
    1013 
    1014     LogFlowFunc(("Completing CCB %RGp\n", GCPhysAddrCCB));
     1158    RTGCPHYS GCPhysAddrMailboxIncoming;
     1159    RTGCPHYS GCPhysAddrCCB = pTaskState->MailboxGuest.u32PhysAddrCCB;
     1160
     1161    GCPhysAddrMailboxIncoming = pBusLogic->GCPhysAddrMailboxIncomingBase + (pBusLogic->uMailboxIncomingPositionCurrent * (pTaskState->fIs24Bit ? sizeof(Mailbox24) : sizeof(Mailbox32)));
     1162    LogFlowFunc(("Completing CCB %RGp hstat=%u, dstat=%u, outgoing mailbox at %RGp\n", GCPhysAddrCCB,
     1163                 uHostAdapterStatus, uDeviceStatus, GCPhysAddrMailboxIncoming));
    10151164
    10161165    /* Update CCB. */
    1017     pTaskState->CommandControlBlockGuest.uHostAdapterStatus = uHostAdapterStatus;
    1018     pTaskState->CommandControlBlockGuest.uDeviceStatus = uDeviceStatus;
     1166    pTaskState->CommandControlBlockGuest.c.uHostAdapterStatus = uHostAdapterStatus;
     1167    pTaskState->CommandControlBlockGuest.c.uDeviceStatus      = uDeviceStatus;
    10191168    /* @todo: this is wrong - writing too much! */
    1020     PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB, &pTaskState->CommandControlBlockGuest, sizeof(CommandControlBlock));
     1169    PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB, &pTaskState->CommandControlBlockGuest, sizeof(CCBC));
    10211170
    10221171#ifdef RT_STRICT
    1023     Mailbox Tmp;
    1024     PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &Tmp, sizeof(Mailbox));
    1025     Assert(Tmp.u.in.uCompletionCode == BUSLOGIC_MAILBOX_INCOMING_COMPLETION_FREE);
     1172    uint8_t     uCode;
     1173    unsigned    uCodeOffs = pTaskState->fIs24Bit ? RT_OFFSETOF(Mailbox24, uCmdState) : RT_OFFSETOF(Mailbox32, u.out.uActionCode);
     1174    PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming + uCodeOffs, &uCode, sizeof(uCode));
     1175    Assert(uCode == BUSLOGIC_MAILBOX_INCOMING_COMPLETION_FREE);
    10261176#endif
    10271177
    10281178    /* Update mailbox. */
    1029     PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &pTaskState->MailboxGuest, sizeof(Mailbox));
     1179    if (pTaskState->fIs24Bit)
     1180    {
     1181        Mailbox24   Mbx24;
     1182
     1183        Mbx24.uCmdState = pTaskState->MailboxGuest.u.in.uCompletionCode;
     1184        U32_TO_ADDR(Mbx24.aPhysAddrCCB, pTaskState->MailboxGuest.u32PhysAddrCCB);
     1185        Log(("24-bit mailbox: completion code=%u, CCB at %RGp\n", Mbx24.uCmdState, (RTGCPHYS)ADDR_TO_U32(Mbx24.aPhysAddrCCB)));
     1186        PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &Mbx24, sizeof(Mailbox24));
     1187    }
     1188    else
     1189    {
     1190        Log(("32-bit mailbox: completion code=%u, CCB at %RGp\n", pTaskState->MailboxGuest.u.in.uCompletionCode, (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB));
     1191        PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &pTaskState->MailboxGuest, sizeof(Mailbox32));
     1192    }
    10301193
    10311194    /* Advance to next mailbox position. */
     
    10521215 *                    false if dumping the incoming state.
    10531216 */
    1054 static void buslogicDumpMailboxInfo(PMailbox pMailbox, bool fOutgoing)
     1217static void buslogicDumpMailboxInfo(PMailbox32 pMailbox, bool fOutgoing)
    10551218{
    10561219    Log(("%s: Dump for %s mailbox:\n", __FUNCTION__, fOutgoing ? "outgoing" : "incoming"));
     
    10721235 *
    10731236 * @returns nothing.
    1074  * @param   pCCB    Pointer to the command control block to dump.
    1075  */
    1076 static void buslogicDumpCCBInfo(PCommandControlBlock pCCB)
    1077 {
    1078     Log(("%s: Dump for Command Control Block:\n", __FUNCTION__));
    1079     Log(("%s: uOpCode=%#x\n", __FUNCTION__, pCCB->uOpcode));
    1080     Log(("%s: uDataDirection=%u\n", __FUNCTION__, pCCB->uDataDirection));
    1081     Log(("%s: fTagQueued=%d\n", __FUNCTION__, pCCB->fTagQueued));
    1082     Log(("%s: uQueueTag=%u\n", __FUNCTION__, pCCB->uQueueTag));
    1083     Log(("%s: cbCDB=%u\n", __FUNCTION__, pCCB->cbCDB));
    1084     Log(("%s: cbSenseData=%u\n", __FUNCTION__, pCCB->cbSenseData));
    1085     Log(("%s: cbData=%u\n", __FUNCTION__, pCCB->cbData));
    1086     Log(("%s: u32PhysAddrData=%#x\n", __FUNCTION__, pCCB->u32PhysAddrData));
    1087     Log(("%s: uHostAdapterStatus=%u\n", __FUNCTION__, pCCB->uHostAdapterStatus));
    1088     Log(("%s: uDeviceStatus=%u\n", __FUNCTION__, pCCB->uDeviceStatus));
    1089     Log(("%s: uTargetId=%u\n", __FUNCTION__, pCCB->uTargetId));
    1090     Log(("%s: uLogicalUnit=%u\n", __FUNCTION__, pCCB->uLogicalUnit));
    1091     Log(("%s: fLegacyTagEnable=%u\n", __FUNCTION__, pCCB->fLegacyTagEnable));
    1092     Log(("%s: uLegacyQueueTag=%u\n", __FUNCTION__, pCCB->uLegacyQueueTag));
    1093     Log(("%s: uCDB[0]=%#x\n", __FUNCTION__, pCCB->aCDB[0]));
    1094     for (int i = 1; i < pCCB->cbCDB; i++)
    1095         Log(("%s: uCDB[%d]=%u\n", __FUNCTION__, i, pCCB->aCDB[i]));
    1096     Log(("%s: u32PhysAddrSenseData=%#x\n", __FUNCTION__, pCCB->u32PhysAddrSenseData));
     1237 * @param   pCCB            Pointer to the command control block to dump.
     1238 * @param   fIs24BitCCB     Flag to determine CCB format.
     1239 */
     1240static void buslogicDumpCCBInfo(PCCBU pCCB, bool fIs24BitCCB)
     1241{
     1242    Log(("%s: Dump for %s Command Control Block:\n", __FUNCTION__, fIs24BitCCB ? "24-bit" : "32-bit"));
     1243    Log(("%s: uOpCode=%#x\n", __FUNCTION__, pCCB->c.uOpcode));
     1244    Log(("%s: uDataDirection=%u\n", __FUNCTION__, pCCB->c.uDataDirection));
     1245    Log(("%s: cbCDB=%u\n", __FUNCTION__, pCCB->c.cbCDB));
     1246    Log(("%s: cbSenseData=%u\n", __FUNCTION__, pCCB->c.cbSenseData));
     1247    Log(("%s: uHostAdapterStatus=%u\n", __FUNCTION__, pCCB->c.uHostAdapterStatus));
     1248    Log(("%s: uDeviceStatus=%u\n", __FUNCTION__, pCCB->c.uDeviceStatus));
     1249    if (fIs24BitCCB)
     1250    {
     1251        Log(("%s: cbData=%u\n", __FUNCTION__, LEN_TO_U32(pCCB->o.acbData)));
     1252        Log(("%s: PhysAddrData=%#x\n", __FUNCTION__, ADDR_TO_U32(pCCB->o.aPhysAddrData)));
     1253        Log(("%s: uTargetId=%u\n", __FUNCTION__, pCCB->o.uTargetId));
     1254        Log(("%s: uLogicalUnit=%u\n", __FUNCTION__, pCCB->o.uLogicalUnit));
     1255    }
     1256    else
     1257    {
     1258        Log(("%s: cbData=%u\n", __FUNCTION__, pCCB->n.cbData));
     1259        Log(("%s: PhysAddrData=%#x\n", __FUNCTION__, pCCB->n.u32PhysAddrData));
     1260        Log(("%s: uTargetId=%u\n", __FUNCTION__, pCCB->n.uTargetId));
     1261        Log(("%s: uLogicalUnit=%u\n", __FUNCTION__, pCCB->n.uLogicalUnit));
     1262        Log(("%s: fTagQueued=%d\n", __FUNCTION__, pCCB->n.fTagQueued));
     1263        Log(("%s: uQueueTag=%u\n", __FUNCTION__, pCCB->n.uQueueTag));
     1264        Log(("%s: fLegacyTagEnable=%u\n", __FUNCTION__, pCCB->n.fLegacyTagEnable));
     1265        Log(("%s: uLegacyQueueTag=%u\n", __FUNCTION__, pCCB->n.uLegacyQueueTag));
     1266        Log(("%s: PhysAddrSenseData=%#x\n", __FUNCTION__, pCCB->n.u32PhysAddrSenseData));
     1267    }
     1268    Log(("%s: uCDB[0]=%#x\n", __FUNCTION__, pCCB->c.aCDB[0]));
     1269    for (int i = 1; i < pCCB->c.cbCDB; i++)
     1270        Log(("%s: uCDB[%d]=%u\n", __FUNCTION__, i, pCCB->c.aCDB[i]));
    10971271}
    10981272#endif
     1273
     1274/**
     1275 * Allocate data buffer.
     1276 *
     1277 * @param   pTaskState    Pointer to the task state.
     1278 * @param   GCSGList      Guest physical address of S/G list.
     1279 * @param   cEntries      Number of list entries to read.
     1280 * @param   pSGEList      Pointer to 32-bit S/G list storage.
     1281 */
     1282
     1283static void buslogicReadSGEntries(PBUSLOGICTASKSTATE pTaskState, RTGCPHYS GCSGList, uint32_t cEntries, SGE32 *pSGEList)
     1284{
     1285    PPDMDEVINS  pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
     1286    SGE24       aSGE24[32];
     1287    Assert(cEntries <= RT_ELEMENTS(aSGE24));
     1288
     1289    /* Read the S/G entries. Convert 24-bit entries to 32-bit format. */
     1290    if (pTaskState->fIs24Bit)
     1291    {
     1292        Log2(("Converting %u 24-bit S/G entries to 32-bit\n", cEntries));
     1293        PDMDevHlpPhysRead(pDevIns, GCSGList, &aSGE24, cEntries * sizeof(SGE24));
     1294        for (unsigned i = 0; i < cEntries; ++i)
     1295        {
     1296            pSGEList[i].cbSegment              = LEN_TO_U32(aSGE24[i].acbSegment);
     1297            pSGEList[i].u32PhysAddrSegmentBase = ADDR_TO_U32(aSGE24[i].aPhysAddrSegmentBase);
     1298        }
     1299    }
     1300    else
     1301        PDMDevHlpPhysRead(pDevIns, GCSGList, pSGEList, cEntries * sizeof(SGE32));
     1302}
    10991303
    11001304/**
     
    11071311{
    11081312    PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
    1109 
    1110     if (   (pTaskState->CommandControlBlockGuest.uDataDirection != BUSLOGIC_CCB_DIRECTION_NO_DATA)
    1111         && (pTaskState->CommandControlBlockGuest.cbData > 0))
     1313    uint32_t   cbDataCCB;
     1314    uint32_t   u32PhysAddrCCB;
     1315   
     1316    /* Extract the data length and physical address from the CCB. */
     1317    if (pTaskState->fIs24Bit)
     1318    {
     1319        u32PhysAddrCCB  = ADDR_TO_U32(pTaskState->CommandControlBlockGuest.o.aPhysAddrData);
     1320        cbDataCCB       = LEN_TO_U32(pTaskState->CommandControlBlockGuest.o.acbData);
     1321    }
     1322    else
     1323    {
     1324        u32PhysAddrCCB  = pTaskState->CommandControlBlockGuest.n.u32PhysAddrData;
     1325        cbDataCCB       = pTaskState->CommandControlBlockGuest.n.cbData;
     1326    }
     1327
     1328    if (   (pTaskState->CommandControlBlockGuest.c.uDataDirection != BUSLOGIC_CCB_DIRECTION_NO_DATA)
     1329        && cbDataCCB)
    11121330    {
    11131331        /*
     
    11191337         * scatter gather list which describes the buffer.
    11201338         */
    1121         if (   (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
    1122             || (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
     1339        if (   (pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
     1340            || (pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
    11231341        {
    11241342            uint32_t cScatterGatherGCRead;
    11251343            uint32_t iScatterGatherEntry;
    1126             ScatterGatherEntry aScatterGatherReadGC[32]; /* Number of scatter gather list entries read from guest memory. */
    1127             uint32_t cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
    1128             RTGCPHYS GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
     1344            SGE32    aScatterGatherReadGC[32]; /* A buffer for scatter gather list entries read from guest memory. */
     1345            uint32_t cScatterGatherGCLeft = cbDataCCB / pTaskState->cbSGEntry;
     1346            RTGCPHYS GCPhysAddrScatterGatherCurrent = u32PhysAddrCCB;
    11291347            size_t cbDataToTransfer = 0;
    11301348
     
    11371355                cScatterGatherGCLeft -= cScatterGatherGCRead;
    11381356
    1139                 /* Read the SG entries. */
    1140                 PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
    1141                                     cScatterGatherGCRead * sizeof(ScatterGatherEntry));
     1357                buslogicReadSGEntries(pTaskState, GCPhysAddrScatterGatherCurrent, cScatterGatherGCRead, aScatterGatherReadGC);
    11421358
    11431359                for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
     
    11561372
    11571373                /* Set address to the next entries to read. */
    1158                 GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
     1374                GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * pTaskState->cbSGEntry;
    11591375            } while (cScatterGatherGCLeft > 0);
    11601376
     
    11681384
    11691385            /* Copy the data if needed */
    1170             if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
     1386            if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
    11711387            {
    1172                 cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
    1173                 GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
     1388                cScatterGatherGCLeft = cbDataCCB / pTaskState->cbSGEntry;
     1389                GCPhysAddrScatterGatherCurrent = u32PhysAddrCCB;
    11741390                uint8_t *pbData = (uint8_t *)pTaskState->DataSeg.pvSeg;
    11751391
     
    11811397                    cScatterGatherGCLeft -= cScatterGatherGCRead;
    11821398
    1183                     /* Read the SG entries. */
    1184                     PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
    1185                                         cScatterGatherGCRead * sizeof(ScatterGatherEntry));
     1399                    buslogicReadSGEntries(pTaskState, GCPhysAddrScatterGatherCurrent, cScatterGatherGCRead, aScatterGatherReadGC);
    11861400
    11871401                    for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
     
    12011415
    12021416                    /* Set address to the next entries to read. */
    1203                     GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
     1417                    GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * pTaskState->cbSGEntry;
    12041418                } while (cScatterGatherGCLeft > 0);
    12051419            }
    12061420
    12071421        }
    1208         else if (   pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB
    1209                  || pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_DATA_LENGTH)
     1422        else if (   pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB
     1423                 || pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_DATA_LENGTH)
    12101424        {
    12111425            /* The buffer is not scattered. */
    1212             RTGCPHYS GCPhysAddrDataBase     = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
     1426            RTGCPHYS GCPhysAddrDataBase = u32PhysAddrCCB;
    12131427
    12141428            AssertMsg(GCPhysAddrDataBase != 0, ("Physical address is 0\n"));
    12151429
    1216             pTaskState->DataSeg.cbSeg = pTaskState->CommandControlBlockGuest.cbData;
     1430            pTaskState->DataSeg.cbSeg = cbDataCCB;
    12171431            pTaskState->DataSeg.pvSeg = RTMemAlloc(pTaskState->DataSeg.cbSeg);
    12181432            if (!pTaskState->DataSeg.pvSeg)
     
    12201434
    12211435            Log(("Non scattered buffer:\n"));
    1222             Log(("u32PhysAddrData=%#x\n", pTaskState->CommandControlBlockGuest.u32PhysAddrData));
    1223             Log(("cbData=%u\n", pTaskState->CommandControlBlockGuest.cbData));
     1436            Log(("u32PhysAddrData=%#x\n", u32PhysAddrCCB));
     1437            Log(("cbData=%u\n", cbDataCCB));
    12241438            Log(("GCPhysAddrDataBase=0x%RGp\n", GCPhysAddrDataBase));
    12251439
     
    12411455{
    12421456    PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
    1243 
    1244     if (   (pTaskState->CommandControlBlockGuest.cbData > 0)
    1245         && (  (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
    1246             || (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)))
    1247     {
    1248         if (   (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
    1249             || (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
     1457    uint32_t   cbDataCCB;
     1458    uint32_t   u32PhysAddrCCB;
     1459
     1460    /* Extract the data length and physical address from the CCB. */
     1461    if (pTaskState->fIs24Bit)
     1462    {
     1463        u32PhysAddrCCB  = ADDR_TO_U32(pTaskState->CommandControlBlockGuest.o.aPhysAddrData);
     1464        cbDataCCB       = LEN_TO_U32(pTaskState->CommandControlBlockGuest.o.acbData);
     1465    }
     1466    else
     1467    {
     1468        u32PhysAddrCCB  = pTaskState->CommandControlBlockGuest.n.u32PhysAddrData;
     1469        cbDataCCB       = pTaskState->CommandControlBlockGuest.n.cbData;
     1470    }
     1471
     1472#if 1
     1473    /* Hack for NT 10/91: A CCB describes a 2K buffer, but TEST UNIT READY is executed. This command
     1474     * returns no data, hence the buffer must be left alone!
     1475     */
     1476    if (pTaskState->CommandControlBlockGuest.c.aCDB[0] == 0)
     1477        cbDataCCB = 0;
     1478#endif
     1479
     1480    LogFlowFunc(("pTaskState=%#p cbDataCCB=%u direction=%u cbSeg=%u\n", pTaskState, cbDataCCB,
     1481                 pTaskState->CommandControlBlockGuest.c.uDataDirection, pTaskState->DataSeg.cbSeg));
     1482
     1483    if (   (cbDataCCB > 0)
     1484        && (   (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
     1485            || (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)))
     1486    {
     1487        if (   (pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
     1488            || (pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
    12501489        {
    12511490            uint32_t cScatterGatherGCRead;
    12521491            uint32_t iScatterGatherEntry;
    1253             ScatterGatherEntry aScatterGatherReadGC[32]; /* Number of scatter gather list entries read from guest memory. */
    1254             uint32_t cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
    1255             RTGCPHYS GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
     1492            SGE32    aScatterGatherReadGC[32]; /* Number of scatter gather list entries read from guest memory. */
     1493            uint32_t cScatterGatherGCLeft = cbDataCCB / pTaskState->cbSGEntry;
     1494            RTGCPHYS GCPhysAddrScatterGatherCurrent = u32PhysAddrCCB;
    12561495            uint8_t *pbData = (uint8_t *)pTaskState->DataSeg.pvSeg;
    12571496
     
    12631502                cScatterGatherGCLeft -= cScatterGatherGCRead;
    12641503
    1265                 /* Read the SG entries. */
    1266                 PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
    1267                                     cScatterGatherGCRead * sizeof(ScatterGatherEntry));
     1504                buslogicReadSGEntries(pTaskState, GCPhysAddrScatterGatherCurrent, cScatterGatherGCRead, aScatterGatherReadGC);
    12681505
    12691506                for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
     
    12841521
    12851522                /* Set address to the next entries to read. */
    1286                 GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
     1523                GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * pTaskState->cbSGEntry;
    12871524            } while (cScatterGatherGCLeft > 0);
    12881525
    12891526        }
    1290         else if (   pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB
    1291                  || pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_DATA_LENGTH)
     1527        else if (   pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB
     1528                 || pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_DATA_LENGTH)
    12921529        {
    12931530            /* The buffer is not scattered. */
    1294             RTGCPHYS GCPhysAddrDataBase = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
     1531            RTGCPHYS GCPhysAddrDataBase = u32PhysAddrCCB;
    12951532
    12961533            AssertMsg(GCPhysAddrDataBase != 0, ("Physical address is 0\n"));
    12971534
    12981535            Log(("Non scattered buffer:\n"));
    1299             Log(("u32PhysAddrData=%#x\n", pTaskState->CommandControlBlockGuest.u32PhysAddrData));
    1300             Log(("cbData=%u\n", pTaskState->CommandControlBlockGuest.cbData));
     1536            Log(("u32PhysAddrData=%#x\n", u32PhysAddrCCB));
     1537            Log(("cbData=%u\n", cbDataCCB));
    13011538            Log(("GCPhysAddrDataBase=0x%RGp\n", GCPhysAddrDataBase));
    13021539
     
    13041541            PDMDevHlpPhysWrite(pDevIns, GCPhysAddrDataBase, pTaskState->DataSeg.pvSeg, pTaskState->DataSeg.cbSeg);
    13051542        }
     1543
     1544    }
     1545    /* Update residual data length. */
     1546    if (   (pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_DATA_LENGTH)
     1547        || (pTaskState->CommandControlBlockGuest.c.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
     1548    {
     1549        uint32_t    cbResidual;
     1550
     1551        //@todo: we need to get the actual transfer length from the VSCSI layer?!
     1552        cbResidual = 0; //LEN_TO_U32(pTaskState->CCBGuest.acbData) - ???;
     1553        if (pTaskState->fIs24Bit)
     1554            U32_TO_LEN(pTaskState->CommandControlBlockGuest.o.acbData, cbResidual);
     1555        else
     1556            pTaskState->CommandControlBlockGuest.n.cbData = cbResidual;
    13061557    }
    13071558
     
    13361587    uint32_t    cbSenseBuffer;
    13371588
    1338     cbSenseBuffer = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.cbSenseData);
     1589    cbSenseBuffer = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.c.cbSenseData);
    13391590
    13401591    /* Copy the sense buffer into guest memory if requested. */
     
    13421593    {
    13431594        PPDMDEVINS  pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
    1344         RTGCPHYS GCPhysAddrSenseBuffer = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrSenseData;
     1595        RTGCPHYS    GCPhysAddrSenseBuffer;
     1596
     1597        /* With 32-bit CCBs, the (optional) sense buffer physical address is provided separately.
     1598         * On the other hand, with 24-bit CCBs, the sense buffer is simply located at the end of
     1599         * the CCB, right after the variable-length CDB.
     1600         */
     1601        if (pTaskState->fIs24Bit)
     1602        {           
     1603            GCPhysAddrSenseBuffer  = pTaskState->MailboxGuest.u32PhysAddrCCB;
     1604            GCPhysAddrSenseBuffer += pTaskState->CommandControlBlockGuest.c.cbCDB + RT_OFFSETOF(CCB24, aCDB);
     1605        }
     1606        else
     1607            GCPhysAddrSenseBuffer = pTaskState->CommandControlBlockGuest.n.u32PhysAddrSenseData;
    13451608
    13461609        PDMDevHlpPhysWrite(pDevIns, GCPhysAddrSenseBuffer, pTaskState->pbSenseBuffer, cbSenseBuffer);
     
    13651628    pTaskState->pbSenseBuffer = NULL;
    13661629
    1367     cbSenseBuffer = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.cbSenseData);
     1630    cbSenseBuffer = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.c.cbSenseData);
    13681631    if (cbSenseBuffer)
    13691632    {
     
    15441807            pReply->fParityCheckingEnabled = true;
    15451808            pReply->cMailbox = pBusLogic->cMailbox;
     1809            U32_TO_ADDR(pReply->MailboxAddress, pBusLogic->GCPhysAddrMailboxOutgoingBase);
    15461810            pReply->uSignature = 'B';
    15471811            /* The 'D' signature prevents Adaptec's OS/2 drivers from getting too
     
    15651829            break;
    15661830        }
     1831        case BUSLOGICCOMMAND_INITIALIZE_MAILBOX:
     1832        {
     1833            PRequestInitMbx pRequest = (PRequestInitMbx)pBusLogic->aCommandBuffer;
     1834
     1835            pBusLogic->fMbxIs24Bit = true;
     1836            pBusLogic->cMailbox = pRequest->cMailbox;
     1837            pBusLogic->GCPhysAddrMailboxOutgoingBase = (RTGCPHYS)ADDR_TO_U32(pRequest->aMailboxBaseAddr);
     1838            /* The area for incoming mailboxes is right after the last entry of outgoing mailboxes. */
     1839            pBusLogic->GCPhysAddrMailboxIncomingBase = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->cMailbox * sizeof(Mailbox24));
     1840   
     1841            Log(("GCPhysAddrMailboxOutgoingBase=%RGp\n", pBusLogic->GCPhysAddrMailboxOutgoingBase));
     1842            Log(("GCPhysAddrMailboxIncomingBase=%RGp\n", pBusLogic->GCPhysAddrMailboxIncomingBase));
     1843            Log(("cMailboxes=%u (24-bit mode)\n", pBusLogic->cMailbox));
     1844            LogRel(("Initialized 24-bit mailbox, %d entries at %08x\n", pRequest->cMailbox, ADDR_TO_U32(pRequest->aMailboxBaseAddr)));
     1845   
     1846            pBusLogic->regStatus &= ~BUSLOGIC_REGISTER_STATUS_INITIALIZATION_REQUIRED;
     1847            pBusLogic->cbReplyParametersLeft = 0;
     1848            break;
     1849        }
    15671850        case BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX:
    15681851        {
    15691852            PRequestInitializeExtendedMailbox pRequest = (PRequestInitializeExtendedMailbox)pBusLogic->aCommandBuffer;
    15701853
     1854            pBusLogic->fMbxIs24Bit = false;
    15711855            pBusLogic->cMailbox = pRequest->cMailbox;
    15721856            pBusLogic->GCPhysAddrMailboxOutgoingBase = (RTGCPHYS)pRequest->uMailboxBaseAddress;
    15731857            /* The area for incoming mailboxes is right after the last entry of outgoing mailboxes. */
    1574             pBusLogic->GCPhysAddrMailboxIncomingBase = (RTGCPHYS)pRequest->uMailboxBaseAddress + (pBusLogic->cMailbox * sizeof(Mailbox));
     1858            pBusLogic->GCPhysAddrMailboxIncomingBase = (RTGCPHYS)pRequest->uMailboxBaseAddress + (pBusLogic->cMailbox * sizeof(Mailbox32));
    15751859
    15761860            Log(("GCPhysAddrMailboxOutgoingBase=%RGp\n", pBusLogic->GCPhysAddrMailboxOutgoingBase));
     
    19092193                    case BUSLOGICCOMMAND_FETCH_HOST_ADAPTER_LOCAL_RAM:
    19102194                        pBusLogic->cbCommandParametersLeft = 2;
     2195                        break;
     2196                    case BUSLOGICCOMMAND_INITIALIZE_MAILBOX:
     2197                        pBusLogic->cbCommandParametersLeft = sizeof(RequestInitMbx);
    19112198                        break;
    19122199                    case BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX:
     
    24622749        }
    24632750#ifdef DEBUG
    2464             buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest);
     2751            buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest, pTaskState->fIs24Bit);
    24652752#endif
    24662753
     
    24952782{
    24962783    int rc = VINF_SUCCESS;
     2784    uint8_t uTargetIdCCB;
     2785    PBUSLOGICDEVICE pTargetDevice;
    24972786
    24982787    /* Fetch the CCB from guest memory. */
     2788    //@todo: How much do we really have to read?
    24992789    RTGCPHYS GCPhysAddrCCB = (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB;
    25002790    PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB,
    2501                         &pTaskState->CommandControlBlockGuest, sizeof(CommandControlBlock));
    2502 
    2503     PBUSLOGICDEVICE pTargetDevice = &pBusLogic->aDeviceStates[pTaskState->CommandControlBlockGuest.uTargetId];
     2791                        &pTaskState->CommandControlBlockGuest, sizeof(CCB32));
     2792
     2793    uTargetIdCCB = pTaskState->fIs24Bit ? pTaskState->CommandControlBlockGuest.o.uTargetId : pTaskState->CommandControlBlockGuest.n.uTargetId;
     2794    pTargetDevice = &pBusLogic->aDeviceStates[uTargetIdCCB];
    25042795    pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice;
    25052796
    25062797#ifdef DEBUG
    2507     buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest);
     2798    buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest, pTaskState->fIs24Bit);
    25082799#endif
    25092800
     
    25162807
    25172808    /* Check if device is present on bus. If not return error immediately and don't process this further. */
    2518     if (!pBusLogic->aDeviceStates[pTaskState->CommandControlBlockGuest.uTargetId].fPresent)
     2809    if (!pBusLogic->aDeviceStates[uTargetIdCCB].fPresent)
    25192810    {
    25202811        buslogicDataBufferFree(pTaskState);
     
    25332824    {
    25342825        /* Setup SCSI request. */
    2535         pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->CommandControlBlockGuest.uLogicalUnit;
    2536 
    2537         if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)
     2826        pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->fIs24Bit ? pTaskState->CommandControlBlockGuest.o.uLogicalUnit
     2827                                                                       : pTaskState->CommandControlBlockGuest.n.uLogicalUnit;
     2828
     2829        if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)
    25382830            pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_UNKNOWN;
    2539         else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
     2831        else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
    25402832            pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_FROM_DEVICE;
    2541         else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
     2833        else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
    25422834            pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_TO_DEVICE;
    2543         else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_NO_DATA)
     2835        else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_NO_DATA)
    25442836            pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_NONE;
    25452837        else
    2546             AssertMsgFailed(("Invalid data direction type %d\n", pTaskState->CommandControlBlockGuest.uDataDirection));
    2547 
    2548         pTaskState->PDMScsiRequest.cbCDB                 = pTaskState->CommandControlBlockGuest.cbCDB;
    2549         pTaskState->PDMScsiRequest.pbCDB                 = pTaskState->CommandControlBlockGuest.aCDB;
     2838            AssertMsgFailed(("Invalid data direction type %d\n", pTaskState->CommandControlBlockGuest.c.uDataDirection));
     2839
     2840        pTaskState->PDMScsiRequest.cbCDB                 = pTaskState->CommandControlBlockGuest.c.cbCDB;
     2841        pTaskState->PDMScsiRequest.pbCDB                 = pTaskState->CommandControlBlockGuest.c.aCDB;
    25502842        if (pTaskState->DataSeg.cbSeg)
    25512843        {
     
    25602852            pTaskState->PDMScsiRequest.paScatterGatherHead   = NULL;
    25612853        }
    2562         pTaskState->PDMScsiRequest.cbSenseBuffer         = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.cbSenseData);
     2854        pTaskState->PDMScsiRequest.cbSenseBuffer         = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.c.cbSenseData);
    25632855        pTaskState->PDMScsiRequest.pbSenseBuffer         = pTaskState->pbSenseBuffer;
    25642856        pTaskState->PDMScsiRequest.pvUser                = pTaskState;
     
    25732865
    25742866/**
     2867 * Read a mailbox from guest memory. Convert 24-bit mailboxes to
     2868 * 32-bit format.
     2869 *
     2870 * @returns Mailbox guest physical address.
     2871 * @param   pBusLogic    Pointer to the BusLogic instance data.
     2872 * @param   pTaskStat    Pointer to the task state being set up.
     2873 */
     2874static RTGCPHYS buslogicReadOutgoingMailbox(PBUSLOGIC pBusLogic, PBUSLOGICTASKSTATE pTaskState)
     2875{
     2876    RTGCPHYS    GCMailbox;
     2877
     2878    if (pBusLogic->fMbxIs24Bit)
     2879    {
     2880        Mailbox24   Mbx24;
     2881
     2882        GCMailbox = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox24));
     2883        PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCMailbox, &Mbx24, sizeof(Mailbox24));
     2884        pTaskState->MailboxGuest.u32PhysAddrCCB    = ADDR_TO_U32(Mbx24.aPhysAddrCCB);
     2885        pTaskState->MailboxGuest.u.out.uActionCode = Mbx24.uCmdState;
     2886    }
     2887    else
     2888    {
     2889        GCMailbox = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox32));
     2890        PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCMailbox, &pTaskState->MailboxGuest, sizeof(Mailbox32));
     2891    }
     2892
     2893    return GCMailbox;
     2894}
     2895
     2896/**
    25752897 * Read mailbox from the guest and execute command.
    25762898 *
     
    25872909    AssertMsgReturn(RT_SUCCESS(rc) && (pTaskState != NULL), ("Failed to get task state from cache\n"), rc);
    25882910
    2589     pTaskState->fBIOS = false;
     2911    pTaskState->fBIOS     = false;
     2912    pTaskState->fIs24Bit  = pBusLogic->fMbxIs24Bit;
     2913    pTaskState->cbSGEntry = pBusLogic->fMbxIs24Bit ? sizeof(SGE24) : sizeof(SGE32);
    25902914
    25912915    if (!pBusLogic->fStrictRoundRobinMode)
     
    25972921        {
    25982922            /* Fetch mailbox from guest memory. */
    2599             GCPhysAddrMailboxCurrent = buslogicOutgoingMailboxGetGCPhys(pBusLogic);
    2600 
    2601             PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent,
    2602                               &pTaskState->MailboxGuest, sizeof(Mailbox));
     2923            GCPhysAddrMailboxCurrent = buslogicReadOutgoingMailbox(pBusLogic,pTaskState);
    26032924
    26042925            /* Check the next mailbox. */
     
    26102931    {
    26112932        /* Fetch mailbox from guest memory. */
    2612         GCPhysAddrMailboxCurrent = buslogicOutgoingMailboxGetGCPhys(pBusLogic);
    2613 
    2614         PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent,
    2615                           &pTaskState->MailboxGuest, sizeof(Mailbox));
     2933        GCPhysAddrMailboxCurrent = buslogicReadOutgoingMailbox(pBusLogic,pTaskState);
    26162934    }
    26172935
     
    26362954    /* We got the mailbox, mark it as free in the guest. */
    26372955    uint8_t uActionCode = BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE;
    2638     PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent + RT_OFFSETOF(Mailbox, u.out.uActionCode), &uActionCode, sizeof(uActionCode));
     2956    unsigned uCodeOffs = pTaskState->fIs24Bit ? RT_OFFSETOF(Mailbox24, uCmdState) : RT_OFFSETOF(Mailbox32, u.out.uActionCode);
     2957    PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent + uCodeOffs, &uActionCode, sizeof(uActionCode));
    26392958
    26402959    if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_START_COMMAND)
     
    27653084    SSMR3PutU8    (pSSM, pBusLogic->uISABaseCode);
    27663085    SSMR3PutU32   (pSSM, pBusLogic->cMailbox);
     3086    SSMR3PutBool  (pSSM, pBusLogic->fMbxIs24Bit);
    27673087    SSMR3PutGCPhys(pSSM, pBusLogic->GCPhysAddrMailboxOutgoingBase);
    27683088    SSMR3PutU32   (pSSM, pBusLogic->uMailboxOutgoingPositionCurrent);
     
    28713191    SSMR3GetU8    (pSSM, &pBusLogic->uISABaseCode);
    28723192    SSMR3GetU32   (pSSM, &pBusLogic->cMailbox);
     3193    if (uVersion > BUSLOGIC_SAVED_STATE_MINOR_PRE_24BIT_MBOX)
     3194        SSMR3GetBool  (pSSM, &pBusLogic->fMbxIs24Bit);
    28733195    SSMR3GetGCPhys(pSSM, &pBusLogic->GCPhysAddrMailboxOutgoingBase);
    28743196    SSMR3GetU32   (pSSM, &pBusLogic->uMailboxOutgoingPositionCurrent);
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