VirtualBox

Changeset 25380 in vbox


Ignore:
Timestamp:
Dec 14, 2009 9:44:14 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56004
Message:

LsiLogic: Don't assert when not reading 4 byte from a register. A SCSI Linux driver scans the range for a device before the controller is nitialized

File:
1 edited

Legend:

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

    r24265 r25380  
    27102710{
    27112711    uint32_t u32 = *(uint32_t *)pv;
    2712     AssertMsg(cb == 4, ("cb != 4 is %d\n", cb));
    27132712
    27142713    LogFlowFunc(("pThis=%#p uOffset=%#x pv=%#p{%.*Rhxs} cb=%u\n", pThis, uOffset, pv, cb, pv, cb));
     
    29082907static int lsilogicRegisterRead(PLSILOGICSCSI pThis, uint32_t uOffset, void *pv, unsigned cb)
    29092908{
    2910     uint32_t *pu32 = (uint32_t *)pv;
    2911     AssertMsg(cb == 4, ("cb != 4 is %d\n", cb));
    2912 
    2913     switch (uOffset)
     2909    uint32_t u32 = 0;
     2910
     2911    /* Align to a 4 byte offset. */
     2912    switch (uOffset & ~3)
    29142913    {
    29152914        case LSILOGIC_REG_REPLY_QUEUE:
    29162915        {
     2916            /*
     2917             * Non 4-byte access may cause real strange behavior because the data is part of a physical guest address.
     2918             * But some drivers use 1-byte access to scan for SCSI controllers.
     2919             */
     2920            if (RT_UNLIKELY(cb != 4))
     2921                LogFlowFunc((": cb is not 4 (%u)\n", cb));
     2922
    29172923            if (pThis->uReplyPostQueueNextEntryFreeWrite != pThis->uReplyPostQueueNextAddressRead)
    29182924            {
    2919                 *pu32 = pThis->CTX_SUFF(pReplyPostQueueBase)[pThis->uReplyPostQueueNextAddressRead];
     2925                u32 = pThis->CTX_SUFF(pReplyPostQueueBase)[pThis->uReplyPostQueueNextAddressRead];
    29202926                pThis->uReplyPostQueueNextAddressRead++;
    29212927                pThis->uReplyPostQueueNextAddressRead %= pThis->cReplyQueueEntries;
     
    29242930            {
    29252931                /* The reply post queue is empty. Reset interrupt. */
    2926                 *pu32 = UINT32_C(0xffffffff);
     2932                u32 = UINT32_C(0xffffffff);
    29272933                lsilogicClearInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_REPLY_INTR);
    29282934            }
    2929             Log(("%s: Returning address %#x\n", __FUNCTION__, *pu32));
     2935            Log(("%s: Returning address %#x\n", __FUNCTION__, u32));
    29302936            break;
    29312937        }
    29322938        case LSILOGIC_REG_DOORBELL:
    29332939        {
    2934             *pu32  = LSILOGIC_REG_DOORBELL_SET_STATE(pThis->enmState);
    2935             *pu32 |= LSILOGIC_REG_DOORBELL_SET_USED(pThis->fDoorbellInProgress);
    2936             *pu32 |= LSILOGIC_REG_DOORBELL_SET_WHOINIT(pThis->enmWhoInit);
     2940            u32  = LSILOGIC_REG_DOORBELL_SET_STATE(pThis->enmState);
     2941            u32 |= LSILOGIC_REG_DOORBELL_SET_USED(pThis->fDoorbellInProgress);
     2942            u32 |= LSILOGIC_REG_DOORBELL_SET_WHOINIT(pThis->enmWhoInit);
    29372943            /*
    29382944             * If there is a doorbell function in progress we pass the return value
     
    29432949            {
    29442950                /* Return next 16bit value. */
    2945                 *pu32 |= pThis->ReplyBuffer.au16Reply[pThis->uNextReplyEntryRead++];
     2951                u32 |= pThis->ReplyBuffer.au16Reply[pThis->uNextReplyEntryRead++];
    29462952            }
    29472953            else
    29482954            {
    29492955                /* We return the status code of the I/O controller. */
    2950                 *pu32 |= pThis->u16IOCFaultCode;
     2956                u32 |= pThis->u16IOCFaultCode;
    29512957            }
    29522958            break;
     
    29542960        case LSILOGIC_REG_HOST_INTR_STATUS:
    29552961        {
    2956             *pu32 = pThis->uInterruptStatus;
     2962            u32 = pThis->uInterruptStatus;
    29572963            break;
    29582964        }
    29592965        case LSILOGIC_REG_HOST_INTR_MASK:
    29602966        {
    2961             *pu32 = pThis->uInterruptMask;
    2962             break;
    2963         }
    2964         case LSILOGIC_REG_HOST_DIAGNOSTIC:
    2965         {
    2966             //AssertMsgFailed(("todo\n"));
    2967             break;
    2968         }
     2967            u32 = pThis->uInterruptMask;
     2968            break;
     2969        }
     2970        case LSILOGIC_REG_HOST_DIAGNOSTIC: /* The spec doesn't say anything about these registers, so we just ignore them */
    29692971        case LSILOGIC_REG_TEST_BASE_ADDRESS:
    2970         {
    2971             AssertMsgFailed(("todo\n"));
    2972             break;
    2973         }
    29742972        case LSILOGIC_REG_DIAG_RW_DATA:
    2975         {
    2976             AssertMsgFailed(("todo\n"));
    2977             break;
    2978         }
    29792973        case LSILOGIC_REG_DIAG_RW_ADDRESS:
    2980         {
    2981             AssertMsgFailed(("todo\n"));
    2982             break;
    2983         }
    29842974        default: /* Ignore. */
    29852975        {
    29862976            break;
    29872977        }
     2978    }
     2979
     2980    /* Clip data according to the read size. */
     2981    switch (cb)
     2982    {
     2983        case 4:
     2984        {
     2985            *(uint32_t *)pv = u32;
     2986            break;
     2987        }
     2988        case 2:
     2989        {
     2990            uint8_t uRegOff = uOffset - (uOffset & 3);
     2991
     2992            u32 = u32 & (0xffff << uRegOff);
     2993            *(uint16_t *)pv = u32 >> uRegOff;
     2994            break;
     2995        }
     2996        case 1:
     2997        {
     2998            uint8_t uRegOff = uOffset - (uOffset & 3);
     2999
     3000            u32 = u32 & (0xff << uRegOff);
     3001            *(uint8_t *)pv = u32 >> uRegOff;
     3002            break;
     3003        }
     3004        default:
     3005            AssertMsgFailed(("Invalid access size %u\n", cb));
    29883006    }
    29893007
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