Changeset 33274 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Oct 20, 2010 5:54:35 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 66842
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
r33101 r33274 59 59 60 60 /** State saved version. */ 61 #define BUSLOGIC_SAVED_STATE_MINOR_VERSION 1 61 #define BUSLOGIC_SAVED_STATE_MINOR_VERSION 2 62 63 /** Saved state version before the suspend on error feature was implemented. */ 64 #define BUSLOGIC_SAVED_STATE_MINOR_PRE_ERROR_HANDLING 1 62 65 63 66 /** … … 259 262 #pragma pack() 260 263 264 /** Pointer to a task state structure. */ 265 typedef struct BUSLOGICTASKSTATE *PBUSLOGICTASKSTATE; 266 261 267 /** 262 268 * Main BusLogic device state. … … 391 397 * a port is entering the idle state. */ 392 398 bool volatile fSignalIdle; 399 /** Flag whether we have tasks which need to be processed again- */ 400 bool volatile fRedo; 401 /** List of tasks which can be redone. */ 402 R3PTRTYPE(volatile PBUSLOGICTASKSTATE) pTasksRedoHead; 393 403 394 404 } BUSLOGIC, *PBUSLOGIC; … … 737 747 typedef struct BUSLOGICTASKSTATE 738 748 { 749 /** Next in the redo list. */ 750 PBUSLOGICTASKSTATE pRedoNext; 739 751 /** Device this task is assigned to. */ 740 752 R3PTRTYPE(PBUSLOGICDEVICE) pTargetDeviceR3; … … 751 763 /** Flag whether this is a request from the BIOS. */ 752 764 bool fBIOS; 753 } BUSLOGICTASKSTATE , *PBUSLOGICTASKSTATE;765 } BUSLOGICTASKSTATE; 754 766 755 767 #ifndef VBOX_DEVICE_STRUCT_TESTCASE … … 1816 1828 } 1817 1829 1830 static void buslogicWarningDiskFull(PPDMDEVINS pDevIns) 1831 { 1832 int rc; 1833 LogRel(("BusLogic#%d: Host disk full\n", pDevIns->iInstance)); 1834 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevBusLogic_DISKFULL", 1835 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space")); 1836 AssertRC(rc); 1837 } 1838 1839 static void buslogicWarningFileTooBig(PPDMDEVINS pDevIns) 1840 { 1841 int rc; 1842 LogRel(("BusLogic#%d: File too big\n", pDevIns->iInstance)); 1843 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevBusLogic_FILETOOBIG", 1844 N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files")); 1845 AssertRC(rc); 1846 } 1847 1848 static void buslogicWarningISCSI(PPDMDEVINS pDevIns) 1849 { 1850 int rc; 1851 LogRel(("BusLogic#%d: iSCSI target unavailable\n", pDevIns->iInstance)); 1852 rc = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevBusLogic_ISCSIDOWN", 1853 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again")); 1854 AssertRC(rc); 1855 } 1856 1857 static void buslogicWarningUnknown(PPDMDEVINS pDevIns, int rc) 1858 { 1859 int rc2; 1860 LogRel(("BusLogic#%d: Unknown but recoverable error has occurred (rc=%Rrc)\n", pDevIns->iInstance, rc)); 1861 rc2 = PDMDevHlpVMSetRuntimeError(pDevIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DevBusLogic_UNKNOWN", 1862 N_("An unknown but recoverable I/O error has occurred (rc=%Rrc). VM execution is suspended. You can resume when the error is fixed"), rc); 1863 AssertRC(rc2); 1864 } 1865 1866 static void buslogicRedoSetWarning(PBUSLOGIC pThis, int rc) 1867 { 1868 if (rc == VERR_DISK_FULL) 1869 buslogicWarningDiskFull(pThis->CTX_SUFF(pDevIns)); 1870 else if (rc == VERR_FILE_TOO_BIG) 1871 buslogicWarningFileTooBig(pThis->CTX_SUFF(pDevIns)); 1872 else if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED) 1873 { 1874 /* iSCSI connection abort (first error) or failure to reestablish 1875 * connection (second error). Pause VM. On resume we'll retry. */ 1876 buslogicWarningISCSI(pThis->CTX_SUFF(pDevIns)); 1877 } 1878 else 1879 buslogicWarningUnknown(pThis->CTX_SUFF(pDevIns), rc); 1880 } 1881 1882 1818 1883 static int buslogicPrepareBIOSSCSIRequest(PBUSLOGIC pBusLogic) 1819 1884 { … … 2025 2090 LogFlowFunc(("after decrement %u\n", pBusLogicDevice->cOutstandingRequests)); 2026 2091 2027 if (pTaskState->fBIOS) 2028 { 2029 rc = vboxscsiRequestFinished(&pBusLogic->VBoxSCSI, pSCSIRequest); 2030 AssertMsgRC(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc)); 2092 if (fRedo) 2093 { 2094 if (!pTaskState->fBIOS) 2095 { 2096 buslogicDataBufferFree(pTaskState); 2097 2098 if (pTaskState->pbSenseBuffer) 2099 buslogicSenseBufferFree(pTaskState, false /* fCopy */); 2100 } 2101 2102 /* Add to the list. */ 2103 do 2104 { 2105 pTaskState->pRedoNext = ASMAtomicReadPtrT(&pBusLogic->pTasksRedoHead, PBUSLOGICTASKSTATE); 2106 } while (!ASMAtomicCmpXchgPtr(&pBusLogic->pTasksRedoHead, pTaskState, pTaskState->pRedoNext)); 2107 2108 /* Suspend the VM if not done already. */ 2109 if (!ASMAtomicXchgBool(&pBusLogic->fRedo, true)) 2110 buslogicRedoSetWarning(pBusLogic, rcReq); 2031 2111 } 2032 2112 else 2033 2113 { 2034 buslogicDataBufferFree(pTaskState); 2035 2036 if (pTaskState->pbSenseBuffer) 2037 buslogicSenseBufferFree(pTaskState, (rcCompletion != SCSI_STATUS_OK)); 2038 2039 buslogicSendIncomingMailbox(pBusLogic, pTaskState, 2040 BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_CMD_COMPLETED, 2041 BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD, 2042 BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITHOUT_ERROR); 2043 } 2044 2045 /* Add task to the cache. */ 2046 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2114 if (pTaskState->fBIOS) 2115 { 2116 rc = vboxscsiRequestFinished(&pBusLogic->VBoxSCSI, pSCSIRequest); 2117 AssertMsgRC(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc)); 2118 } 2119 else 2120 { 2121 buslogicDataBufferFree(pTaskState); 2122 2123 if (pTaskState->pbSenseBuffer) 2124 buslogicSenseBufferFree(pTaskState, (rcCompletion != SCSI_STATUS_OK)); 2125 2126 buslogicSendIncomingMailbox(pBusLogic, pTaskState, 2127 BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_CMD_COMPLETED, 2128 BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD, 2129 BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITHOUT_ERROR); 2130 } 2131 2132 /* Add task to the cache. */ 2133 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2134 } 2047 2135 2048 2136 if (pBusLogicDevice->cOutstandingRequests == 0 && pBusLogic->fSignalIdle) … … 2050 2138 2051 2139 return VINF_SUCCESS; 2140 } 2141 2142 static int buslogicDeviceSCSIRequestSetup(PBUSLOGIC pBusLogic, PBUSLOGICTASKSTATE pTaskState) 2143 { 2144 int rc = VINF_SUCCESS; 2145 2146 /* Fetch CCB. */ 2147 RTGCPHYS GCPhysAddrCCB = (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB; 2148 PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB, 2149 &pTaskState->CommandControlBlockGuest, sizeof(CommandControlBlock)); 2150 2151 PBUSLOGICDEVICE pTargetDevice = &pBusLogic->aDeviceStates[pTaskState->CommandControlBlockGuest.uTargetId]; 2152 pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice; 2153 2154 #ifdef DEBUG 2155 buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest); 2156 #endif 2157 2158 /* Alloc required buffers. */ 2159 rc = buslogicDataBufferAlloc(pTaskState); 2160 AssertMsgRC(rc, ("Alloc failed rc=%Rrc\n", rc)); 2161 2162 if (pTaskState->CommandControlBlockGuest.cbSenseData) 2163 { 2164 rc = buslogicSenseBufferAlloc(pTaskState); 2165 AssertMsgRC(rc, ("Mapping sense buffer failed rc=%Rrc\n", rc)); 2166 } 2167 2168 /* Check if device is present on bus. If not return error immediately and don't process this further. */ 2169 if (!pBusLogic->aDeviceStates[pTaskState->CommandControlBlockGuest.uTargetId].fPresent) 2170 { 2171 buslogicDataBufferFree(pTaskState); 2172 2173 if (pTaskState->pbSenseBuffer) 2174 buslogicSenseBufferFree(pTaskState, true); 2175 2176 buslogicSendIncomingMailbox(pBusLogic, pTaskState, 2177 BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_SCSI_SELECTION_TIMEOUT, 2178 BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD, 2179 BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITH_ERROR); 2180 2181 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2182 } 2183 else 2184 { 2185 /* Setup SCSI request. */ 2186 pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->CommandControlBlockGuest.uLogicalUnit; 2187 2188 if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN) 2189 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_UNKNOWN; 2190 else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN) 2191 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_FROM_DEVICE; 2192 else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT) 2193 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_TO_DEVICE; 2194 else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_NO_DATA) 2195 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_NONE; 2196 else 2197 AssertMsgFailed(("Invalid data direction type %d\n", pTaskState->CommandControlBlockGuest.uDataDirection)); 2198 2199 pTaskState->PDMScsiRequest.cbCDB = pTaskState->CommandControlBlockGuest.cbCDB; 2200 pTaskState->PDMScsiRequest.pbCDB = pTaskState->CommandControlBlockGuest.aCDB; 2201 if (pTaskState->DataSeg.cbSeg) 2202 { 2203 pTaskState->PDMScsiRequest.cbScatterGather = pTaskState->DataSeg.cbSeg; 2204 pTaskState->PDMScsiRequest.cScatterGatherEntries = 1; 2205 pTaskState->PDMScsiRequest.paScatterGatherHead = &pTaskState->DataSeg; 2206 } 2207 else 2208 { 2209 pTaskState->PDMScsiRequest.cbScatterGather = 0; 2210 pTaskState->PDMScsiRequest.cScatterGatherEntries = 0; 2211 pTaskState->PDMScsiRequest.paScatterGatherHead = NULL; 2212 } 2213 pTaskState->PDMScsiRequest.cbSenseBuffer = pTaskState->CommandControlBlockGuest.cbSenseData; 2214 pTaskState->PDMScsiRequest.pbSenseBuffer = pTaskState->pbSenseBuffer; 2215 pTaskState->PDMScsiRequest.pvUser = pTaskState; 2216 2217 ASMAtomicIncU32(&pTargetDevice->cOutstandingRequests); 2218 rc = pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTargetDevice->pDrvSCSIConnector, &pTaskState->PDMScsiRequest); 2219 AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc)); 2220 } 2221 2222 return rc; 2052 2223 } 2053 2224 … … 2101 2272 2102 2273 if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_START_COMMAND) 2103 { 2104 /* Fetch CCB now. */ 2105 RTGCPHYS GCPhysAddrCCB = (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB; 2106 PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB, 2107 &pTaskState->CommandControlBlockGuest, sizeof(CommandControlBlock)); 2108 2109 PBUSLOGICDEVICE pTargetDevice = &pBusLogic->aDeviceStates[pTaskState->CommandControlBlockGuest.uTargetId]; 2110 pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice; 2111 2112 #ifdef DEBUG 2113 buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest); 2114 #endif 2115 2116 /* Alloc required buffers. */ 2117 rc = buslogicDataBufferAlloc(pTaskState); 2118 AssertMsgRC(rc, ("Alloc failed rc=%Rrc\n", rc)); 2119 2120 if (pTaskState->CommandControlBlockGuest.cbSenseData) 2121 { 2122 rc = buslogicSenseBufferAlloc(pTaskState); 2123 AssertMsgRC(rc, ("Mapping sense buffer failed rc=%Rrc\n", rc)); 2124 } 2125 2126 /* Check if device is present on bus. If not return error immediately and don't process this further. */ 2127 if (!pBusLogic->aDeviceStates[pTaskState->CommandControlBlockGuest.uTargetId].fPresent) 2128 { 2129 buslogicDataBufferFree(pTaskState); 2130 2131 if (pTaskState->pbSenseBuffer) 2132 buslogicSenseBufferFree(pTaskState, true); 2133 2134 buslogicSendIncomingMailbox(pBusLogic, pTaskState, 2135 BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_SCSI_SELECTION_TIMEOUT, 2136 BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD, 2137 BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITH_ERROR); 2138 2139 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2140 } 2141 else 2142 { 2143 /* Setup SCSI request. */ 2144 pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->CommandControlBlockGuest.uLogicalUnit; 2145 2146 if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN) 2147 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_UNKNOWN; 2148 else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN) 2149 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_FROM_DEVICE; 2150 else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT) 2151 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_TO_DEVICE; 2152 else if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_NO_DATA) 2153 pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_NONE; 2154 else 2155 AssertMsgFailed(("Invalid data direction type %d\n", pTaskState->CommandControlBlockGuest.uDataDirection)); 2156 2157 pTaskState->PDMScsiRequest.cbCDB = pTaskState->CommandControlBlockGuest.cbCDB; 2158 pTaskState->PDMScsiRequest.pbCDB = pTaskState->CommandControlBlockGuest.aCDB; 2159 if (pTaskState->DataSeg.cbSeg) 2160 { 2161 pTaskState->PDMScsiRequest.cbScatterGather = pTaskState->DataSeg.cbSeg; 2162 pTaskState->PDMScsiRequest.cScatterGatherEntries = 1; 2163 pTaskState->PDMScsiRequest.paScatterGatherHead = &pTaskState->DataSeg; 2164 } 2165 else 2166 { 2167 pTaskState->PDMScsiRequest.cbScatterGather = 0; 2168 pTaskState->PDMScsiRequest.cScatterGatherEntries = 0; 2169 pTaskState->PDMScsiRequest.paScatterGatherHead = NULL; 2170 } 2171 pTaskState->PDMScsiRequest.cbSenseBuffer = pTaskState->CommandControlBlockGuest.cbSenseData; 2172 pTaskState->PDMScsiRequest.pbSenseBuffer = pTaskState->pbSenseBuffer; 2173 pTaskState->PDMScsiRequest.pvUser = pTaskState; 2174 2175 LogFlowFunc(("before increment %u\n", pTargetDevice->cOutstandingRequests)); 2176 ASMAtomicIncU32(&pTargetDevice->cOutstandingRequests); 2177 LogFlowFunc(("after increment %u\n", pTargetDevice->cOutstandingRequests)); 2178 rc = pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTargetDevice->pDrvSCSIConnector, &pTaskState->PDMScsiRequest); 2179 AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc)); 2180 } 2181 } 2274 rc = buslogicDeviceSCSIRequestSetup(pBusLogic, pTaskState); 2182 2275 else if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_ABORT_COMMAND) 2183 2276 { … … 2186 2279 else 2187 2280 AssertMsgFailed(("Invalid outgoing mailbox action code %u\n", pTaskState->MailboxGuest.u.out.uActionCode)); 2281 2282 AssertRC(rc); 2188 2283 2189 2284 /* We got the mailbox, mark it as free in the guest. */ … … 2231 2326 2232 2327 return true; 2328 } 2329 2330 /** 2331 * Kicks the controller to process pending tasks after the VM was resumed 2332 * or loaded from a saved state. 2333 * 2334 * @returns nothing. 2335 * @param pThis The LsiLogic device instance. 2336 */ 2337 static void buslogicKick(PBUSLOGIC pThis) 2338 { 2339 if (pThis->fRedo) 2340 { 2341 pThis->fRedo = false; 2342 if (pThis->VBoxSCSI.fBusy) 2343 { 2344 2345 /* The BIOS had a request active when we got suspended. Resume it. */ 2346 int rc = buslogicPrepareBIOSSCSIRequest(pThis); 2347 AssertRC(rc); 2348 } 2349 else 2350 { 2351 /* Queue all pending tasks again. */ 2352 PBUSLOGICTASKSTATE pTaskState = pThis->pTasksRedoHead; 2353 2354 pThis->pTasksRedoHead = NULL; 2355 2356 while (pTaskState) 2357 { 2358 PBUSLOGICTASKSTATE pCur = pTaskState; 2359 2360 int rc = buslogicDeviceSCSIRequestSetup(pThis, pCur); 2361 AssertRC(rc); 2362 2363 pTaskState = pTaskState->pRedoNext; 2364 } 2365 } 2366 } 2233 2367 } 2234 2368 … … 2293 2427 SSMR3PutBool (pSSM, pBusLogic->VBoxSCSI.fBusy); 2294 2428 SSMR3PutU8 (pSSM, pBusLogic->VBoxSCSI.enmState); 2295 if (pBusLogic->VBoxSCSI.cb CDB)2429 if (pBusLogic->VBoxSCSI.cbBuf) 2296 2430 SSMR3PutMem(pSSM, pBusLogic->VBoxSCSI.pBuf, pBusLogic->VBoxSCSI.cbBuf); 2297 2431 2432 /* 2433 * Save the physical addresses of the command control blocks of still pending tasks. 2434 * They are processed again on resume. 2435 * 2436 * The number of pending tasks needs to be determined first. 2437 */ 2438 uint32_t cTasks = 0; 2439 2440 PBUSLOGICTASKSTATE pTaskState = pBusLogic->pTasksRedoHead; 2441 if (pBusLogic->fRedo) 2442 { 2443 while (pTaskState) 2444 { 2445 cTasks++; 2446 pTaskState = pTaskState->pRedoNext; 2447 } 2448 } 2449 SSMR3PutU32(pSSM, cTasks); 2450 2451 /* Write the address of every task now. */ 2452 pTaskState = pBusLogic->pTasksRedoHead; 2453 while (pTaskState) 2454 { 2455 SSMR3PutU32(pSSM, pTaskState->MailboxGuest.u32PhysAddrCCB); 2456 pTaskState = pTaskState->pRedoNext; 2457 } 2458 2298 2459 return SSMR3PutU32(pSSM, ~0); 2299 2460 } 2300 2461 2462 static DECLCALLBACK(int) buslogicLoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 2463 { 2464 PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2465 2466 buslogicKick(pThis); 2467 return VINF_SUCCESS; 2468 } 2469 2301 2470 static DECLCALLBACK(int) buslogicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 2302 2471 { 2303 2472 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2304 int rc ;2473 int rc = VINF_SUCCESS; 2305 2474 2306 2475 /* We support saved states only from this and older versions. */ … … 2363 2532 SSMR3GetBool(pSSM, (bool *)&pBusLogic->VBoxSCSI.fBusy); 2364 2533 SSMR3GetU8 (pSSM, (uint8_t *)&pBusLogic->VBoxSCSI.enmState); 2365 if (pBusLogic->VBoxSCSI.cb CDB)2366 { 2367 pBusLogic->VBoxSCSI.pBuf = (uint8_t *)RTMemAllocZ(pBusLogic->VBoxSCSI.cb CDB);2534 if (pBusLogic->VBoxSCSI.cbBuf) 2535 { 2536 pBusLogic->VBoxSCSI.pBuf = (uint8_t *)RTMemAllocZ(pBusLogic->VBoxSCSI.cbBuf); 2368 2537 if (!pBusLogic->VBoxSCSI.pBuf) 2369 2538 { … … 2375 2544 } 2376 2545 2377 uint32_t u32; 2378 rc = SSMR3GetU32(pSSM, &u32); 2379 if (RT_FAILURE(rc)) 2380 return rc; 2381 AssertMsgReturn(u32 == ~0U, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 2382 2383 return VINF_SUCCESS; 2546 if (pBusLogic->VBoxSCSI.fBusy) 2547 pBusLogic->fRedo = true; 2548 2549 if (uVersion > BUSLOGIC_SAVED_STATE_MINOR_PRE_ERROR_HANDLING) 2550 { 2551 /* Check if there are pending tasks saved. */ 2552 uint32_t cTasks = 0; 2553 2554 SSMR3GetU32(pSSM, &cTasks); 2555 2556 if (cTasks) 2557 pBusLogic->fRedo = true; 2558 2559 for (uint32_t i = 0; i < cTasks; i++) 2560 { 2561 PBUSLOGICTASKSTATE pTaskState = (PBUSLOGICTASKSTATE)RTMemCacheAlloc(pBusLogic->hTaskCache); 2562 if (!pTaskState) 2563 { 2564 rc = VERR_NO_MEMORY; 2565 break; 2566 } 2567 2568 rc = SSMR3GetU32(pSSM, &pTaskState->MailboxGuest.u32PhysAddrCCB); 2569 if (RT_FAILURE(rc)) 2570 { 2571 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2572 break; 2573 } 2574 2575 /* Link into the list. */ 2576 pTaskState->pRedoNext = pBusLogic->pTasksRedoHead; 2577 pBusLogic->pTasksRedoHead = pTaskState; 2578 } 2579 } 2580 2581 if (RT_SUCCESS(rc)) 2582 { 2583 uint32_t u32; 2584 rc = SSMR3GetU32(pSSM, &u32); 2585 if (RT_SUCCESS(rc)) 2586 AssertMsgReturn(u32 == ~0U, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 2587 } 2588 2589 return rc; 2384 2590 } 2385 2591 … … 2494 2700 * Common worker for ahciR3Suspend and ahciR3PowerOff. 2495 2701 */ 2496 static void buslogicR3SuspendOrPowerOff(PPDMDEVINS pDevIns )2702 static void buslogicR3SuspendOrPowerOff(PPDMDEVINS pDevIns, bool fPowerOff) 2497 2703 { 2498 2704 PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC); … … 2502 2708 PDMDevHlpSetAsyncNotification(pDevIns, buslogicR3IsAsyncSuspendOrPowerOffDone); 2503 2709 else 2710 { 2504 2711 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 2712 2713 AssertMsg(!pThis->fNotificationSend, ("The PDM Queue should be empty at this point\n")); 2714 2715 if (pThis->fRedo) 2716 { 2717 if (fPowerOff) 2718 { 2719 /* Free tasks which would have been queued again on resume. */ 2720 PBUSLOGICTASKSTATE pTaskState = pThis->pTasksRedoHead; 2721 2722 pThis->pTasksRedoHead = NULL; 2723 2724 while (pTaskState) 2725 { 2726 PBUSLOGICTASKSTATE pFree; 2727 2728 pFree = pTaskState; 2729 pTaskState = pTaskState->pRedoNext; 2730 2731 RTMemCacheFree(pThis->hTaskCache, pFree); 2732 } 2733 pThis->fRedo = false; 2734 } 2735 else if (pThis->VBoxSCSI.fBusy) 2736 { 2737 /* Destroy the task because the BIOS interface has all necessary information. */ 2738 Assert(pThis->pTasksRedoHead->fBIOS); 2739 Assert(!pThis->pTasksRedoHead->pRedoNext); 2740 2741 RTMemCacheFree(pThis->hTaskCache, pThis->pTasksRedoHead); 2742 pThis->pTasksRedoHead = NULL; 2743 } 2744 } 2745 } 2505 2746 } 2506 2747 … … 2513 2754 { 2514 2755 Log(("buslogicSuspend\n")); 2515 buslogicR3SuspendOrPowerOff(pDevIns); 2516 } 2756 buslogicR3SuspendOrPowerOff(pDevIns, false /* fPoweroff */); 2757 } 2758 2759 /** 2760 * Resume notification. 2761 * 2762 * @param pDevIns The device instance data. 2763 */ 2764 static DECLCALLBACK(void) buslogicResume(PPDMDEVINS pDevIns) 2765 { 2766 Log(("buslogicResume\n")); 2767 PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2768 buslogicKick(pThis); 2769 } 2770 2517 2771 2518 2772 /** … … 2652 2906 { 2653 2907 Log(("buslogicPowerOff\n")); 2654 buslogicR3SuspendOrPowerOff(pDevIns );2908 buslogicR3SuspendOrPowerOff(pDevIns, true /* fPoweroff */); 2655 2909 } 2656 2910 … … 2669 2923 2670 2924 PDMR3CritSectDelete(&pThis->CritSectIntr); 2925 2926 /* 2927 * Free all tasks which are still hanging around 2928 * (Power off after the VM was suspended). 2929 */ 2930 if (pThis->fRedo) 2931 { 2932 /* Free tasks which would have been queued again on resume. */ 2933 PBUSLOGICTASKSTATE pTaskState = pThis->pTasksRedoHead; 2934 2935 pThis->pTasksRedoHead = NULL; 2936 2937 while (pTaskState) 2938 { 2939 PBUSLOGICTASKSTATE pFree; 2940 2941 pFree = pTaskState; 2942 pTaskState = pTaskState->pRedoNext; 2943 2944 RTMemCacheFree(pThis->hTaskCache, pFree); 2945 } 2946 pThis->fRedo = false; 2947 } 2671 2948 2672 2949 int rc = RTMemCacheDestroy(pThis->hTaskCache); … … 2825 3102 } 2826 3103 2827 rc = PDMDevHlpSSMRegister3(pDevIns, BUSLOGIC_SAVED_STATE_MINOR_VERSION, sizeof(*pThis), 2828 buslogicLiveExec, buslogicSaveExec, buslogicLoadExec); 3104 rc = PDMDevHlpSSMRegisterEx(pDevIns, BUSLOGIC_SAVED_STATE_MINOR_VERSION, sizeof(*pThis), NULL, 3105 NULL, buslogicLiveExec, NULL, 3106 NULL, buslogicSaveExec, NULL, 3107 NULL, buslogicLoadExec, buslogicLoadDone); 2829 3108 if (RT_FAILURE(rc)) 2830 3109 return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register save state handlers")); … … 2875 3154 buslogicSuspend, 2876 3155 /* pfnResume */ 2877 NULL,3156 buslogicResume, 2878 3157 /* pfnAttach */ 2879 3158 buslogicAttach, -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r33210 r33274 1554 1554 GEN_CHECK_OFF(BUSLOGIC, pLedsConnector); 1555 1555 GEN_CHECK_OFF(BUSLOGIC, fSignalIdle); 1556 GEN_CHECK_OFF(BUSLOGIC, fRedo); 1557 GEN_CHECK_OFF(BUSLOGIC, pTasksRedoHead); 1556 1558 #endif /* VBOX_WITH_BUSLOGIC */ 1557 1559
Note:
See TracChangeset
for help on using the changeset viewer.