Changeset 80058 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Jul 30, 2019 8:17:49 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 132495
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r79973 r80058 44 44 #include "VBoxDD.h" 45 45 46 47 /********************************************************************************************************************************* 48 * Structures and Typedefs * 49 *********************************************************************************************************************************/ 50 #define VIRTIOSCSI_MAX_TARGETS 1 51 52 /** 53 * Device Instance Data. 46 #define VIRTIOSCSI_MAX_TARGETS 1 47 #define VIRTIOSCSI_SAVED_STATE_MINOR_VERSION 0x01 48 #define REQ_ALLOC_SIZE 1024 /* TBD */ 49 50 #define PCI_VENDOR_ID_VIRTIO 0x1AF4 51 #define PCI_DEVICE_ID_VIRTIOSCSI_HOST 0x1048 52 #define PCI_CLASS_BASE_MASS_STORAGE 0x01 53 #define PCI_CLASS_SUB_SCSI_STORAGE_CONTROLLER 0x00 54 #define PCI_CLASS_PROG_UNSPECIFIED 0x00 55 #define VIRTIOSCSI_NAME_FMT "VIRTIOSCSI%d" /* "VSCSI" *might* be ambiguous with VBoxSCSI? */ 56 #define VIRTIOSCSI_PCI_CLASS 0x01 /* Base class Mass Storage? */ 57 #define VIRTIOSCSI_N_QUEUES 3 /* Control, Event, Request */ 58 #define VIRTIOSCSI_REGION_MEM_IO 0 59 #define VIRTIOSCSI_REGION_PORT_IO 1 60 #define VIRTIOSCSI_REGION_PCI_CAP 2 61 62 /** 63 * Definitions that follow are based on the VirtIO 1.0 specification. 64 * Struct names are the same. The field names have been adapted to VirtualBox 65 * data type + camel case annotation, with the original field name from the 66 * VirtIO specification in the field's comment. 67 */ 68 69 /** @name VirtIO 1.0 SCSI Host feature bits 70 * @{ */ 71 #define VIRTIOSCSI_F_INOUT RT_BIT_64(0) /** Request is device readable AND writeable */ 72 #define VIRTIOSCSI_F_HOTPLUG RT_BIT_64(1) /** Host SHOULD allow hotplugging SCSI LUNs & targets */ 73 #define VIRTIOSCSI_F_CHANGE RT_BIT_64(2) /** Host reports LUN changes via VIRTIOSCSI_T_PARAM_CHANGE event */ 74 #define VIRTIOSCSI_F_T10_PI RT_BIT_64(3) /** Ext. flds for T10 prot info (DIF/DIX) in SCSI req hdr */ 75 /** @} */ 76 77 /** 78 * Features VirtIO 1.0 Host SCSI controller offers guest driver 79 */ 80 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED VIRTIOSCSI_F_INOUT \ 81 | VIRTIOSCSI_F_HOTPLUG \ 82 | VIRTIOSCSI_F_CHANGE \ 83 | VIRTIOSCSI_F_T10_PI \ 84 85 /** 86 * State of a target attached to the VirtIO SCSI Host 54 87 */ 55 88 typedef struct VIRTIOSCSITARGET 56 89 { 57 /** Pointer to PCI device that owns this target instance. - R3 /pointer */90 /** Pointer to PCI device that owns this target instance. - R3 pointer */ 58 91 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsiR3; 59 /** Pointer to PCI device that owns this target instance. - R0 pointer */60 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsiR0;61 /** Pointer to PCI device that owns this target instance. - RC pointer */62 R3PTRTYPE(struct VIRTIOSCSI *) pVirtioScsiRC;63 92 64 93 /** Pointer to attached driver's base interface. */ 65 R3PTRTYPE(PPDMIBASE) p UpstreamDrvBase;66 67 /** LUN of the device.*/94 R3PTRTYPE(PPDMIBASE) pDrvBase; 95 96 /** Target LUN */ 68 97 RTUINT iLUN; 69 98 70 /** Our base interface. */ 99 /** Target LUN Description */ 100 char * pszLunName; 101 102 /** Target base interface. */ 71 103 PDMIBASE IBase; 72 104 … … 74 106 bool fPresent; 75 107 108 76 109 /** Media port interface. */ 77 110 PDMIMEDIAPORT IMediaPort; 111 /** Pointer to the attached driver's media interface. */ 112 R3PTRTYPE(PPDMIMEDIA) pDrvMedia; 113 78 114 79 115 /** Extended media port interface. */ 80 116 PDMIMEDIAEXPORT IMediaExPort; 117 /** Pointer to the attached driver's extended media interface. */ 118 R3PTRTYPE(PPDMIMEDIAEX) pDrvMediaEx; 119 120 121 /** Status LED interface */ 122 PDMILEDPORTS ILed; 123 /** The status LED state for this device. */ 124 PDMLED led; 81 125 82 126 /** Number of outstanding tasks on the port. */ 83 127 volatile uint32_t cOutstandingRequests; 84 85 /** LUN Description */86 char * pszLunName;87 88 /** Pointer to the attached driver's media interface. */89 R3PTRTYPE(PPDMIMEDIA) pDrvMedia;90 91 /** Pointer to the attached driver's extended media interface. */92 R3PTRTYPE(PPDMIMEDIAEX) pDrvMediaEx;93 128 94 129 R3PTRTYPE(PVQUEUE) pCtlQueue; // ? TBD … … 100 135 101 136 /** 102 * Main VirtIO SCSI device state.137 * PDM instance data (state) for VirtIO Host SCSI device 103 138 * 104 139 * @extends PDMPCIDEV … … 112 147 VIRTIOSCSITARGET aTargetInstances[VIRTIOSCSI_MAX_TARGETS]; 113 148 114 PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */ 115 PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */ 116 PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */ 149 /** Device base interface. */ 150 PDMIBASE IBase; 151 152 /** Pointer to the device instance. - R3 ptr. */ 153 PPDMDEVINSR3 pDevInsR3; 154 /** Pointer to the device instance. - R0 ptr. */ 155 PPDMDEVINSR0 pDevInsR0; 156 /** Pointer to the device instance. - RC ptr. */ 157 PPDMDEVINSRC pDevInsRC; 158 159 /** Status LUN: LEDs port interface. */ 160 PDMILEDPORTS ILeds; 161 162 /** Status LUN: Partner of ILeds. */ 163 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector; 117 164 118 165 /** Base address of the memory mapping. */ … … 133 180 /** The event semaphore the processing thread waits on. */ 134 181 SUPSEMEVENT hEvtProcess; 182 183 PVIRTIOCALLBACKS pVirtioCallbacks; 135 184 136 185 /** Number of ports detected */ … … 168 217 169 218 170 #define VIRTIOSCSI_SAVED_STATE_MINOR_VERSION 0x01171 172 #define PCI_VENDOR_ID_VIRTIO 0x1AF4173 #define PCI_DEVICE_ID_VIRTIO_SCSI_HOST 0x1048174 #define PCI_CLASS_BASE_MASS_STORAGE 0x01175 #define PCI_CLASS_SUB_SCSI_STORAGE_CONTROLLER 0x00176 #define PCI_CLASS_PROG_UNSPECIFIED 0x00177 #define VIRTIO_SCSI_NAME_FMT "VIRTIOSCSI%d" /* "VSCSI" *might* be ambiguous with VBoxSCSI? */178 #define VIRTIO_SCSI_PCI_CLASS 0x01 /* Base class Mass Storage? */179 #define VIRTIO_SCSI_N_QUEUES 3 /* Control, Event, Request */180 #define VIRTIO_SCSI_REGION_MEM_IO 0181 #define VIRTIO_SCSI_REGION_PORT_IO 1182 #define VIRTIO_SCSI_REGION_PCI_CAP 2183 184 /**185 * Definitions that follow are based on the VirtIO 1.0 specification.186 * Struct names are the same. The field names have been adapted to VirtualBox187 * data type + camel case annotation, with the original field name from the188 * VirtIO specification in the field's comment.189 */190 191 /** @name VirtIO 1.0 SCSI Host feature bits192 * @{ */193 #define VIRTIO_SCSI_F_INOUT 0 /** Request is device readable AND writeable */194 #define VIRTIO_SCSI_F_HOTPLUG 1 /** Host SHOULD allow hotplugging SCSI LUNs & targets */195 #define VIRTIO_SCSI_F_CHANGE 2 /** Host reports LUN changes via VIRTIO_SCSI_T_PARAM_CHANGE event */196 /** @} */197 198 219 #define CDB_SIZE 1 /* logic tbd */ 199 220 #define SENSE_SIZE 1 /* logic tbd */ … … 211 232 uint8_t uCdb[CDB_SIZE]; /** cdb */ 212 233 213 /** Following three fields only present if VIRTIO _SCSI_F_T10_PI negotiated */234 /** Following three fields only present if VIRTIOSCSI_F_T10_PI negotiated */ 214 235 215 236 uint32_t uPiBytesOut; /** pi_bytesout */ … … 227 248 uint8_t uSense[SENSE_SIZE]; /** sense */ 228 249 229 /** Following two fields only present if VIRTIO _SCSI_F_T10_PI negotiated */250 /** Following two fields only present if VIRTIOSCSI_F_T10_PI negotiated */ 230 251 uint8_t uPiIn[PI_BYTES_IN]; /** pi_in[] */ 231 252 uint8_t uDataIn[]; /** detain; */ … … 233 254 234 255 /** Command-specific response values */ 235 #define VIRTIO _SCSI_S_OK 0 /* control, command */236 #define VIRTIO _SCSI_S_OVERRUN 1 /* control */237 #define VIRTIO _SCSI_S_ABORTED 2 /* control */238 #define VIRTIO _SCSI_S_BAD_TARGET 3 /* control, command */239 #define VIRTIO _SCSI_S_RESET 4 /* control */240 #define VIRTIO _SCSI_S_BUSY 5 /* control, command */241 #define VIRTIO _SCSI_S_TRANSPORT_FAILURE 6 /* control, command */242 #define VIRTIO _SCSI_S_TARGET_FAILURE 7 /* control, command */243 #define VIRTIO _SCSI_S_NEXUS_FAILURE 8 /* control, command */244 #define VIRTIO _SCSI_S_FAILURE 9 /* control, command */245 #define VIRTIO _SCSI_S_INCORRECT_LUN 12 /* command */256 #define VIRTIOSCSI_S_OK 0 /* control, command */ 257 #define VIRTIOSCSI_S_OVERRUN 1 /* control */ 258 #define VIRTIOSCSI_S_ABORTED 2 /* control */ 259 #define VIRTIOSCSI_S_BAD_TARGET 3 /* control, command */ 260 #define VIRTIOSCSI_S_RESET 4 /* control */ 261 #define VIRTIOSCSI_S_BUSY 5 /* control, command */ 262 #define VIRTIOSCSI_S_TRANSPORT_FAILURE 6 /* control, command */ 263 #define VIRTIOSCSI_S_TARGET_FAILURE 7 /* control, command */ 264 #define VIRTIOSCSI_S_NEXUS_FAILURE 8 /* control, command */ 265 #define VIRTIOSCSI_S_FAILURE 9 /* control, command */ 266 #define VIRTIOSCSI_S_INCORRECT_LUN 12 /* command */ 246 267 247 268 248 269 /** task_attr */ 249 #define VIRTIO _SCSI_S_SIMPLE 0250 #define VIRTIO _SCSI_S_ORDERED 1251 #define VIRTIO _SCSI_S_HEAD 2252 #define VIRTIO _SCSI_S_ACA 3253 254 #define VIRTIO _SCSI_T_TMF 0255 #define VIRTIO _SCSI_T_TMF_ABORT_TASK 0256 #define VIRTIO _SCSI_T_TMF_ABORT_TASK_SET 1257 #define VIRTIO _SCSI_T_TMF_CLEAR_ACA 2258 #define VIRTIO _SCSI_T_TMF_CLEAR_TASK_SET 3259 #define VIRTIO _SCSI_T_TMF_I_T_NEXUS_RESET 4260 #define VIRTIO _SCSI_T_TMF_LOGICAL_UNIT_RESET 5261 #define VIRTIO _SCSI_T_TMF_QUERY_TASK 6262 #define VIRTIO _SCSI_T_TMF_QUERY_TASK_SET 7270 #define VIRTIOSCSI_S_SIMPLE 0 271 #define VIRTIOSCSI_S_ORDERED 1 272 #define VIRTIOSCSI_S_HEAD 2 273 #define VIRTIOSCSI_S_ACA 3 274 275 #define VIRTIOSCSI_T_TMF 0 276 #define VIRTIOSCSI_T_TMF_ABORT_TASK 0 277 #define VIRTIOSCSI_T_TMF_ABORT_TASK_SET 1 278 #define VIRTIOSCSI_T_TMF_CLEAR_ACA 2 279 #define VIRTIOSCSI_T_TMF_CLEAR_TASK_SET 3 280 #define VIRTIOSCSI_T_TMF_I_T_NEXUS_RESET 4 281 #define VIRTIOSCSI_T_TMF_LOGICAL_UNIT_RESET 5 282 #define VIRTIOSCSI_T_TMF_QUERY_TASK 6 283 #define VIRTIOSCSI_T_TMF_QUERY_TASK_SET 7 263 284 264 285 typedef struct virtio_scsi_ctrl_tmf … … 275 296 /* command-specific response values */ 276 297 277 #define VIRTIO _SCSI_S_FUNCTION_COMPLETE 0278 #define VIRTIO _SCSI_S_FUNCTION_SUCCEEDED 10279 #define VIRTIO _SCSI_S_FUNCTION_REJECTED 11280 281 #define VIRTIO _SCSI_T_AN_QUERY 1 /** Asynchronous notification query */282 #define VIRTIO _SCSI_T_AN_SUBSCRIBE 2 /** Asynchronous notification subscription */298 #define VIRTIOSCSI_S_FUNCTION_COMPLETE 0 299 #define VIRTIOSCSI_S_FUNCTION_SUCCEEDED 10 300 #define VIRTIOSCSI_S_FUNCTION_REJECTED 11 301 302 #define VIRTIOSCSI_T_AN_QUERY 1 /** Asynchronous notification query */ 303 #define VIRTIOSCSI_T_AN_SUBSCRIBE 2 /** Asynchronous notification subscription */ 283 304 284 305 typedef struct virtio_scsi_ctrl_an … … 293 314 } VIRTIOSCSICTRLAN, *PVIRTIOSCSICTRLAN; 294 315 295 #define VIRTIO _SCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2296 #define VIRTIO _SCSI_EVT_ASYNC_POWER_MGMT 4297 #define VIRTIO _SCSI_EVT_ASYNC_EXTERNAL_REQUEST 8298 #define VIRTIO _SCSI_EVT_ASYNC_MEDIA_CHANGE 16299 #define VIRTIO _SCSI_EVT_ASYNC_MULTI_HOST 32300 #define VIRTIO _SCSI_EVT_ASYNC_DEVICE_BUSY 64316 #define VIRTIOSCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2 317 #define VIRTIOSCSI_EVT_ASYNC_POWER_MGMT 4 318 #define VIRTIOSCSI_EVT_ASYNC_EXTERNAL_REQUEST 8 319 #define VIRTIOSCSI_EVT_ASYNC_MEDIA_CHANGE 16 320 #define VIRTIOSCSI_EVT_ASYNC_MULTI_HOST 32 321 #define VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY 64 301 322 302 323 /** Device operation: controlq */ … … 308 329 } VIRTIOSCSICTRL, *PVIRTIOSCSICTRL; 309 330 310 #define VIRTIO _SCSI_T_NO_EVENT 0311 312 #define VIRTIO _SCSI_T_TRANSPORT_RESET 1313 #define VIRTIO _SCSI_T_ASYNC_NOTIFY 2 /** Asynchronous notification */314 #define VIRTIO _SCSI_T_PARAM_CHANGE 3315 316 #define VIRTIO _SCSI_EVT_RESET_HARD 0317 #define VIRTIO _SCSI_EVT_RESET_RESCAN 1318 #define VIRTIO _SCSI_EVT_RESET_REMOVED 2331 #define VIRTIOSCSI_T_NO_EVENT 0 332 333 #define VIRTIOSCSI_T_TRANSPORT_RESET 1 334 #define VIRTIOSCSI_T_ASYNC_NOTIFY 2 /** Asynchronous notification */ 335 #define VIRTIOSCSI_T_PARAM_CHANGE 3 336 337 #define VIRTIOSCSI_EVT_RESET_HARD 0 338 #define VIRTIOSCSI_EVT_RESET_RESCAN 1 339 #define VIRTIOSCSI_EVT_RESET_REMOVED 2 319 340 320 341 /** Device operation: eventq */ 321 342 322 #define VIRTIO _SCSI_T_EVENTS_MISSED 0x80000000343 #define VIRTIOSCSI_T_EVENTS_MISSED 0x80000000 323 344 typedef struct virtio_scsi_event { 324 345 // Device-writable part … … 352 373 } 353 374 #endif 375 376 /** 377 * Turns on/off the write status LED. 378 * 379 * @returns VBox status code. 380 * @param pState Pointer to the device state structure. 381 * @param fOn New LED state. 382 */ 383 void virtioScsiSetWriteLed(PVIRTIOSCSITARGET pTarget, bool fOn) 384 { 385 LogFlow(("%s virtioSetWriteLed: %s\n", pTarget->pszLunName, fOn ? "on" : "off")); 386 if (fOn) 387 pTarget->led.Asserted.s.fWriting = pTarget->led.Actual.s.fWriting = 1; 388 else 389 pTarget->led.Actual.s.fWriting = fOn; 390 } 391 392 /** 393 * Turns on/off the read status LED. 394 * 395 * @returns VBox status code. 396 * @param pState Pointer to the device state structure. 397 * @param fOn New LED state. 398 */ 399 void virtioScsiSetReadLed(PVIRTIOSCSITARGET pTarget, bool fOn) 400 { 401 LogFlow(("%s virtioSetReadLed: %s\n", pTarget->pszLunName, fOn ? "on" : "off")); 402 if (fOn) 403 pTarget->led.Asserted.s.fReading = pTarget->led.Actual.s.fReading = 1; 404 else 405 pTarget->led.Actual.s.fReading = fOn; 406 } 354 407 355 408 /** … … 418 471 return VINF_SUCCESS; 419 472 } 420 421 /**422 * Memory mapped I/O Handler for read operations.423 *424 * @returns VBox status code.425 *426 * @param pDevIns The device instance.427 * @param pvUser User argument.428 * @param GCPhysAddr Physical address (in GC) where the read starts.429 * @param pv Where to store the result.430 * @param cb Number of bytes read.431 */432 PDMBOTHCBDECL(int) virtioScsiMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)433 {434 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb);435 LogFunc(("Read from MMIO area\n"));436 return VINF_SUCCESS;437 }438 439 /**440 * Memory mapped I/O Handler for write operations.441 *442 * @returns VBox status code.443 *444 * @param pDevIns The device instance.445 * @param pvUser User argument.446 * @param GCPhysAddr Physical address (in GC) where the read starts.447 * @param pv Where to fetch the result.448 * @param cb Number of bytes to write.449 */450 PDMBOTHCBDECL(int) virtioScsiMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)451 {452 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb);453 LogFunc(("Write to MMIO area\n"));454 return VINF_SUCCESS;455 }456 457 /**458 * @callback_method_impl{FNPCIIOREGIONMAP}459 */460 static DECLCALLBACK(int) virtioScsiR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,461 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)462 {463 RT_NOREF(pPciDev, iRegion);464 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI);465 int rc = VINF_SUCCESS;466 467 Assert(cb >= 32);468 469 switch (iRegion)470 {471 case 0:472 LogFunc(("virtio-scsi controller MMIO mapped at GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddress, cb));473 474 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */475 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,476 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,477 virtioScsiMMIOWrite, virtioScsiMMIORead,478 "virtio-scsi MMIO");479 pThis->GCPhysMMIOBase = RT_SUCCESS(rc) ? GCPhysAddress : 0;480 return rc;481 case 1:482 /* VirtIO 1.0 doesn't uses Port I/O (Virtio 0.95 e.g. "legacy", does) */483 AssertMsgFailed(("virtio-scsi: Port I/O not supported by this Host SCSI device\n"));484 default:485 AssertMsgFailed(("Invalid enmType=%d\n", enmType));486 }487 return VERR_GENERAL_FAILURE; /* Should never get here */488 }489 490 473 491 474 /** … … 654 637 655 638 if (pThis->pMediaNotify) 656 virtioSetWriteLed(&(pThis->virtioState), false); 657 } 658 639 virtioScsiSetWriteLed(pTarget, false); 640 } 659 641 660 642 /** … … 680 662 681 663 /** 664 * Gets the pointer to the status LED of a unit. 665 * 666 * @returns VBox status code. 667 * @param pInterface Pointer to the interface structure containing the called function pointer. 668 * @param iLUN The unit which status LED we desire. 669 * @param ppLed Where to store the LED pointer. 670 */ 671 static DECLCALLBACK(int) virtioScsiR3TargetQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed) 672 { 673 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, ILed); 674 if (iLUN == 0) 675 { 676 *ppLed = &pTarget->led; 677 Assert((*ppLed)->u32Magic == PDMLED_MAGIC); 678 return VINF_SUCCESS; 679 } 680 return VERR_PDM_LUN_NOT_FOUND; 681 } 682 683 684 /** 685 * Gets the pointer to the status LED of a unit. 686 * 687 * @returns VBox status code. 688 * @param pInterface Pointer to the interface structure containing the called function pointer. 689 * @param iLUN The unit which status LED we desire. 690 * @param ppLed Where to store the LED pointer. 691 */ 692 static DECLCALLBACK(int) virtioScsiR3DeviceQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed) 693 { 694 PVIRTIOSCSI pThis = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, ILeds); 695 if (iLUN < pThis->cTargets) 696 { 697 *ppLed = &pThis->aTargetInstances[iLUN].led; 698 Assert((*ppLed)->u32Magic == PDMLED_MAGIC); 699 return VINF_SUCCESS; 700 } 701 return VERR_PDM_LUN_NOT_FOUND; 702 } 703 704 /** 705 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 706 */ 707 static DECLCALLBACK(void *) virtioScsiR3TargetQueryInterface(PPDMIBASE pInterface, const char *pszIID) 708 { 709 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IBase); 710 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pTarget->IBase); 711 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pTarget->IMediaPort); 712 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pTarget->IMediaExPort); 713 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pTarget->ILed); 714 return NULL; 715 } 716 717 /** 682 718 * virtio-scsi VirtIO Device-specific capabilities read callback 683 719 * (other VirtIO capabilities and features are handled in VirtIO implementation) … … 691 727 { 692 728 /*TBD*/ 693 LogF lowFunc(("Read from Device-Specific capabilities, callback to VirtIO client\n"));729 LogFunc(("Read from Device-Specific capabilities\n")); 694 730 RT_NOREF(pDevIns); 695 731 RT_NOREF(GCPhysAddr); … … 712 748 { 713 749 /*TBD*/ 714 LogF lowFunc(("Write to Device-Specific capabilities, callback to VirtIO client\n"));750 LogFunc(("Write to Device-Specific capabilities\n")); 715 751 RT_NOREF(pDevIns); 716 752 RT_NOREF(GCPhysAddr); … … 721 757 } 722 758 759 760 /** 761 * Memory mapped I/O Handler for read operations. 762 * 763 * @returns VBox status code. 764 * 765 * @param pDevIns The device instance. 766 * @param pvUser User argument. 767 * @param GCPhysAddr Physical address (in GC) where the read starts. 768 * @param pv Where to store the result. 769 * @param cb Number of bytes read. 770 */ 771 PDMBOTHCBDECL(int) virtioScsiMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 772 { 773 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb); 774 LogFunc(("Read from MMIO area\n")); 775 return VINF_SUCCESS; 776 } 777 778 /** 779 * Memory mapped I/O Handler for write operations. 780 * 781 * @returns VBox status code. 782 * 783 * @param pDevIns The device instance. 784 * @param pvUser User argument. 785 * @param GCPhysAddr Physical address (in GC) where the read starts. 786 * @param pv Where to fetch the result. 787 * @param cb Number of bytes to write. 788 */ 789 PDMBOTHCBDECL(int) virtioScsiMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb) 790 { 791 RT_NOREF_PV(pDevIns); RT_NOREF_PV(pvUser); RT_NOREF_PV(GCPhysAddr); RT_NOREF_PV(pv); RT_NOREF_PV(cb); 792 LogFunc(("Write to MMIO area\n")); 793 return VINF_SUCCESS; 794 } 795 796 /** 797 * @callback_method_impl{FNPCIIOREGIONMAP} 798 */ 799 static DECLCALLBACK(int) virtioScsiR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 800 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType) 801 { 802 RT_NOREF(pPciDev, iRegion); 803 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 804 int rc = VINF_SUCCESS; 805 806 Assert(cb >= 32); 807 808 switch (iRegion) 809 { 810 case 0: 811 LogFunc(("virtio-scsi MMIO mapped at GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddress, cb)); 812 813 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 814 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 815 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 816 virtioScsiMMIOWrite, virtioScsiMMIORead, 817 "virtio-scsi MMIO"); 818 pThis->GCPhysMMIOBase = RT_SUCCESS(rc) ? GCPhysAddress : 0; 819 return rc; 820 case 1: 821 /* VirtIO 1.0 doesn't uses Port I/O (Virtio 0.95 e.g. "legacy", does) */ 822 AssertMsgFailed(("virtio-scsi: Port I/O not supported by this Host SCSI device\n")); 823 default: 824 AssertMsgFailed(("Invalid enmType=%d\n", enmType)); 825 } 826 return VERR_GENERAL_FAILURE; /* Should never get here */ 827 } 828 829 /** 830 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 831 */ 832 static DECLCALLBACK(void *) virtioScsiR3DeviceQueryInterface(PPDMIBASE pInterface, const char *pszIID) 833 { 834 PVIRTIOSCSI pVirtioScsi = RT_FROM_MEMBER(pInterface, VIRTIOSCSI, IBase); 835 836 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pVirtioScsi->IBase); 837 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pVirtioScsi->ILeds); 838 839 return NULL; 840 } 841 842 723 843 /** 724 844 * Detach notification. … … 737 857 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN]; 738 858 739 Log (("%s:\n", __FUNCTION__));859 LogFunc(("")); 740 860 741 861 AssertMsg(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG, … … 746 866 */ 747 867 pTarget->fPresent = false; 748 pTarget->pUpstreamDrvBase = NULL; 749 } 750 751 752 /** 753 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 754 */ 755 static DECLCALLBACK(void *) virtioScsiR3DeviceQueryInterface(PPDMIBASE pInterface, const char *pszIID) 756 { 757 PPDMDRVINS pDevIns = PDMIBASE_2_PDMDRV(pInterface); 758 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IBase); 759 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDevIns->IBase); 760 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pTarget->IMediaPort); 761 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pTarget->IMediaExPort); 762 763 /* This call back is necessary to get Status / LED support */ 764 return virtioQueryInterface(pInterface, pszIID); 765 766 return NULL; 868 pTarget->pDrvBase = NULL; 767 869 } 768 870 … … 792 894 793 895 /* the usual paranoia */ 794 AssertRelease(!pTarget->p UpstreamDrvBase);896 AssertRelease(!pTarget->pDrvBase); 795 897 Assert(pTarget->iLUN == iLUN); 796 898 … … 800 902 */ 801 903 rc = PDMDevHlpDriverAttach(pDevIns, pTarget->iLUN, &pDevIns->IBase, 802 &pTarget->p UpstreamDrvBase, (const char *)&pTarget->pszLunName);904 &pTarget->pDrvBase, (const char *)&pTarget->pszLunName); 803 905 if (RT_SUCCESS(rc)) 804 906 pTarget->fPresent = true; … … 809 911 { 810 912 pTarget->fPresent = false; 811 pTarget->p UpstreamDrvBase = NULL;913 pTarget->pDrvBase = NULL; 812 914 } 813 915 return rc; … … 823 925 } 824 926 825 static DECLCALLBACK(int) virtioScsiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg) 826 { 927 static DECLCALLBACK(int) virtioScsiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg){ 827 928 828 929 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 930 829 931 PVIRTIOSCSI pThis = PDMINS_2_DATA(pDevIns, PVIRTIOSCSI); 830 932 int rc = VINF_SUCCESS; 831 933 bool fBootable = true; 934 935 pThis->pDevInsR3 = pDevIns; 936 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 937 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 832 938 833 939 LogFunc(("PDM device instance: %d\n", iInstance)); … … 857 963 858 964 VIRTIOPCIPARAMS virtioPciParams, *pVirtioPciParams = &virtioPciParams; 859 pVirtioPciParams->uDeviceId = PCI_DEVICE_ID_VIRTIO _SCSI_HOST;965 pVirtioPciParams->uDeviceId = PCI_DEVICE_ID_VIRTIOSCSI_HOST; 860 966 pVirtioPciParams->uClassBase = PCI_CLASS_BASE_MASS_STORAGE; 861 967 pVirtioPciParams->uClassSub = PCI_CLASS_SUB_SCSI_STORAGE_CONTROLLER; 862 968 pVirtioPciParams->uClassProg = PCI_CLASS_PROG_UNSPECIFIED; 863 pVirtioPciParams->uSubsystemId = PCI_DEVICE_ID_VIRTIO _SCSI_HOST; /* Virtio 1.0 spec allows PCI Device ID here */969 pVirtioPciParams->uSubsystemId = PCI_DEVICE_ID_VIRTIOSCSI_HOST; /* Virtio 1.0 spec allows PCI Device ID here */ 864 970 pVirtioPciParams->uInterruptLine = 0x00; 865 971 pVirtioPciParams->uInterruptPin = 0x01; 866 972 867 973 PVIRTIOSTATE pVirtio = &(pThis->virtioState); 868 pDevIns->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 869 870 rc = virtioConstruct(pDevIns, pVirtio, iInstance, pVirtioPciParams, 871 VIRTIO_SCSI_NAME_FMT, VIRTIO_SCSI_N_QUEUES, VIRTIO_SCSI_REGION_PCI_CAP, 872 virtioScsiR3DevCapRead, virtioScsiR3DevCapWrite, sizeof(VIRTIODEVCAP)); 974 975 pThis->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface; 976 rc = virtioConstruct(pDevIns, pVirtio, iInstance, pVirtioPciParams, &pThis->pVirtioCallbacks, 977 VIRTIOSCSI_NAME_FMT, VIRTIOSCSI_N_QUEUES, VIRTIOSCSI_REGION_PCI_CAP, 978 virtioScsiR3DevCapRead, virtioScsiR3DevCapWrite, 979 0 /* cbDevSpecificCap */, 980 0 /* uNotifyOffMultiplier */); 981 982 873 983 if (RT_FAILURE(rc)) 874 984 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO")); 875 985 876 rc = PDMDevHlpPCIIORegionRegister(pDevIns, VIRTIO_SCSI_REGION_MEM_IO, 32, 986 pThis->pVirtioCallbacks->pfnSetHostFeatures(pVirtio, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED); 987 988 rc = PDMDevHlpPCIIORegionRegister(pDevIns, VIRTIOSCSI_REGION_MEM_IO, 32, 877 989 PCI_ADDRESS_SPACE_MEM, virtioScsiR3Map); 878 990 if (RT_FAILURE(rc)) … … 903 1015 PVIRTIOSCSITARGET pTarget = &pThis->aTargetInstances[iLUN]; 904 1016 905 if (RTStrAPrintf(&pTarget->pszLunName, " VIRTIOSCSI%u", iLUN) < 0)1017 if (RTStrAPrintf(&pTarget->pszLunName, "vSCSI%u", iLUN) < 0) 906 1018 AssertLogRelFailedReturn(VERR_NO_MEMORY); 907 1019 … … 909 1021 pTarget->iLUN = iLUN; 910 1022 pTarget->pVirtioScsiR3 = pThis; 1023 1024 pTarget->IBase.pfnQueryInterface = virtioScsiR3TargetQueryInterface; 1025 911 1026 /* IMediaPort and IMediaExPort interfaces provide callbacks for VD media and downstream driver access */ 912 1027 pTarget->IMediaPort.pfnQueryDeviceLocation = virtioScsiR3QueryDeviceLocation; … … 918 1033 pTarget->IMediaExPort.pfnIoReqQueryBuf = NULL; 919 1034 pTarget->IMediaExPort.pfnIoReqQueryDiscardRanges = NULL; 1035 pTarget->IBase.pfnQueryInterface = virtioScsiR3TargetQueryInterface; 1036 pTarget->ILed.pfnQueryStatusLed = virtioScsiR3TargetQueryStatusLed; 1037 pThis->ILeds.pfnQueryStatusLed = virtioScsiR3DeviceQueryStatusLed; 1038 pTarget->led.u32Magic = PDMLED_MAGIC; 920 1039 921 1040 LogFunc(("Attaching LUN: %s\n", pTarget->pszLunName)); … … 923 1042 /* Attach this SCSI driver (upstream driver pre-determined statically outside this module) */ 924 1043 AssertReturn(iLUN < RT_ELEMENTS(pThis->aTargetInstances), VERR_PDM_NO_SUCH_LUN); 925 rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &p DevIns->IBase, &pTarget->pUpstreamDrvBase, (const char *)&pTarget->pszLunName);1044 rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pTarget->IBase, &pTarget->pDrvBase, (const char *)&pTarget->pszLunName); 926 1045 if (RT_SUCCESS(rc)) 927 1046 { 928 1047 pTarget->fPresent = true; 929 1048 930 pTarget->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pTarget->p UpstreamDrvBase, PDMIMEDIA);1049 pTarget->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pTarget->pDrvBase, PDMIMEDIA); 931 1050 AssertMsgReturn(VALID_PTR(pTarget->pDrvMedia), 932 1051 ("virtio-scsi configuration error: LUN#%d missing basic media interface!\n", pTarget->iLUN), 933 1052 VERR_PDM_MISSING_INTERFACE); 934 1053 935 936 pTarget->pDrvMediaEx = PDMIBASE_QUERY_INTERFACE(pTarget->pUpstreamDrvBase, PDMIMEDIAEX);937 1054 /* Get the extended media interface. */ 1055 pTarget->pDrvMediaEx = PDMIBASE_QUERY_INTERFACE(pTarget->pDrvBase, PDMIMEDIAEX); 1056 AssertMsgReturn(VALID_PTR(pTarget->pDrvMediaEx), 938 1057 ("virtio-scsi configuration error: LUN#%d missing extended media interface!\n", pTarget->iLUN), 939 1058 VERR_PDM_MISSING_INTERFACE); 940 1059 941 // pk: Not sure if this is needed here yet with VirtIO or DrvScsi, will investigate after basic VirtIO working. 942 // rc = pTarget->pDrvMediaEx->pfnIoReqAllocSizeSet(pTarget->pDrvMediaEx, sizeof(BUSLOGICREQ)); 943 // AssertMsgRCReturn(rc, ("BusLogic configuration error: LUN#%u: Failed to set I/O request size!", pTarget->iLUN), 1060 rc = pTarget->pDrvMediaEx->pfnIoReqAllocSizeSet(pTarget->pDrvMediaEx, REQ_ALLOC_SIZE /*TBD*/); 1061 AssertMsgReturn(VALID_PTR(pTarget->pDrvMediaEx), 1062 ("virtio-scsi configuration error: LUN#%u: Failed to set I/O request size!\n", pTarget->iLUN), 1063 rc); 944 1064 945 1065 } … … 947 1067 { 948 1068 pTarget->fPresent = false; 949 pTarget->p UpstreamDrvBase = NULL;1069 pTarget->pDrvBase = NULL; 950 1070 rc = VINF_SUCCESS; 951 1071 Log(("virtio-scsi: no driver attached to device %s\n", pTarget->pszLunName)); … … 964 1084 if (RT_FAILURE(rc)) 965 1085 return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi cannot register save state handlers")); 1086 1087 /* Status driver */ 1088 PPDMIBASE pUpBase; 1089 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pUpBase, "Status Port"); 1090 if (RT_FAILURE(rc)) 1091 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the status LUN")); 1092 966 1093 /* 967 1094 * Register the debugger info callback.
Note:
See TracChangeset
for help on using the changeset viewer.