Changeset 79928 in vbox
- Timestamp:
- Jul 23, 2019 11:47:38 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 132346
- Location:
- trunk/src/VBox
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Makefile.kmk
r79891 r79928 532 532 VBoxDD_DEFS += VBOX_WITH_VIRTIO_SCSI 533 533 VBoxDD_SOURCES += \ 534 Virtio/Virtio_1_0.cpp \ 534 535 Storage/DevVirtioSCSI.cpp 535 536 endif -
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r79535 r79928 39 39 # include <iprt/uuid.h> 40 40 #endif 41 #include "../VirtIO/Virtio_1_0.h" 42 41 43 #include "VBoxSCSI.h" 42 44 #include "VBoxDD.h" … … 53 55 typedef struct VIRTIOSCSITARGET 54 56 { 57 58 55 59 /** Pointer to the owning virtioScsi device instance. - R3 pointer */ 56 60 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsiR3; 57 61 /** Pointer to the owning virtioScsi device instance. - R0 pointer */ 62 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsiR0; 58 63 /** Pointer to the owning virtioScsi device instance. - RC pointer */ 59 RCPTRTYPE(struct VIRTIOSCSI *) pVirtioScsiRC; 60 61 /** Pointer to the attached driver's base interface. */ 62 R3PTRTYPE(PPDMIBASE) pDrvBase; 64 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsiRC; 65 66 /** Pointer to attached driver's base interface. */ 67 R3PTRTYPE(PPDMIBASE) pUpstreamDrvBase; 68 69 /** LUN of the device. */ 70 RTUINT iLUN; 63 71 64 72 /** Our base interface. */ 65 PDMIBASE IBase; 66 67 /** LUN of the device. */ 68 RTUINT iLUN; 73 PDMIBASE IBase; 69 74 70 75 /** Flag whether device is present. */ 71 bool fPresent;76 bool fPresent; 72 77 73 78 /** Media port interface. */ 74 PDMIMEDIAPORT IMediaPort; 79 PDMIMEDIAPORT IMediaPort; 80 75 81 /** Extended media port interface. */ 76 PDMIMEDIAEXPORT IMediaExPort; 77 /** Led interface. */ 78 PDMILEDPORTS ILed; 79 80 /** The status LED state for this device. */ 81 PDMLED Led; 82 PDMIMEDIAEXPORT IMediaExPort; 82 83 83 84 /** Number of outstanding tasks on the port. */ 84 volatile uint32_t cOutstandingRequests; 85 86 } VIRTIOSCSITARGET; 87 typedef VIRTIOSCSITARGET *PVIRTIOSCSITARGET; 85 volatile uint32_t cOutstandingRequests; 86 87 /** LUN Description */ 88 char * pszLunName; 89 90 /** Pointer to the attached driver's media interface. */ 91 R3PTRTYPE(PPDMIMEDIA) pDrvMedia; 92 93 /** Pointer to the attached driver's extended media interface. */ 94 R3PTRTYPE(PPDMIMEDIAEX) pDrvMediaEx; 95 96 R3PTRTYPE(PVQUEUE) pCtlQueue; // ? TBD 97 R3PTRTYPE(PVQUEUE) pEvtQueue; // ? TBD 98 R3PTRTYPE(PVQUEUE) pReqQueue; // ? TBD 99 100 } VIRTIOSCSITARGET, *PVIRTIOSCSITARGET; 88 101 89 102 … … 92 105 * 93 106 * @extends PDMPCIDEV 94 * @implements PDMILEDPORTS95 107 */ 96 108 typedef struct VIRTIOSCSI 97 109 { 98 110 99 VIRTIOSCSITARGET aTargetInstances[VIRTIOSCSI_MAX_TARGETS]; 100 101 /** The PCI device structure. */ 102 PDMPCIDEV dev; 103 /** Pointer to the device instance - HC ptr */ 104 PPDMDEVINSR3 pDevInsR3; 105 /** Pointer to the device instance - R0 ptr */ 106 PPDMDEVINSR0 pDevInsR0; 107 /** Pointer to the device instance - RC ptr. */ 108 PPDMDEVINSRC pDevInsRC; 111 PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */ 112 PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */ 113 PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */ 114 115 /* virtioState must be first member */ 116 VIRTIOSTATE virtioState; 117 118 /* SCSI target instances data */ 119 VIRTIOSCSITARGET aTargetInstances[VIRTIOSCSI_MAX_TARGETS]; 120 121 /** Base address of the I/O ports. */ 122 RTIOPORT IOPortBase; 123 124 /** Base address of the memory mapping. */ 125 RTGCPHYS GCPhysMMIOBase; 126 127 /** IMediaExPort: Media ejection notification */ 128 R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify; 109 129 110 130 /** Queue to send tasks to R3. - HC ptr */ 111 131 R3PTRTYPE(PPDMQUEUE) pNotifierQueueR3; 112 /** Queue to send tasks to R3. - HC ptr */113 R0PTRTYPE(PPDMQUEUE) pNotifierQueueR0;114 /** Queue to send tasks to R3. - RC ptr */115 RCPTRTYPE(PPDMQUEUE) pNotifierQueueRC;116 132 117 133 /** The support driver session handle. */ 118 134 R3R0PTRTYPE(PSUPDRVSESSION) pSupDrvSession; 135 119 136 /** Worker thread. */ 120 137 R3PTRTYPE(PPDMTHREAD) pThreadWrk; 138 121 139 /** The event semaphore the processing thread waits on. */ 122 140 SUPSEMEVENT hEvtProcess; 123 141 124 /** The base interface.125 * @todo use PDMDEVINS::IBase */126 PDMIBASE IBase;127 128 /** Whether R0 is enabled. */129 bool fR0Enabled;130 /** Whether RC is enabled. */131 bool fGCEnabled;132 142 /** Number of ports detected */ 133 143 uint64_t cTargets; 134 144 135 /** Base address of the I/O ports. */ 136 RTIOPORT IOPortBase; 137 138 /** Base address of the memory mapping. */ 139 RTGCPHYS MMIOBase; 140 141 /** Status LUN: Media Notifys. */ 142 R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify; 143 144 /** Partner of ILeds. */ 145 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector; 146 147 /** Indicates that PDMDevHlpAsyncNotificationCompleted should be called when 148 * a port is entering the idle state. */ 145 /** True if PDMDevHlpAsyncNotificationCompleted should be called when port goes idle */ 149 146 bool volatile fSignalIdle; 150 147 … … 152 149 153 150 151 152 //pk: Needed for virtioIO (e.g. to talk to devSCSI? TBD ?? 154 153 /** 155 154 * Task state for a CCB request. … … 174 173 typedef struct VIRTIOSCSIREQ *PVIRTIOSCSIREQ; 175 174 175 176 176 #define VIRTIOSCSI_SAVED_STATE_MINOR_VERSION 0x01 177 178 #define PCI_VENDOR_ID_VIRTIO 0x1AF4 179 #define PCI_DEVICE_ID_VIRTIO_SCSI_HOST 0x1048 180 #define PCI_CLASS_BASE_MASS_STORAGE 0x01 181 #define PCI_CLASS_SUB_SCSI_STORAGE_CONTROLLER 0x00 182 #define PCI_CLASS_PROG_UNSPECIFIED 0x00 183 #define VIRTIO_SCSI_NAME_FMT "VIRTIOSCSI%d" /* "VSCSI" *might* be ambiguous with VBoxSCSI? */ 184 #define VIRTIO_SCSI_PCI_CLASS 0x01 /* Base class Mass Storage? */ 185 #define VIRTIO_SCSI_N_QUEUES 3 /* Control, Event, Request */ 186 #define VIRTIO_SCSI_REGION_MEM_IO 0 187 #define VIRTIO_SCSI_REGION_PORT_IO 1 188 #define VIRTIO_SCSI_REGION_PCI_CAP 2 189 190 /** 191 * Definitions that follow are based on the VirtIO 1.0 specification. 192 * Struct names are the same. The field names have been adapted to VirtualBox 193 * data type + camel case annotation, with the original field name from the 194 * VirtIO specification in the field's comment. 195 */ 196 197 /** @name VirtIO 1.0 SCSI Host feature bits 198 * @{ */ 199 #define VIRTIO_SCSI_F_INOUT 0 /** Request is device readable AND writeable */ 200 #define VIRTIO_SCSI_F_HOTPLUG 1 /** Host SHOULD allow hotplugging SCSI LUNs & targets */ 201 #define VIRTIO_SCSI_F_CHANGE 2 /** Host reports LUN changes via VIRTIO_SCSI_T_PARAM_CHANGE event */ 202 /** @} */ 203 204 #define CDB_SIZE 1 /* logic tbd */ 205 #define SENSE_SIZE 1 /* logic tbd */ 206 #define PI_BYTES_OUT 1 /* logic tbd */ 207 #define PI_BYTES_IN 1 /* logic tbd */ 208 #define DATA_OUT 1 /* logic tbd */ 209 typedef struct virtio_scsi_req_cmd 210 { 211 /* Device-readable part */ 212 uint8_t uLUN[8]; /** lun */ 213 uint64_t uId; /** id */ 214 uint8_t uTaskAttr; /** task_attr */ 215 uint8_t uPrio; /** prio */ 216 uint8_t uCrn; /** crn */ 217 uint8_t uCdb[CDB_SIZE]; /** cdb */ 218 219 /** Following three fields only present if VIRTIO_SCSI_F_T10_PI negotiated */ 220 221 uint32_t uPiBytesOut; /** pi_bytesout */ 222 uint32_t uPiBytesIn; /** pi_bytesin */ 223 uint8_t uPiOut[PI_BYTES_OUT]; /** pi_out[] */ 224 225 uint8_t uDataOut[DATA_OUT]; /** dataout */ 226 227 /* Device-writable part */ 228 uint32_t uSenseLen; /** sense_len */ 229 uint32_t uResidual; /** residual */ 230 uint16_t uStatusQualifier; /** status_qualifier */ 231 uint8_t uStatus; /** status */ 232 uint8_t uResponse; /** response */ 233 uint8_t uSense[SENSE_SIZE]; /** sense */ 234 235 /** Following two fields only present if VIRTIO_SCSI_F_T10_PI negotiated */ 236 uint8_t uPiIn[PI_BYTES_IN]; /** pi_in[] */ 237 uint8_t uDataIn[]; /** detain; */ 238 } VIRTIOSCSIREQCMD, *PVIRTIOSCSIREQCMD; 239 240 /** Command-specific response values */ 241 #define VIRTIO_SCSI_S_OK 0 /* control, command */ 242 #define VIRTIO_SCSI_S_OVERRUN 1 /* control */ 243 #define VIRTIO_SCSI_S_ABORTED 2 /* control */ 244 #define VIRTIO_SCSI_S_BAD_TARGET 3 /* control, command */ 245 #define VIRTIO_SCSI_S_RESET 4 /* control */ 246 #define VIRTIO_SCSI_S_BUSY 5 /* control, command */ 247 #define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 /* control, command */ 248 #define VIRTIO_SCSI_S_TARGET_FAILURE 7 /* control, command */ 249 #define VIRTIO_SCSI_S_NEXUS_FAILURE 8 /* control, command */ 250 #define VIRTIO_SCSI_S_FAILURE 9 /* control, command */ 251 #define VIRTIO_SCSI_S_INCORRECT_LUN 12 /* command */ 252 253 254 /** task_attr */ 255 #define VIRTIO_SCSI_S_SIMPLE 0 256 #define VIRTIO_SCSI_S_ORDERED 1 257 #define VIRTIO_SCSI_S_HEAD 2 258 #define VIRTIO_SCSI_S_ACA 3 259 260 #define VIRTIO_SCSI_T_TMF 0 261 #define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 262 #define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 263 #define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 264 #define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 265 #define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 266 #define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 267 #define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 268 #define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 269 270 typedef struct virtio_scsi_ctrl_tmf 271 { 272 // Device-readable part 273 uint32_t uType; /** type */ 274 uint32_t uSubtype; /** subtype */ 275 uint8_t uLUN[8]; /** lun */ 276 uint64_t uId; /** id */ 277 // Device-writable part 278 uint8_t uResponse; /** response */ 279 } VIRTIOSCSICTRLBUF, *PVIRTIOSCSICTRLBUF; 280 281 /* command-specific response values */ 282 283 #define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0 284 #define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 285 #define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 286 287 #define VIRTIO_SCSI_T_AN_QUERY 1 /** Asynchronous notification query */ 288 #define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 /** Asynchronous notification subscription */ 289 290 typedef struct virtio_scsi_ctrl_an 291 { 292 // Device-readable part 293 uint32_t uType; /** type */ 294 uint8_t uLUN[8]; /** lun */ 295 uint32_t uEventRequested; /** event_requested */ 296 // Device-writable part 297 uint32_t uEventActual; /** event_actual */ 298 uint8_t uResponse; /** response */ 299 } VIRTIOSCSICTRLAN, *PVIRTIOSCSICTRLAN; 300 301 #define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2 302 #define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT 4 303 #define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST 8 304 #define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 305 #define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST 32 306 #define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY 64 307 308 /** Device operation: controlq */ 309 310 typedef struct virtio_scsi_ctrl 311 { 312 uint32_t type; /** type */ 313 uint8_t response; /** response */ 314 } VIRTIOSCSICTRL, *PVIRTIOSCSICTRL; 315 316 #define VIRTIO_SCSI_T_NO_EVENT 0 317 318 #define VIRTIO_SCSI_T_TRANSPORT_RESET 1 319 #define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 /** Asynchronous notification */ 320 #define VIRTIO_SCSI_T_PARAM_CHANGE 3 321 322 #define VIRTIO_SCSI_EVT_RESET_HARD 0 323 #define VIRTIO_SCSI_EVT_RESET_RESCAN 1 324 #define VIRTIO_SCSI_EVT_RESET_REMOVED 2 325 326 /** Device operation: eventq */ 327 328 #define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 329 typedef struct virtio_scsi_event { 330 // Device-writable part 331 uint32_t uEvent; /** event: */ 332 uint8_t uLUN[8]; /** lun */ 333 uint32_t uReason; /** reason */ 334 } VIRTIOSCSIEVENT, *PVIRTIOSCSIEVENT; 335 336 177 337 /*********************************************************************************************************************************/ 338 339 #ifdef BOOTABLE_SUPPORT_TBD 340 /** @callback_method_impl{FNIOMIOPORTIN} */ 341 static DECLCALLBACK(int) virtioScsiR3BiosIoPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint8_t *pbDst, 342 uint32_t *pcTransfers, unsigned cb); 343 { 344 } 345 /** @callback_method_impl{FNIOMIOPORTOUT} */ 346 static DECLCALLBACK(int) virtioScsiR3BiosIoPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb); 347 { 348 } 349 /** @callback_method_impl{FNIOMIOPORTOUTSTRING} */ 350 static DECLCALLBACK(int) virtioScsiR3BiosIoPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, const uint8_t *pbSrc, 351 uint32_t *pcTransfers, unsigned cb); 352 { 353 } 354 /** @callback_method_impl{FNIOMIOPORTINSTRING} */ 355 static DECLCALLBACK(int) virtioScsiR3BiosIoPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint8_t *pbDst, 356 uint32_t *pcTransfers, unsigned cb); 357 { 358 } 359 #endif 178 360 179 361 /** … … 186 368 static DECLCALLBACK(void) virtioScsiR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 187 369 { 188 PVIRTIOSCSI 189 bool 370 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 371 bool fVerbose = false; 190 372 191 373 /* Parse arguments. */ … … 197 379 pDevIns->pReg->szName, 198 380 pDevIns->iInstance); 199 pHlp->pfnPrintf(pHlp, "GC=%RTbool R0=%RTbool\n", 200 !!pThis->fGCEnabled, !!pThis->fR0Enabled); 381 pHlp->pfnPrintf(pHlp, "numTargets=%lu", pThis->cTargets); 201 382 } 202 383 … … 204 385 static DECLCALLBACK(int) virtioScsiR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass) 205 386 { 387 LogFunc(("callback")); 388 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 389 RT_NOREF(pThis); 206 390 RT_NOREF(uPass); 207 NOREF(pSSM); 208 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 209 LogFunc(("callback")); 210 NOREF(pThis); 391 RT_NOREF(pSSM); 211 392 return VINF_SSM_DONT_CALL_AGAIN; 212 393 } … … 215 396 static DECLCALLBACK(int) virtioScsiR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 216 397 { 398 LogFunc(("callback")); 399 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 400 RT_NOREF(pThis); 217 401 RT_NOREF(uPass); 218 NOREF(pSSM); 219 NOREF(uVersion); 220 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 221 LogFunc(("callback")); 222 NOREF(pThis); 402 RT_NOREF(pSSM); 403 RT_NOREF(uVersion); 223 404 return VINF_SSM_DONT_CALL_AGAIN; 224 405 } … … 227 408 static DECLCALLBACK(int) virtioScsiR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 228 409 { 410 LogFunc(("callback")); 411 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 412 RT_NOREF(pThis); 229 413 RT_NOREF(pSSM); 230 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);231 LogFunc(("callback"));232 NOREF(pThis);233 414 return VINF_SUCCESS; 234 415 } … … 237 418 static DECLCALLBACK(int) virtioScsiR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 238 419 { 420 LogFunc(("callback")); 421 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 422 RT_NOREF(pThis); 239 423 RT_NOREF(pSSM); 240 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);241 LogFunc(("callback"));242 NOREF(pThis);243 424 return VINF_SUCCESS; 244 425 } … … 258 439 { 259 440 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb); 260 261 /* the linux driver does not make use of the MMIO area. */ 262 AssertMsgFailed(("MMIO Read\n")); 441 LogFunc(("Read from MMIO area\n")); 263 442 return VINF_SUCCESS; 264 443 } 265 266 444 267 445 /** … … 279 457 { 280 458 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb); 281 282 /* the linux driver does not make use of the MMIO area. */ 283 AssertMsgFailed(("MMIO Write\n")); 459 LogFunc(("Write to MMIO area\n")); 284 460 return VINF_SUCCESS; 285 461 } 286 462 287 463 /** 288 * Port I/O Handler for IN operations.289 *290 * @returns VBox status code.291 *292 * @param pDevIns The device instance.293 * @param pvUser User argument.294 * @param uPort Port number used for the IN operation.295 * @param pu32 Where to store the result.296 * @param cb Number of bytes read.297 */298 PDMBOTHCBDECL(int) virtioScsiIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb)299 {300 // PVIRTIOSCSI pVirtioScsi = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);301 unsigned iRegister = uPort % 4;302 NOREF(iRegister);303 NOREF(pDevIns);304 NOREF(pu32);305 RT_NOREF_PV(pvUser); RT_NOREF_PV(cb);306 307 Assert(cb == 1);308 309 // return buslogicRegisterRead(pVirtioScsi, iRegister, pu32);310 return 0;311 }312 313 314 /**315 * Port I/O Handler for OUT operations.316 *317 * @returns VBox status code.318 *319 * @param pDevIns The device instance.320 * @param pvUser User argument.321 * @param uPort Port number used for the IN operation.322 * @param u32 The value to output.323 * @param cb The value size in bytes.324 */325 PDMBOTHCBDECL(int) virtioScsiIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb)326 {327 // PVIRTIOSCSI pVirtioScsi = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);328 unsigned iRegister = uPort % 4;329 uint8_t uVal = (uint8_t)u32;330 NOREF(uVal);331 NOREF(iRegister);332 RT_NOREF2(pvUser, cb);333 NOREF(u32);334 335 Assert(cb == 1);336 337 // int rc = buslogicRegisterWrite(pVirtioScsi, iRegister, (uint8_t)uVal);338 int rc = 0;339 Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x uPort=%#x rc=%Rrc\n",340 pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, uPort, rc));341 342 return rc;343 }344 345 /**346 464 * @callback_method_impl{FNPCIIOREGIONMAP} 347 465 */ 348 static DECLCALLBACK(int) virtioScsiR3M mioMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,466 static DECLCALLBACK(int) virtioScsiR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 349 467 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType) 350 468 { 351 469 RT_NOREF(pPciDev, iRegion); 352 470 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 353 int rc = VINF_SUCCESS; 354 355 LogFunc(("Register MMIO area at GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddress, cb)); 471 int rc = VINF_SUCCESS; 356 472 357 473 Assert(cb >= 32); 358 474 359 if (enmType == PCI_ADDRESS_SPACE_MEM)475 switch (iRegion) 360 476 { 361 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 362 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 477 case 0: 478 LogFunc(("virtio-scsi controller MMIO mapped at GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddress, cb)); 479 480 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 481 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 363 482 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 364 virtioScsiMMIOWrite, virtioScsiMMIORead, "virtio-scsi MMIO"); 365 if (RT_FAILURE(rc)) 483 virtioScsiMMIOWrite, virtioScsiMMIORead, 484 "virtio-scsi MMIO"); 485 pThis->GCPhysMMIOBase = RT_SUCCESS(rc) ? GCPhysAddress : 0; 366 486 return rc; 367 368 if (pThis->fGCEnabled) 369 { 370 rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/, 371 "virtioScsiMMIOWrite", "virtioScsiMMIORead"); 372 if (RT_FAILURE(rc)) 373 return rc; 374 } 375 376 pThis->MMIOBase = GCPhysAddress; 487 case 1: 488 /* VirtIO 1.0 doesn't uses Port I/O (Virtio 0.95 e.g. "legacy", does) */ 489 AssertMsgFailed(("virtio-scsi: Port I/O not supported by this Host SCSI device\n")); 490 default: 491 AssertMsgFailed(("Invalid enmType=%d\n", enmType)); 377 492 } 378 else if (enmType == PCI_ADDRESS_SPACE_IO) 379 { 380 rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, 32, 381 NULL, virtioScsiIOPortWrite, virtioScsiIOPortRead, NULL, NULL, "virtio-scsi PCI"); 382 if (RT_FAILURE(rc)) 383 return rc; 384 385 if (pThis->fGCEnabled) 386 { 387 rc = PDMDevHlpIOPortRegisterRC(pDevIns, (RTIOPORT)GCPhysAddress, 32, 388 0, "virtioScsiIOPortWrite", "virtioScsiIOPortRead", NULL, NULL, "virtio-scsi PCI"); 389 if (RT_FAILURE(rc)) 390 return rc; 391 } 392 393 pThis->IOPortBase = (RTIOPORT)GCPhysAddress; 394 } 395 else 396 AssertMsgFailed(("Invalid enmType=%d\n", enmType)); 397 398 return rc; 493 return VERR_GENERAL_FAILURE; /* Should never get here */ 399 494 } 400 495 … … 419 514 static DECLCALLBACK(void) virtioScsiR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta) 420 515 { 421 LogFunc(("Relocating virtio-scsci"));516 LogFunc(("Relocating virtio-scsi")); 422 517 RT_NOREF(offDelta); 423 518 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 424 519 425 520 pThis->pDevInsR3 = pDevIns; 426 // pThis->pNotifierQueueRC = PDMQueueRCPtr(pThis->pNotifierQueueR3);427 521 428 522 for (uint32_t i = 0; i < VIRTIOSCSI_MAX_TARGETS; i++) … … 458 552 size_t cbCopy) 459 553 { 460 NOREF(pInterface); 461 NOREF(pvIoReqAlloc); 462 NOREF(offDst); 463 NOREF(pSgBuf); 464 465 RT_NOREF1(hIoReq); 466 // PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 467 // PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 468 554 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 555 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 469 556 size_t cbCopied = 0; 557 RT_NOREF(pTarget); 558 RT_NOREF(pReq); 559 RT_NOREF(pInterface); 560 RT_NOREF(pvIoReqAlloc); 561 RT_NOREF(offDst); 562 RT_NOREF(pSgBuf); 563 RT_NOREF(hIoReq); 564 RT_NOREF(cbCopy); 565 RT_NOREF(cbCopied); 566 470 567 /* 471 568 if (RT_UNLIKELY(pReq->fBIOS)) … … 473 570 else 474 571 cbCopied = virtioScsiR3CopySgBufToGuest(pTarget->CTX_SUFF(pVirtioScsi), pReq, pSgBuf, offDst, cbCopy); 572 return cbCopied == cbCopy ? VINF_SUCCESS : VERR_PDM_MEDIAEX_IOBUF_OVERFLOW; 475 573 */ 476 return cbCopied == cbCopy ? VINF_SUCCESS : VERR_PDM_MEDIAEX_IOBUF_OVERFLOW;574 return 0; /* placeholder */ 477 575 } 478 576 … … 484 582 size_t cbCopy) 485 583 { 486 NOREF(pInterface); 487 NOREF(pvIoReqAlloc); 488 NOREF(offSrc); 489 NOREF(pSgBuf); 490 491 RT_NOREF1(hIoReq); 492 // PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 493 // PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 494 584 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 585 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 495 586 size_t cbCopied = 0; 587 RT_NOREF(pTarget); 588 RT_NOREF(pReq); 589 RT_NOREF(pInterface); 590 RT_NOREF(pvIoReqAlloc); 591 RT_NOREF(offSrc); 592 RT_NOREF(pSgBuf); 593 RT_NOREF(hIoReq); 594 RT_NOREF(cbCopy); 595 RT_NOREF(cbCopied); 596 496 597 /* 497 598 if (RT_UNLIKELY(pReq->fBIOS)) … … 499 600 else 500 601 cbCopied = vboxscsiR3CopySgBufFromGuest(pTarget->CTX_SUFF(pVirtioScsi), pReq, pSgBuf, offSrc, cbCopy); 602 return cbCopied == cbCopy ? VINF_SUCCESS : VERR_PDM_MEDIAEX_IOBUF_UNDERRUN; 501 603 */ 502 return cbCopied == cbCopy ? VINF_SUCCESS : VERR_PDM_MEDIAEX_IOBUF_UNDERRUN; 604 return 0; /* placeholder */ 605 503 606 } 504 607 … … 509 612 void *pvIoReqAlloc, int rcReq) 510 613 { 511 NOREF(pInterface); 512 NOREF(pvIoReqAlloc); 513 NOREF(rcReq); 614 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 615 RT_NOREF(pTarget); 616 RT_NOREF(pInterface); 617 RT_NOREF(pvIoReqAlloc); 618 RT_NOREF(rcReq); 514 619 RT_NOREF(hIoReq); 515 // PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort);516 620 // virtioScsiR3ReqComplete(pTarget->CTX_SUFF(pVirtioScsi), (VIRTIOSCSIREQ)pvIoReqAlloc, rcReq); 517 621 return VINF_SUCCESS; … … 525 629 { 526 630 527 NOREF(pInterface); 528 NOREF(hIoReq); 529 NOREF(enmState); 530 RT_NOREF3(hIoReq, pvIoReqAlloc, enmState); 631 RT_NOREF4(pInterface, hIoReq, pvIoReqAlloc, enmState); 531 632 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 532 633 … … 551 652 552 653 /** 553 * Gets the pointer to the status LED of a device - called from the SCSI driver.554 *555 * @returns VBox status code.556 * @param pInterface Pointer to the interface structure containing the called function pointer.557 * @param iLUN The unit which status LED we desire. Always 0 here as the driver558 * doesn't know about other LUN's.559 * @param ppLed Where to store the LED pointer.560 */561 static DECLCALLBACK(int) virtioScsiR3DeviceQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)562 {563 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, ILed);564 if (iLUN == 0)565 {566 *ppLed = &pTarget->Led;567 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);568 return VINF_SUCCESS;569 }570 return VERR_PDM_LUN_NOT_FOUND;571 }572 573 /**574 654 * @interface_method_impl{PDMIMEDIAEXPORT,pfnMediumEjected} 575 655 */ … … 580 660 581 661 if (pThis->pMediaNotify) 582 { 583 int rc = VMR3ReqCallNoWait(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), VMCPUID_ANY, 584 (PFNRT)pThis->pMediaNotify->pfnEjected, 2, 585 pThis->pMediaNotify, pTarget->iLUN); 586 AssertRC(rc); 587 } 588 } 589 590 591 /** 592 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 593 */ 594 static DECLCALLBACK(void *) virtioScsiR3DeviceQueryInterface(PPDMIBASE pInterface, const char *pszIID) 595 { 596 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IBase); 597 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pTarget->IBase); 598 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pTarget->IMediaPort); 599 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pTarget->IMediaExPort); 600 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pTarget->ILed); 601 return NULL; 602 } 662 virtioSetWriteLed(&(pThis->virtioState), false); 663 } 664 603 665 604 666 /** … … 622 684 } 623 685 686 687 /** 688 * virtio-scsi VirtIO Device-specific capabilities read callback 689 * (other VirtIO capabilities and features are handled in VirtIO implementation) 690 * 691 * @param pDevIns The device instance. 692 * @param GCPhysAddr Guest driver physical address to read 693 * @param pvBuf Buffer in which to save read data 694 * @param cbRead Number of bytes to read 695 */ 696 static DECLCALLBACK(int) virtioScsiR3DevCapRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead) 697 { 698 /*TBD*/ 699 LogFlowFunc(("Read from Device-Specific capabilities, callback to VirtIO client\n")); 700 RT_NOREF(pDevIns); 701 RT_NOREF(GCPhysAddr); 702 RT_NOREF(pvBuf); 703 RT_NOREF(cbRead); 704 int rv = VINF_SUCCESS; 705 return rv; 706 } 707 708 /** 709 * virtio-scsi VirtIO Device-specific capabilities read callback 710 * (other VirtIO capabilities and features are handled in VirtIO implementation) 711 * 712 * @param pDevIns The device instance. 713 * @param GCPhysAddr Guest driver physical address to write 714 * @param pvBuf Buffer in which to save read data 715 * @param cbRead Number of bytes to write 716 */ 717 static DECLCALLBACK(int) virtioScsiR3DevCapWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite) 718 { 719 /*TBD*/ 720 LogFlowFunc(("Write to Device-Specific capabilities, callback to VirtIO client\n")); 721 RT_NOREF(pDevIns); 722 RT_NOREF(GCPhysAddr); 723 RT_NOREF(pvBuf); 724 RT_NOREF(cbWrite); 725 int rv = VINF_SUCCESS; 726 return rv; 727 } 728 729 /** 730 * Detach notification. 731 * 732 * One harddisk at one port has been unplugged. 733 * The VM is suspended at this point. 734 * 735 * @param pDevIns The device instance. 736 * @param iLUN The logical unit which is being detached. 737 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 738 */ 739 static DECLCALLBACK(void) virtioScsiR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 740 { 741 RT_NOREF(fFlags); 742 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 743 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN]; 744 745 Log(("%s:\n", __FUNCTION__)); 746 747 AssertMsg(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG, 748 ("virtio-scsi: Device does not support hotplugging\n")); 749 750 /* 751 * Zero some important members. 752 */ 753 pTarget->fPresent = false; 754 pTarget->pUpstreamDrvBase = NULL; 755 } 756 757 758 /** 759 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 760 */ 761 static DECLCALLBACK(void *) virtioScsiR3DeviceQueryInterface(PPDMIBASE pInterface, const char *pszIID) 762 { 763 PPDMDRVINS pDevIns = PDMIBASE_2_PDMDRV(pInterface); 764 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IBase); 765 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDevIns->IBase); 766 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pTarget->IMediaPort); 767 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pTarget->IMediaExPort); 768 return NULL; 769 } 770 771 /** 772 * Attach command. 773 * 774 * This is called when we change block driver. 775 * 776 * @returns VBox status code. 777 * @param pDevIns The device instance. 778 * @param iLUN The logical unit which is being detached. 779 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 780 */ 781 static DECLCALLBACK(int) virtioScsiR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 782 { 783 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 784 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN]; 785 int rc; 786 787 pThis->pDevInsR3 = pDevIns; 788 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 789 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 790 791 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG, 792 ("virtio-scsi: Device does not support hotplugging\n"), 793 VERR_INVALID_PARAMETER); 794 795 /* the usual paranoia */ 796 AssertRelease(!pTarget->pUpstreamDrvBase); 797 Assert(pTarget->iLUN == iLUN); 798 799 /* 800 * Try attach the SCSI driver and get the interfaces, 801 * required as well as optional. 802 */ 803 rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iLUN, &pDevIns->IBase, 804 &pTarget->pUpstreamDrvBase, (const char *)&pTarget->pszLunName); 805 if (RT_SUCCESS(rc)) 806 pTarget->fPresent = true; 807 else 808 AssertMsgFailed(("Failed to attach %s. rc=%Rrc\n", pTarget->pszLunName, rc)); 809 810 if (RT_FAILURE(rc)) 811 { 812 pTarget->fPresent = false; 813 pTarget->pUpstreamDrvBase = NULL; 814 } 815 return rc; 816 } 817 624 818 static DECLCALLBACK(int) virtioScsiDestruct(PPDMDEVINS pDevIns) 625 819 { … … 628 822 */ 629 823 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); 630 631 824 return VINF_SUCCESS; 632 825 } … … 635 828 { 636 829 830 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 637 831 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 638 int rc = VINF_SUCCESS; 639 bool fBootable = true; 640 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 641 642 NOREF(fBootable); 643 NOREF(iInstance); 644 645 /* 646 * Init instance data (do early because of constructor). 647 */ 648 pThis->pDevInsR3 = pDevIns; 649 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 650 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 651 652 PCIDevSetVendorId (&pThis->dev, 0x1AF4); /* VirtIO */ 653 PCIDevSetDeviceId (&pThis->dev, 0x1048); /* SCSI Host */ 654 PCIDevSetCommand (&pThis->dev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS); 655 PCIDevSetRevisionId (&pThis->dev, 0x01); 656 PCIDevSetClassProg (&pThis->dev, 0x00); /* SCSI */ 657 PCIDevSetClassSub (&pThis->dev, 0x00); /* SCSI */ 658 PCIDevSetClassBase (&pThis->dev, 0x01); /* Mass storage */ 659 PCIDevSetBaseAddress (&pThis->dev, 0, true /*IO*/, false /*Pref*/, false /*64-bit*/, 0x00000000); 660 PCIDevSetBaseAddress (&pThis->dev, 1, false /*IO*/, false /*Pref*/, false /*64-bit*/, 0x00000000); 661 PCIDevSetSubSystemVendorId(&pThis->dev, 0x104b); 662 PCIDevSetSubSystemId (&pThis->dev, 0x1040); 663 PCIDevSetInterruptLine (&pThis->dev, 0x00); 664 PCIDevSetInterruptPin (&pThis->dev, 0x01); 832 int rc = VINF_SUCCESS; 833 bool fBootable = true; 834 835 LogFunc(("PDM device instance: %d\n", iInstance)); 665 836 666 837 /* 667 838 * Validate and read configuration. 668 839 */ 669 if (!CFGMR3AreValuesValid(pCfg, 670 "GCEnabled\0" 671 "R0Enabled\0" 672 "NumTargets\0")) 673 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 840 if (!CFGMR3AreValuesValid(pCfg,"NumTargets\0" 841 "Bootable\0" 842 /* "GCEnabled\0" TBD */ 843 /* "R0Enabled\0" TBD */ 844 )) 845 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 674 846 N_("virtio-scsi configuration error: unknown option specified")); 675 676 rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &pThis->fGCEnabled, true);677 if (RT_FAILURE(rc))678 return PDMDEV_SET_ERROR(pDevIns, rc,679 N_("virtio-scsi configuration error: failed to read GCEnabled as boolean"));680 LogFunc(("fGCEnabled=%d\n", pThis->fGCEnabled));681 682 rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &pThis->fR0Enabled, true);683 if (RT_FAILURE(rc))684 return PDMDEV_SET_ERROR(pDevIns, rc,685 N_("virtio-scsi configuration error: failed to read R0Enabled as boolean"));686 LogFunc(("R0Enabled=%d\n", pThis->fGCEnabled));687 847 688 848 rc = CFGMR3QueryIntegerDef(pCfg, "NumTargets", &pThis->cTargets, true); … … 690 850 return PDMDEV_SET_ERROR(pDevIns, rc, 691 851 N_("virtio-scsi configuration error: failed to read NumTargets as integer")); 692 LogFunc(("NumTargets=%d\n", pThis->fGCEnabled)); 693 694 695 LogFunc(("Register PCI device and map mmio and ports\n")); 696 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev); 852 LogFunc(("NumTargets=%d\n", pThis->cTargets)); 853 854 rc = CFGMR3QueryBoolDef(pCfg, "Bootable", &fBootable, true); 697 855 if (RT_FAILURE(rc)) 698 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi cannot register with PCI bus")); 699 700 LogFunc(("Register io region\n")); 701 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 32, PCI_ADDRESS_SPACE_IO, virtioScsiR3MmioMap); 856 return PDMDEV_SET_ERROR(pDevIns, rc, 857 N_("virtio-scsi configuration error: failed to read Bootable as boolean")); 858 LogFunc(("Bootable=%RTbool (unimplemented)\n", fBootable)); 859 860 VIRTIOPCIPARAMS virtioPciParams, *pVirtioPciParams = &virtioPciParams; 861 pVirtioPciParams->uDeviceId = PCI_DEVICE_ID_VIRTIO_SCSI_HOST; 862 pVirtioPciParams->uClassBase = PCI_CLASS_BASE_MASS_STORAGE; 863 pVirtioPciParams->uClassSub = PCI_CLASS_SUB_SCSI_STORAGE_CONTROLLER; 864 pVirtioPciParams->uClassProg = PCI_CLASS_PROG_UNSPECIFIED; 865 pVirtioPciParams->uSubsystemId = PCI_DEVICE_ID_VIRTIO_SCSI_HOST; /* Virtio 1.0 spec allows PCI Device ID here */ 866 pVirtioPciParams->uInterruptLine = 0x00; 867 pVirtioPciParams->uInterruptPin = 0x01; 868 869 870 PVIRTIOSTATE pVirtioScsi = &(pThis->virtioState); 871 rc = virtioConstruct(pDevIns, pVirtioScsi, iInstance, pVirtioPciParams, 872 VIRTIO_SCSI_NAME_FMT, VIRTIO_SCSI_N_QUEUES, VIRTIO_SCSI_REGION_PCI_CAP, 873 virtioScsiR3DevCapRead, virtioScsiR3DevCapWrite, sizeof(VIRTIODEVCFG)); 702 874 if (RT_FAILURE(rc)) 703 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi cannot register PCI I/O address space")); 704 LogFunc(("Register mmio region\n")); 705 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1, 32, PCI_ADDRESS_SPACE_MEM, virtioScsiR3MmioMap); 875 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO")); 876 877 rc = PDMDevHlpPCIIORegionRegister(pDevIns, VIRTIO_SCSI_REGION_PORT_IO, 32, 878 PCI_ADDRESS_SPACE_MEM, virtioScsiR3Map); 706 879 if (RT_FAILURE(rc)) 707 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi cannot register PCI mmio address space")); 708 #if 0 880 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: cannot register PCI mmio address space")); 881 882 #ifdef BOOTABLE_SUPPORT_TBD 709 883 if (fBootable) 710 884 { … … 718 892 } 719 893 #endif 894 720 895 /* Initialize task queue. */ 721 896 rc = PDMDevHlpQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 5, 0, … … 724 899 return rc; 725 900 726 pThis->pNotifierQueueR0 = PDMQueueR0Ptr(pThis->pNotifierQueueR3);727 pThis->pNotifierQueueRC = PDMQueueRCPtr(pThis->pNotifierQueueR3);728 729 901 /* Initialize per device instance. */ 730 for ( unsigned i = 0; i < VIRTIOSCSI_MAX_TARGETS; i++)902 for (RTUINT iLUN = 0; iLUN < VIRTIOSCSI_MAX_TARGETS; iLUN++) 731 903 { 732 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[i]; 733 char *pszName; 734 735 if (RTStrAPrintf(&pszName, "Device%u", i) < 0) 904 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN]; 905 906 if (RTStrAPrintf(&pTarget->pszLunName, "VSCSI%u", iLUN) < 0) 736 907 AssertLogRelFailedReturn(VERR_NO_MEMORY); 737 908 738 909 /* Initialize static parts of the device. */ 739 pTarget->iLUN = i ;910 pTarget->iLUN = iLUN; 740 911 pTarget->pVirtioScsiR3 = pThis; 741 pTarget->pVirtioScsiRC = PDMINS_2_DATA_RCPTR(pDevIns); 742 pTarget->Led.u32Magic = PDMLED_MAGIC; 743 pTarget->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 912 /* IMediaPort and IMediaExPort interfaces provide callbacks for VD media and downstream driver access */ 744 913 pTarget->IMediaPort.pfnQueryDeviceLocation = virtioScsiR3QueryDeviceLocation; 745 914 pTarget->IMediaExPort.pfnIoReqCompleteNotify = virtioScsiR3IoReqCompleteNotify; 746 915 pTarget->IMediaExPort.pfnIoReqCopyFromBuf = virtioScsiR3IoReqCopyFromBuf; 747 916 pTarget->IMediaExPort.pfnIoReqCopyToBuf = virtioScsiR3IoReqCopyToBuf; 917 pTarget->IMediaExPort.pfnIoReqStateChanged = virtioScsiR3IoReqStateChanged; 918 pTarget->IMediaExPort.pfnMediumEjected = virtioScsiR3MediumEjected; 748 919 pTarget->IMediaExPort.pfnIoReqQueryBuf = NULL; 749 920 pTarget->IMediaExPort.pfnIoReqQueryDiscardRanges = NULL; 750 pTarget->IMediaExPort.pfnIoReqStateChanged = virtioScsiR3IoReqStateChanged; 751 pTarget->IMediaExPort.pfnMediumEjected = virtioScsiR3MediumEjected; 752 pTarget->ILed.pfnQueryStatusLed = virtioScsiR3DeviceQueryStatusLed; 753 754 LogFunc(("Attaching: Lun=%d, pszName=%s\n", pTarget->iLUN, pszName)); 755 /* Attach SCSI driver. */ 756 AssertReturn(pTarget->iLUN < RT_ELEMENTS(pThis->aTargetInstances), VERR_PDM_NO_SUCH_LUN); 757 rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iLUN, &pTarget->IBase, &pTarget->pDrvBase, pszName); 921 pDevIns->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 922 923 LogFunc(("Attaching LUN: %s\n", pTarget->pszLunName)); 924 925 /* Attach this SCSI driver (upstream driver pre-determined statically outside this module) */ 926 AssertReturn(iLUN < RT_ELEMENTS(pThis->aTargetInstances), VERR_PDM_NO_SUCH_LUN); 927 rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pDevIns->IBase, &pTarget->pUpstreamDrvBase, (const char *)&pTarget->pszLunName); 758 928 if (RT_SUCCESS(rc)) 929 { 759 930 pTarget->fPresent = true; 931 932 pTarget->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pTarget->pUpstreamDrvBase, PDMIMEDIA); 933 AssertMsgReturn(VALID_PTR(pTarget->pDrvMedia), 934 ("virtio-scsi configuration error: LUN#%d missing basic media interface!\n", pTarget->iLUN), 935 VERR_PDM_MISSING_INTERFACE); 936 937 /* Get the extended media interface. */ 938 pTarget->pDrvMediaEx = PDMIBASE_QUERY_INTERFACE(pTarget->pUpstreamDrvBase, PDMIMEDIAEX); 939 AssertMsgReturn(VALID_PTR(pTarget->pDrvMediaEx), 940 ("virtio-scsi configuration error: LUN#%d missing extended media interface!\n", pTarget->iLUN), 941 VERR_PDM_MISSING_INTERFACE); 942 943 // pk: Not sure if this is needed here yet with VirtIO or DrvScsi, will investigate after basic VirtIO working. 944 // rc = pTarget->pDrvMediaEx->pfnIoReqAllocSizeSet(pTarget->pDrvMediaEx, sizeof(BUSLOGICREQ)); 945 // AssertMsgRCReturn(rc, ("BusLogic configuration error: LUN#%u: Failed to set I/O request size!", pTarget->iLUN), 946 947 } 760 948 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 761 949 { 762 pTarget->fPresent 763 pTarget->p DrvBase= NULL;950 pTarget->fPresent = false; 951 pTarget->pUpstreamDrvBase = NULL; 764 952 rc = VINF_SUCCESS; 765 Log(("virtio-scsi: no driver attached to device %s\n", p szName));953 Log(("virtio-scsi: no driver attached to device %s\n", pTarget->pszLunName)); 766 954 } 767 955 else 768 956 { 769 AssertLogRelMsgFailed(("virtio-scsi: Failed to attach %s\n", p szName));957 AssertLogRelMsgFailed(("virtio-scsi: Failed to attach %s\n", pTarget->pszLunName)); 770 958 return rc; 771 959 } 772 960 } 773 961 774 /*775 * Attach status driver (optional).776 */777 /*778 PPDMIBASE pBase;779 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");780 if (RT_SUCCESS(rc))781 pThis->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);782 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)783 {784 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));785 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi cannot attach to status driver"));786 }787 */788 962 rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIOSCSI_SAVED_STATE_MINOR_VERSION, sizeof(*pThis), NULL, 789 963 NULL, virtioScsiR3LiveExec, NULL, … … 797 971 char szTmp[128]; 798 972 RTStrPrintf(szTmp, sizeof(szTmp), "%s%d", pDevIns->pReg->szName, pDevIns->iInstance); 799 PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "virtio-scsi HBAinfo", virtioScsiR3Info);973 PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "virtio-scsi info", virtioScsiR3Info); 800 974 801 975 return rc; 802 976 } 803 804 805 /**806 * Detach notification.807 *808 * One harddisk at one port has been unplugged.809 * The VM is suspended at this point.810 *811 * @param pDevIns The device instance.812 * @param iLUN The logical unit which is being detached.813 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.814 */815 static DECLCALLBACK(void) virtioScsiR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)816 {817 RT_NOREF(fFlags);818 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);819 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN];820 821 Log(("%s:\n", __FUNCTION__));822 823 AssertMsg(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,824 ("virtio-scsi: Device does not support hotplugging\n"));825 826 /*827 * Zero some important members.828 */829 pTarget->fPresent = false;830 pTarget->pDrvBase = NULL;831 }832 833 834 /**835 * Attach command.836 *837 * This is called when we change block driver.838 *839 * @returns VBox status code.840 * @param pDevIns The device instance.841 * @param iLUN The logical unit which is being detached.842 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.843 */844 static DECLCALLBACK(int) virtioScsiR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)845 {846 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);847 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN];848 int rc;849 850 LogFlowFunc(("iLun=%d"));851 852 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,853 ("virtio-scsi: Device does not support hotplugging\n"),854 VERR_INVALID_PARAMETER);855 856 /* the usual paranoia */857 AssertRelease(!pTarget->pDrvBase);858 Assert(pTarget->iLUN == iLUN);859 860 /*861 * Try attach the SCSI driver and get the interfaces,862 * required as well as optional.863 */864 rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iLUN, &pTarget->IBase, &pTarget->pDrvBase, NULL);865 if (RT_SUCCESS(rc))866 pTarget->fPresent = true;867 else868 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pTarget->iLUN, rc));869 870 if (RT_FAILURE(rc))871 {872 pTarget->fPresent = false;873 pTarget->pDrvBase = NULL;874 }875 return rc;876 }877 878 977 879 978 /** … … 887 986 "virtio-scsi", 888 987 /* szRCMod */ 889 " VBoxDDRC.rc",988 "", 890 989 /* szR0Mod */ 891 " VBoxDDR0.r0",990 "", 892 991 /* pszDescription */ 893 "Virtio SCSI Device.",992 "Virtio SCSI.\n", 894 993 /* fFlags */ 994 #ifdef VIRTIOSCSI_GC_SUPPORT 995 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0, 996 #else 895 997 PDM_DEVREG_FLAGS_DEFAULT_BITS, 998 #endif 896 999 /* fClass */ 897 1000 PDM_DEVREG_CLASS_MISC, -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r79551 r79928 2413 2413 hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts); H(); 2414 2414 InsertConfigInteger(pCfg, "NumTargets", cPorts); 2415 InsertConfigInteger(pCfg, "Bootable", fBootable); 2415 2416 2416 2417 /* Attach the status driver */
Note:
See TracChangeset
for help on using the changeset viewer.