Changeset 36030 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Feb 21, 2011 11:26:58 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 70138
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
r35768 r36030 16 16 */ 17 17 18 /* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]). 18 /* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]). 19 19 * See also: http://www.drdobbs.com/184410111 20 20 */ … … 406 406 R3PTRTYPE(volatile PBUSLOGICTASKSTATE) pTasksRedoHead; 407 407 408 #ifdef LOG_ENABLED 409 # if HC_ARCH_BITS == 64 410 uint32_t Alignment4; 411 # endif 412 413 volatile uint32_t cInMailboxesReady; 414 #endif 415 408 416 } BUSLOGIC, *PBUSLOGIC; 409 417 … … 817 825 818 826 #if defined(IN_RING3) 827 828 /** 829 * Advances the mailbox pointer to the next slot. 830 */ 831 DECLINLINE(void) buslogicOutgoingMailboxAdvance(PBUSLOGIC pBusLogic) 832 { 833 pBusLogic->uMailboxOutgoingPositionCurrent = (pBusLogic->uMailboxOutgoingPositionCurrent + 1) % pBusLogic->cMailbox; 834 } 835 836 /** 837 * Returns the physical address of the next outgoing mailbox to process. 838 */ 839 DECLINLINE(RTGCPHYS) buslogicOutgoingMailboxGetGCPhys(PBUSLOGIC pBusLogic) 840 { 841 return pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox)); 842 } 843 819 844 /** 820 845 * Initialize local RAM of host adapter with default values. … … 944 969 RTGCPHYS GCPhysAddrCCB = (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB; 945 970 971 LogFlowFunc(("Completing CCB %RGp\n", GCPhysAddrCCB)); 972 946 973 /* Update CCB. */ 947 974 pTaskState->CommandControlBlockGuest.uHostAdapterStatus = uHostAdapterStatus; … … 949 976 PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB, &pTaskState->CommandControlBlockGuest, sizeof(CommandControlBlock)); 950 977 978 #ifdef RT_STRICT 979 Mailbox Tmp; 980 PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &Tmp, sizeof(Mailbox)); 981 Assert(Tmp.u.in.uCompletionCode == BUSLOGIC_MAILBOX_INCOMING_COMPLETION_FREE); 982 #endif 983 951 984 /* Update mailbox. */ 952 985 PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &pTaskState->MailboxGuest, sizeof(Mailbox)); … … 956 989 if (pBusLogic->uMailboxIncomingPositionCurrent >= pBusLogic->cMailbox) 957 990 pBusLogic->uMailboxIncomingPositionCurrent = 0; 991 992 #ifdef LOG_ENABLED 993 ASMAtomicIncU32(&pBusLogic->cInMailboxesReady); 994 #endif 958 995 959 996 pBusLogic->regInterrupt |= BUSLOGIC_REGISTER_INTERRUPT_INCOMING_MAILBOX_LOADED; … … 1611 1648 if (rc != VINF_SUCCESS) 1612 1649 return rc; 1650 1651 #ifdef LOG_ENABLED 1652 uint32_t cMailboxesReady = ASMAtomicXchgU32(&pBusLogic->cInMailboxesReady, 0); 1653 Log(("%u incoming mailboxes are ready when this interrupt was cleared\n", cMailboxesReady)); 1654 #endif 1613 1655 1614 1656 if (uVal & BUSLOGIC_REGISTER_CONTROL_INTERRUPT_RESET) … … 2279 2321 if (!pBusLogic->fStrictRoundRobinMode) 2280 2322 { 2281 /* Search for a filled mailbox. */ 2323 /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ 2324 uint8_t uMailboxPosCur = pBusLogic->uMailboxOutgoingPositionCurrent; 2325 2282 2326 do 2283 2327 { 2284 2328 /* Fetch mailbox from guest memory. */ 2285 GCPhysAddrMailboxCurrent = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox));2329 GCPhysAddrMailboxCurrent = buslogicOutgoingMailboxGetGCPhys(pBusLogic); 2286 2330 2287 2331 PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent, 2288 2332 &pTaskState->MailboxGuest, sizeof(Mailbox)); 2289 2333 2290 pBusLogic->uMailboxOutgoingPositionCurrent++; 2291 2292 /* Check if we reached the end and start from the beginning if so. */ 2293 if (pBusLogic->uMailboxOutgoingPositionCurrent >= pBusLogic->cMailbox) 2294 pBusLogic->uMailboxOutgoingPositionCurrent = 0; 2295 } while (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE); 2334 /* Check the next mailbox. */ 2335 buslogicOutgoingMailboxAdvance(pBusLogic); 2336 } while ( pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE 2337 && uMailboxPosCur != pBusLogic->uMailboxOutgoingPositionCurrent); 2296 2338 } 2297 2339 else 2298 2340 { 2299 2341 /* Fetch mailbox from guest memory. */ 2300 GCPhysAddrMailboxCurrent = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox));2342 GCPhysAddrMailboxCurrent = buslogicOutgoingMailboxGetGCPhys(pBusLogic); 2301 2343 2302 2344 PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent, … … 2304 2346 } 2305 2347 2348 /* 2349 * Check if the mailbox is actually loaded. 2350 * It might be possible that the guest notified us without 2351 * a loaded mailbox. Do nothing in that case but leave a 2352 * log entry. 2353 */ 2354 if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE) 2355 { 2356 Log(("No loaded mailbox left\n")); 2357 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2358 return VERR_NO_DATA; 2359 } 2360 2361 LogFlow(("Got loaded mailbox at slot %u, CCB phys %RGp\n", pBusLogic->uMailboxOutgoingPositionCurrent, pTaskState->MailboxGuest.u32PhysAddrCCB)); 2306 2362 #ifdef DEBUG 2307 2363 buslogicDumpMailboxInfo(&pTaskState->MailboxGuest, true); 2308 2364 #endif 2309 2365 2366 /* We got the mailbox, mark it as free in the guest. */ 2367 uint8_t uActionCode = BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE; 2368 PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent + RT_OFFSETOF(Mailbox, u.out.uActionCode), &uActionCode, sizeof(uActionCode)); 2369 2310 2370 if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_START_COMMAND) 2311 2371 rc = buslogicDeviceSCSIRequestSetup(pBusLogic, pTaskState); … … 2319 2379 AssertRC(rc); 2320 2380 2321 /* We got the mailbox, mark it as free in the guest. */ 2322 pTaskState->MailboxGuest.u.out.uActionCode = BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE; 2323 PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent, &pTaskState->MailboxGuest, sizeof(Mailbox)); 2324 2381 /* Advance to the next mailbox. */ 2325 2382 if (pBusLogic->fStrictRoundRobinMode) 2326 { 2327 pBusLogic->uMailboxOutgoingPositionCurrent++; 2328 2329 /* Check if we reached the end and start from the beginning if so. */ 2330 if (pBusLogic->uMailboxOutgoingPositionCurrent >= pBusLogic->cMailbox) 2331 pBusLogic->uMailboxOutgoingPositionCurrent = 0; 2332 } 2383 buslogicOutgoingMailboxAdvance(pBusLogic); 2333 2384 2334 2385 return rc; … … 2347 2398 { 2348 2399 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2349 uint32_t cMailboxesReady = 0;2350 2400 2351 2401 /* Reset notification send flag now. */ 2352 2402 Assert(pBusLogic->fNotificationSend); 2353 2403 ASMAtomicXchgBool(&pBusLogic->fNotificationSend, false); 2354 2355 /* 2356 * It is possible that there is a notification send but that there is no mailbox ready 2357 * in the SMP case. Just do nothing. 2358 */ 2359 cMailboxesReady = ASMAtomicXchgU32(&pBusLogic->cMailboxesReady, 0); 2360 if (!cMailboxesReady) 2361 return true; 2404 ASMAtomicXchgU32(&pBusLogic->cMailboxesReady, 0); /* @todo: Actually not required anymore but to stay compatible with older saved states. */ 2362 2405 2363 2406 /* Process mailboxes. */ 2407 int rc; 2364 2408 do 2365 2409 { 2366 int rc;2367 2368 2410 rc = buslogicProcessMailboxNext(pBusLogic); 2369 AssertMsg RC(rc, ("Processing mailbox failed rc=%Rrc\n", rc));2370 } while ( --cMailboxesReady > 0);2411 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NO_DATA, ("Processing mailbox failed rc=%Rrc\n", rc)); 2412 } while (RT_SUCCESS(rc)); 2371 2413 2372 2414 return true;
Note:
See TracChangeset
for help on using the changeset viewer.