- Timestamp:
- Oct 31, 2012 6:30:35 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/UsbMsd.cpp
r40282 r43788 39 39 * @{ */ 40 40 #define USBMSD_STR_ID_MANUFACTURER 1 41 #define USBMSD_STR_ID_PRODUCT 41 #define USBMSD_STR_ID_PRODUCT_HD 2 42 42 /** @} */ 43 43 44 /** @name USB MSD vendor and product IDs 45 * @{ */ 46 #define VBOX_USB_VENDOR 0x80EE 47 #define USBMSD_PID_HD 0x0030 48 #define USBMSD_PID_CD 0x0031 49 /** @} */ 44 50 45 51 /******************************************************************************* 46 52 * Structures and Typedefs * 47 53 *******************************************************************************/ 48 /** 49 * USB Command block wrapper (MSD/SCSI). 54 55 /** 56 * USB MSD Command Block Wrapper or CBW. The command block 57 * itself (CBWCB) contains protocol-specific data (here SCSI). 50 58 */ 51 59 #pragma pack(1) … … 72 80 73 81 /** 74 * USB Command Status Wrapper (MSD/SCSI).82 * USB MSD Command Status Wrapper or CSW. 75 83 */ 76 84 #pragma pack(1) … … 255 263 static const PDMUSBDESCCACHESTRING g_aUsbMsdStrings_en_US[] = 256 264 { 257 { USBMSD_STR_ID_MANUFACTURER, "VirtualBox" 258 { USBMSD_STR_ID_PRODUCT , "VirtualBox MSD" },265 { USBMSD_STR_ID_MANUFACTURER, "VirtualBox" }, 266 { USBMSD_STR_ID_PRODUCT_HD, "USB Harddisk" }, 259 267 }; 260 268 … … 272 280 /* .bEndpointAddress = */ 0x81 /* ep=1, in */, 273 281 /* .bmAttributes = */ 2 /* bulk */, 274 /* .wMaxPacketSize = */ 0x200 /* or 64? */,275 /* .bInterval = */ 0 xff,282 /* .wMaxPacketSize = */ 64,//512 /* or 64? */, <-- depends on device speed! 283 /* .bInterval = */ 0, 276 284 }, 277 285 /* .pvMore = */ NULL, … … 285 293 /* .bEndpointAddress = */ 0x02 /* ep=2, out */, 286 294 /* .bmAttributes = */ 2 /* bulk */, 287 /* .wMaxPacketSize = */ 0x200 /* or 64? */,288 /* .bInterval = */ 0 xff,295 /* .wMaxPacketSize = */ 64,//512 /* or 64? */, <-- depends on device speed! 296 /* .bInterval = */ 0, 289 297 }, 290 298 /* .pvMore = */ NULL, … … 313 321 }; 314 322 315 static const VUSBINTERFACE g_aUsbMsdInterfaces[ 2] =323 static const VUSBINTERFACE g_aUsbMsdInterfaces[] = 316 324 { 317 325 { &g_UsbMsdInterfaceDesc, /* .cSettings = */ 1 }, … … 330 338 /* .MaxPower = */ 50 /* 100mA */ 331 339 }, 332 NULL, 333 &g_aUsbMsdInterfaces[0] 340 NULL, /* pvMore */ 341 &g_aUsbMsdInterfaces[0], 342 NULL /* pvOriginal */ 334 343 }; 335 344 … … 338 347 /* .bLength = */ sizeof(g_UsbMsdDeviceDesc), 339 348 /* .bDescriptorType = */ VUSB_DT_DEVICE, 340 /* .bcdUsb = */ 0x200, 349 /* .bcdUsb = */ 0x200, /* USB 2.0 */ 341 350 /* .bDeviceClass = */ 0 /* Class specified in the interface desc. */, 342 351 /* .bDeviceSubClass = */ 0 /* Subclass specified in the interface desc. */, 343 /* .bDeviceProtocol = */ 0 x50/* Protocol specified in the interface desc. */,352 /* .bDeviceProtocol = */ 0 /* Protocol specified in the interface desc. */, 344 353 /* .bMaxPacketSize0 = */ 64, 345 /* .idVendor = */ 0x4200,346 /* .idProduct = */ 0x0042,347 /* .bcdDevice = */ 0x0100, 354 /* .idVendor = */ VBOX_USB_VENDOR, 355 /* .idProduct = */ USBMSD_PID_HD, 356 /* .bcdDevice = */ 0x0100, /* 1.0 */ 348 357 /* .iManufacturer = */ USBMSD_STR_ID_MANUFACTURER, 349 /* .iProduct = */ USBMSD_STR_ID_PRODUCT ,358 /* .iProduct = */ USBMSD_STR_ID_PRODUCT_HD, 350 359 /* .iSerialNumber = */ 0, 351 360 /* .bNumConfigurations = */ 1 361 }; 362 363 static const VUSBDEVICEQUALIFIER g_UsbMsdDeviceQualifier = 364 { 365 /* .bLength = */ sizeof(g_UsbMsdDeviceQualifier), 366 /* .bDescriptorType = */ VUSB_DT_DEVICE_QUALIFIER, 367 /* .bcdUsb = */ 0x200, /* USB 2.0 */ 368 /* .bDeviceClass = */ 0 /* Class specified in the interface desc. */, 369 /* .bDeviceSubClass = */ 0 /* Subclass specified in the interface desc. */, 370 /* .bDeviceProtocol = */ 0 /* Protocol specified in the interface desc. */, 371 /* .bMaxPacketSize0 = */ 64, 372 /* .bNumConfigurations = */ 1, 373 /* .bReserved = */ 0 352 374 }; 353 375 … … 636 658 637 659 pUrb->enmStatus = VUSBSTATUS_OK; 638 pUrb->cbData = cbData;660 pUrb->cbData = (uint32_t)cbData; 639 661 640 662 usbMsdLinkDone(pThis, pUrb); … … 665 687 && pReq->enmState == USBMSDREQSTATE_EXECUTING) 666 688 { 667 /* Don't try deal with the set config variant nor multiple build-only689 /* Don't try to deal with the set config variant nor multiple build-only 668 690 mass storage resets. */ 669 691 if (pThis->pResetUrb && (pUrb || fSetConfig)) … … 785 807 break; 786 808 787 /* Process it asthe normal way. */809 /* Process it the normal way. */ 788 810 usbMsdHandleBulkDevToHost(pThis, &pThis->aEps[1], pUrb); 789 811 } … … 914 936 if ((pCbw->bmCBWFlags & USBCBW_DIR_MASK) != USBCBW_DIR_IN) 915 937 return usbMsdScsiIllegalRequest(pThis, pReq, SCSI_ASC_INVALID_MESSAGE, 0, "direction"); 916 if (pCbw->bCBWCBLength !=6)938 if (pCbw->bCBWCBLength < 6) 917 939 return usbMsdScsiIllegalRequest(pThis, pReq, SCSI_ASC_INVALID_MESSAGE, 0, "length"); 918 940 if ((pCbw->CBWCB[1] >> 5) != pCbw->bCBWLun) … … 920 942 if (pCbw->bCBWLun != 0) 921 943 return usbMsdScsiIllegalRequest(pThis, pReq, SCSI_ASC_INVALID_MESSAGE, 0, "lun0"); 922 if ( (pCbw->CBWCB[4] < 6) != pCbw->bCBWLun)944 if (pCbw->CBWCB[4] < 6) 923 945 return usbMsdScsiIllegalRequest(pThis, pReq, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0, "out length"); 924 946 … … 1001 1023 1002 1024 /** 1003 * Handle s request sent to the out-bound (to device) bulk pipe.1025 * Handle requests sent to the outbound (to device) bulk pipe. 1004 1026 */ 1005 1027 static int usbMsdHandleBulkHostToDev(PUSBMSD pThis, PUSBMSDEP pEp, PVUSBURB pUrb) … … 1035 1057 return usbMsdCompleteStall(pThis, NULL, pUrb, "BAD CBW"); 1036 1058 } 1037 Log(("usbMsd: CBW: dCBWSignature=%#x dCBWTag=%#x dCBWDataTransferLength=%#x bmCBWFlags=%#x bCBWLun=%#x bCBWCBLength=%#x cbData=%#x fShortNotOk=%RTbool\n",1038 pCbw->dCBWSignature, pCbw->dCBWTag, pCbw->dCBWDataTransferLength, pCbw->bmCBWFlags, pCbw->bCBWLun, pCbw->bCBWCBLength, pUrb->cbData, pUrb->fShortNotOk));1039 1059 if (pCbw->dCBWSignature != USBCBW_SIGNATURE) 1040 1060 { … … 1042 1062 return usbMsdCompleteStall(pThis, NULL, pUrb, "Bad CBW"); 1043 1063 } 1064 Log(("usbMsd: CBW: dCBWTag=%#x dCBWDataTransferLength=%#x bmCBWFlags=%#x bCBWLun=%#x bCBWCBLength=%#x cbData=%#x fShortNotOk=%RTbool\n", 1065 pCbw->dCBWTag, pCbw->dCBWDataTransferLength, pCbw->bmCBWFlags, pCbw->bCBWLun, pCbw->bCBWCBLength, pUrb->cbData, pUrb->fShortNotOk)); 1044 1066 if (pCbw->bmCBWFlags & ~USBCBW_DIR_MASK) 1045 1067 { … … 1149 1171 } 1150 1172 } 1151 return usbMsdCompleteOk(pThis, pUrb, 0);1173 return usbMsdCompleteOk(pThis, pUrb, cbData); 1152 1174 } 1153 1175 … … 1169 1191 1170 1192 /** 1171 * Handle s request sent to the in-bound (to host) bulk pipe.1193 * Handle requests sent to the inbound (to host) bulk pipe. 1172 1194 */ 1173 1195 static int usbMsdHandleBulkDevToHost(PUSBMSD pThis, PUSBMSDEP pEp, PVUSBURB pUrb) … … 1217 1239 case USBMSDREQSTATE_STATUS: 1218 1240 { 1219 /** @todo !fShortNotOk and CSW request? */ 1220 if (pUrb->cbData != sizeof(USBCSW)) 1221 { 1222 Log(("usbMsd: Unexpected status request size: %#x (expected %#x)\n", pUrb->cbData, sizeof(USBCSW))); 1241 if ((pUrb->cbData < sizeof(USBCSW)) || (pUrb->cbData > sizeof(USBCSW) && pUrb->fShortNotOk)) 1242 { 1243 Log(("usbMsd: Unexpected status request size: %#x (expected %#x), fShortNotOK=%RTbool\n", pUrb->cbData, sizeof(USBCSW), pUrb->fShortNotOk)); 1223 1244 return usbMsdCompleteStall(pThis, NULL, pUrb, "Invalid CSW size"); 1224 1245 } … … 1233 1254 ? USBCSW_STATUS_FAILED 1234 1255 : USBCSW_STATUS_PHASE_ERROR; 1256 /** @todo the following is not always accurate; VSCSI needs 1257 * to implement residual counts properly! */ 1235 1258 if ((pReq->Cbw.bmCBWFlags & USBCBW_DIR_MASK) == USBCBW_DIR_OUT) 1236 1259 pCsw->dCSWDataResidue = pCsw->bCSWStatus == USBCSW_STATUS_OK … … 1239 1262 else 1240 1263 pCsw->dCSWDataResidue = pCsw->bCSWStatus == USBCSW_STATUS_OK 1241 ? pReq->ScsiReq.cbScatterGather1242 : 0;1243 Log(("usbMsd HandleBulkDevToHost: CSW: dCSWTag=%#x bCSWStatus=%d dCSWDataResidue=%#x\n",1264 ? 0 1265 : pReq->ScsiReq.cbScatterGather; 1266 Log(("usbMsd: CSW: dCSWTag=%#x bCSWStatus=%d dCSWDataResidue=%#x\n", 1244 1267 pCsw->dCSWTag, pCsw->bCSWStatus, pCsw->dCSWDataResidue)); 1245 1268 … … 1334 1357 switch (pSetup->wValue >> 8) 1335 1358 { 1359 uint32_t cbCopy; 1360 1336 1361 case VUSB_DT_STRING: 1337 1362 Log(("usbMsd: GET_DESCRIPTOR DT_STRING wValue=%#x wIndex=%#x\n", pSetup->wValue, pSetup->wIndex)); 1338 1363 break; 1364 case VUSB_DT_DEVICE_QUALIFIER: 1365 Log(("usbMsd: GET_DESCRIPTOR DT_DEVICE_QUALIFIER wValue=%#x wIndex=%#x\n", pSetup->wValue, pSetup->wIndex)); 1366 /* Returned data is written after the setup message. */ 1367 cbCopy = pUrb->cbData - sizeof(*pSetup); 1368 cbCopy = RT_MIN(cbCopy, sizeof(g_UsbMsdDeviceQualifier)); 1369 memcpy(&pUrb->abData[sizeof(*pSetup)], &g_UsbMsdDeviceQualifier, cbCopy); 1370 return usbMsdCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup)); 1339 1371 default: 1340 1372 Log(("usbMsd: GET_DESCRIPTOR, huh? wValue=%#x wIndex=%#x\n", pSetup->wValue, pSetup->wIndex));
Note:
See TracChangeset
for help on using the changeset viewer.