Changeset 59738 in vbox for trunk/src/VBox/Devices/USB/VUSBUrb.cpp
- Timestamp:
- Feb 19, 2016 11:55:56 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/VUSBUrb.cpp
r59737 r59738 5 5 6 6 /* 7 * Copyright (C) 2006-201 5Oracle Corporation7 * Copyright (C) 2006-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 53 53 * Internal Functions * 54 54 *********************************************************************************************************************************/ 55 static PVUSBCTRLEXTRA vusbMsgAllocExtraData(PVUSBURB pUrb);56 57 58 #ifdef LOG_ENABLED59 DECLINLINE(const char *) vusbUrbStatusName(VUSBSTATUS enmStatus)60 {61 /** Strings for the URB statuses. */62 static const char * const s_apszNames[] =63 {64 "OK",65 "STALL",66 "ERR_DNR",67 "ERR_CRC",68 "DATA_UNDERRUN",69 "DATA_OVERRUN",70 "NOT_ACCESSED",71 "7", "8", "9", "10", "11", "12", "13", "14", "15"72 };73 74 return enmStatus < (int)RT_ELEMENTS(s_apszNames)75 ? s_apszNames[enmStatus]76 : enmStatus == VUSBSTATUS_INVALID77 ? "INVALID"78 : "??";79 }80 81 DECLINLINE(const char *) vusbUrbDirName(VUSBDIRECTION enmDir)82 {83 /** Strings for the URB directions. */84 static const char * const s_apszNames[] =85 {86 "setup",87 "in",88 "out"89 };90 91 return enmDir < (int)RT_ELEMENTS(s_apszNames)92 ? s_apszNames[enmDir]93 : "??";94 }95 96 DECLINLINE(const char *) vusbUrbTypeName(VUSBXFERTYPE enmType)97 {98 /** Strings for the URB types. */99 static const char * const s_apszName[] =100 {101 "control-part",102 "isochronous",103 "bulk",104 "interrupt",105 "control"106 };107 108 return enmType < (int)RT_ELEMENTS(s_apszName)109 ? s_apszName[enmType]110 : "??";111 }112 113 DECLINLINE(const char *) GetScsiErrCd(uint8_t ScsiErr)114 {115 switch (ScsiErr)116 {117 case 0: return "?";118 }119 return "?";120 }121 122 DECLINLINE(const char *) GetScsiKCQ(uint8_t Key, uint8_t ASC, uint8_t ASCQ)123 {124 switch (Key)125 {126 case 0:127 switch (RT_MAKE_U16(ASC, ASCQ))128 {129 case RT_MAKE_U16(0x00, 0x00): return "No error";130 }131 break;132 133 case 1:134 return "Soft Error";135 136 case 2:137 return "Not Ready";138 139 case 3:140 return "Medium Error";141 142 case 4:143 return "Hard Error";144 145 case 5:146 return "Illegal Request";147 148 case 6:149 return "Unit Attention";150 151 case 7:152 return "Write Protected";153 154 case 0xb:155 return "Aborted Command";156 }157 return "?";158 }159 160 161 /**162 * Logs an URB.163 *164 * Note that pUrb->pVUsb->pDev and pUrb->pVUsb->pDev->pUsbIns can all be NULL.165 */166 void vusbUrbTrace(PVUSBURB pUrb, const char *pszMsg, bool fComplete)167 {168 PVUSBDEV pDev = pUrb->pVUsb ? pUrb->pVUsb->pDev : NULL; /* Can be NULL when called from usbProxyConstruct and friends. */169 PVUSBPIPE pPipe = &pDev->aPipes[pUrb->EndPt];170 const uint8_t *pbData = pUrb->abData;171 uint32_t cbData = pUrb->cbData;172 PCVUSBSETUP pSetup = NULL;173 bool fDescriptors = false;174 static size_t s_cchMaxMsg = 10;175 size_t cchMsg = strlen(pszMsg);176 if (cchMsg > s_cchMaxMsg)177 s_cchMaxMsg = cchMsg;178 179 Log(("%s: %*s: pDev=%p[%s] rc=%s a=%i e=%u d=%s t=%s cb=%#x(%d) ts=%RU64 (%RU64 ns ago) %s\n",180 pUrb->pszDesc, s_cchMaxMsg, pszMsg,181 pDev,182 pUrb->pVUsb && pUrb->pVUsb->pDev ? pUrb->pVUsb->pDev->pUsbIns->pszName : "",183 vusbUrbStatusName(pUrb->enmStatus),184 pDev ? pDev->u8Address : -1,185 pUrb->EndPt,186 vusbUrbDirName(pUrb->enmDir),187 vusbUrbTypeName(pUrb->enmType),188 pUrb->cbData,189 pUrb->cbData,190 pUrb->pVUsb ? pUrb->pVUsb->u64SubmitTS : 0,191 pUrb->pVUsb ? RTTimeNanoTS() - pUrb->pVUsb->u64SubmitTS : 0,192 pUrb->fShortNotOk ? "ShortNotOk" : "ShortOk"));193 194 #ifndef DEBUG_bird195 if ( pUrb->enmType == VUSBXFERTYPE_CTRL196 && pUrb->enmStatus == VUSBSTATUS_OK)197 return;198 #endif199 200 if ( pUrb->enmType == VUSBXFERTYPE_MSG201 || ( pUrb->enmDir == VUSBDIRECTION_SETUP202 && pUrb->enmType == VUSBXFERTYPE_CTRL203 && cbData))204 {205 static const char * const s_apszReqDirs[] = {"host2dev", "dev2host"};206 static const char * const s_apszReqTypes[] = {"std", "class", "vendor", "reserved"};207 static const char * const s_apszReqRecipients[] = {"dev", "if", "endpoint", "other"};208 static const char * const s_apszRequests[] =209 {210 "GET_STATUS", "CLEAR_FEATURE", "2?", "SET_FEATURE",211 "4?", "SET_ADDRESS", "GET_DESCRIPTOR", "SET_DESCRIPTOR",212 "GET_CONFIGURATION", "SET_CONFIGURATION", "GET_INTERFACE", "SET_INTERFACE",213 "SYNCH_FRAME"214 };215 pSetup = (PVUSBSETUP)pUrb->abData;216 pbData += sizeof(*pSetup);217 cbData -= sizeof(*pSetup);218 219 Log(("%s: %*s: CTRL: bmRequestType=0x%.2x (%s %s %s) bRequest=0x%.2x (%s) wValue=0x%.4x wIndex=0x%.4x wLength=0x%.4x\n",220 pUrb->pszDesc, s_cchMaxMsg, pszMsg,221 pSetup->bmRequestType, s_apszReqDirs[pSetup->bmRequestType >> 7], s_apszReqTypes[(pSetup->bmRequestType >> 5) & 0x3],222 (unsigned)(pSetup->bmRequestType & 0xf) < RT_ELEMENTS(s_apszReqRecipients) ? s_apszReqRecipients[pSetup->bmRequestType & 0xf] : "??",223 pSetup->bRequest, pSetup->bRequest < RT_ELEMENTS(s_apszRequests) ? s_apszRequests[pSetup->bRequest] : "??",224 pSetup->wValue, pSetup->wIndex, pSetup->wLength));225 226 if ( pSetup->bRequest == VUSB_REQ_GET_DESCRIPTOR227 && fComplete228 && pUrb->enmStatus == VUSBSTATUS_OK229 && ((pSetup->bmRequestType >> 5) & 0x3) < 2 /* vendor */)230 fDescriptors = true;231 }232 else if ( fComplete233 && pUrb->enmDir == VUSBDIRECTION_IN234 && pUrb->enmType == VUSBXFERTYPE_CTRL235 && pUrb->enmStatus == VUSBSTATUS_OK236 && pPipe->pCtrl237 && pPipe->pCtrl->enmStage == CTLSTAGE_DATA238 && cbData > 0)239 {240 pSetup = pPipe->pCtrl->pMsg;241 if (pSetup->bRequest == VUSB_REQ_GET_DESCRIPTOR)242 fDescriptors = true;243 }244 245 /*246 * Dump descriptors.247 */248 if (fDescriptors)249 {250 const uint8_t *pb = pbData;251 const uint8_t *pbEnd = pbData + cbData;252 while (pb + 1 < pbEnd)253 {254 const unsigned cbLeft = pbEnd - pb;255 const unsigned cbLength = *pb;256 unsigned cb = cbLength;257 uint8_t bDescriptorType = pb[1];258 259 /* length out of bounds? */260 if (cbLength > cbLeft)261 {262 cb = cbLeft;263 if (cbLength != 0xff) /* ignore this */264 Log(("URB: %*s: DESC: warning descriptor length goes beyond the end of the URB! cbLength=%d cbLeft=%d\n",265 s_cchMaxMsg, pszMsg, cbLength, cbLeft));266 }267 268 if (cb >= 2)269 {270 Log(("URB: %*s: DESC: %04x: %25s = %#04x (%d)\n"271 "URB: %*s: %04x: %25s = %#04x (",272 s_cchMaxMsg, pszMsg, pb - pbData, "bLength", cbLength, cbLength,273 s_cchMaxMsg, pszMsg, pb - pbData + 1, "bDescriptorType", bDescriptorType));274 275 #pragma pack(1)276 #define BYTE_FIELD(strct, memb) \277 if ((unsigned)RT_OFFSETOF(strct, memb) < cb) \278 Log(("URB: %*s: %04x: %25s = %#04x\n", s_cchMaxMsg, pszMsg, \279 pb + RT_OFFSETOF(strct, memb) - pbData, #memb, pb[RT_OFFSETOF(strct, memb)]))280 #define BYTE_FIELD_START(strct, memb) do { \281 if ((unsigned)RT_OFFSETOF(strct, memb) < cb) \282 { \283 Log(("URB: %*s: %04x: %25s = %#04x", s_cchMaxMsg, pszMsg, \284 pb + RT_OFFSETOF(strct, memb) - pbData, #memb, pb[RT_OFFSETOF(strct, memb)]))285 #define BYTE_FIELD_END(strct, memb) \286 Log(("\n")); \287 } } while (0)288 #define WORD_FIELD(strct, memb) \289 if ((unsigned)RT_OFFSETOF(strct, memb) + 1 < cb) \290 Log(("URB: %*s: %04x: %25s = %#06x\n", s_cchMaxMsg, pszMsg, \291 pb + RT_OFFSETOF(strct, memb) - pbData, #memb, *(uint16_t *)&pb[RT_OFFSETOF(strct, memb)]))292 #define BCD_FIELD(strct, memb) \293 if ((unsigned)RT_OFFSETOF(strct, memb) + 1 < cb) \294 Log(("URB: %*s: %04x: %25s = %#06x (%02x.%02x)\n", s_cchMaxMsg, pszMsg, \295 pb + RT_OFFSETOF(strct, memb) - pbData, #memb, *(uint16_t *)&pb[RT_OFFSETOF(strct, memb)], \296 pb[RT_OFFSETOF(strct, memb) + 1], pb[RT_OFFSETOF(strct, memb)]))297 #define SIZE_CHECK(strct) \298 if (cb > sizeof(strct)) \299 Log(("URB: %*s: %04x: WARNING %d extra byte(s) %.*Rhxs\n", s_cchMaxMsg, pszMsg, \300 pb + sizeof(strct) - pbData, cb - sizeof(strct), cb - sizeof(strct), pb + sizeof(strct))); \301 else if (cb < sizeof(strct)) \302 Log(("URB: %*s: %04x: WARNING %d missing byte(s)! Expected size %d.\n", s_cchMaxMsg, pszMsg, \303 pb + cb - pbData, sizeof(strct) - cb, sizeof(strct)))304 305 /* on type */306 switch (bDescriptorType)307 {308 case VUSB_DT_DEVICE:309 {310 struct dev_desc311 {312 uint8_t bLength;313 uint8_t bDescriptorType;314 uint16_t bcdUSB;315 uint8_t bDeviceClass;316 uint8_t bDeviceSubClass;317 uint8_t bDeviceProtocol;318 uint8_t bMaxPacketSize0;319 uint16_t idVendor;320 uint16_t idProduct;321 uint16_t bcdDevice;322 uint8_t iManufacturer;323 uint8_t iProduct;324 uint8_t iSerialNumber;325 uint8_t bNumConfigurations;326 } *pDesc = (struct dev_desc *)pb; NOREF(pDesc);327 Log(("DEV)\n"));328 BCD_FIELD( struct dev_desc, bcdUSB);329 BYTE_FIELD(struct dev_desc, bDeviceClass);330 BYTE_FIELD(struct dev_desc, bDeviceSubClass);331 BYTE_FIELD(struct dev_desc, bDeviceProtocol);332 BYTE_FIELD(struct dev_desc, bMaxPacketSize0);333 WORD_FIELD(struct dev_desc, idVendor);334 WORD_FIELD(struct dev_desc, idProduct);335 BCD_FIELD( struct dev_desc, bcdDevice);336 BYTE_FIELD(struct dev_desc, iManufacturer);337 BYTE_FIELD(struct dev_desc, iProduct);338 BYTE_FIELD(struct dev_desc, iSerialNumber);339 BYTE_FIELD(struct dev_desc, bNumConfigurations);340 SIZE_CHECK(struct dev_desc);341 break;342 }343 344 case VUSB_DT_CONFIG:345 {346 struct cfg_desc347 {348 uint8_t bLength;349 uint8_t bDescriptorType;350 uint16_t wTotalLength;351 uint8_t bNumInterfaces;352 uint8_t bConfigurationValue;353 uint8_t iConfiguration;354 uint8_t bmAttributes;355 uint8_t MaxPower;356 } *pDesc = (struct cfg_desc *)pb; NOREF(pDesc);357 Log(("CFG)\n"));358 WORD_FIELD(struct cfg_desc, wTotalLength);359 BYTE_FIELD(struct cfg_desc, bNumInterfaces);360 BYTE_FIELD(struct cfg_desc, bConfigurationValue);361 BYTE_FIELD(struct cfg_desc, iConfiguration);362 BYTE_FIELD_START(struct cfg_desc, bmAttributes);363 static const char * const s_apszTransType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };364 static const char * const s_apszSyncType[4] = { "NoSync", "Asynchronous", "Adaptive", "Synchronous" };365 static const char * const s_apszUsageType[4] = { "Data ep", "Feedback ep.", "Implicit feedback Data ep.", "Reserved" };366 Log((" %s - %s - %s", s_apszTransType[(pDesc->bmAttributes & 0x3)],367 s_apszSyncType[((pDesc->bmAttributes >> 2) & 0x3)], s_apszUsageType[((pDesc->bmAttributes >> 4) & 0x3)]));368 BYTE_FIELD_END(struct cfg_desc, bmAttributes);369 BYTE_FIELD(struct cfg_desc, MaxPower);370 SIZE_CHECK(struct cfg_desc);371 break;372 }373 374 case VUSB_DT_STRING:375 if (!pSetup->wIndex)376 {377 /* langid array */378 uint16_t *pu16 = (uint16_t *)pb + 1;379 Log(("LANGIDs)\n"));380 while ((uintptr_t)pu16 + 2 - (uintptr_t)pb <= cb)381 {382 Log(("URB: %*s: %04x: wLANGID[%#x] = %#06x\n",383 s_cchMaxMsg, pszMsg, (uint8_t *)pu16 - pbData, pu16 - (uint16_t *)pb, *pu16));384 pu16++;385 }386 if (cb & 1)387 Log(("URB: %*s: %04x: WARNING descriptor size is odd! extra byte: %02\n",388 s_cchMaxMsg, pszMsg, (uint8_t *)pu16 - pbData, *(uint8_t *)pu16));389 }390 else391 {392 /** a string. */393 Log(("STRING)\n"));394 if (cb > 2)395 Log(("URB: %*s: %04x: Length=%d String=%.*ls\n",396 s_cchMaxMsg, pszMsg, pb - pbData, cb - 2, cb / 2 - 1, pb + 2));397 else398 Log(("URB: %*s: %04x: Length=0!\n", s_cchMaxMsg, pszMsg, pb - pbData));399 }400 break;401 402 case VUSB_DT_INTERFACE:403 {404 struct if_desc405 {406 uint8_t bLength;407 uint8_t bDescriptorType;408 uint8_t bInterfaceNumber;409 uint8_t bAlternateSetting;410 uint8_t bNumEndpoints;411 uint8_t bInterfaceClass;412 uint8_t bInterfaceSubClass;413 uint8_t bInterfaceProtocol;414 uint8_t iInterface;415 } *pDesc = (struct if_desc *)pb; NOREF(pDesc);416 Log(("IF)\n"));417 BYTE_FIELD(struct if_desc, bInterfaceNumber);418 BYTE_FIELD(struct if_desc, bAlternateSetting);419 BYTE_FIELD(struct if_desc, bNumEndpoints);420 BYTE_FIELD(struct if_desc, bInterfaceClass);421 BYTE_FIELD(struct if_desc, bInterfaceSubClass);422 BYTE_FIELD(struct if_desc, bInterfaceProtocol);423 BYTE_FIELD(struct if_desc, iInterface);424 SIZE_CHECK(struct if_desc);425 break;426 }427 428 case VUSB_DT_ENDPOINT:429 {430 struct ep_desc431 {432 uint8_t bLength;433 uint8_t bDescriptorType;434 uint8_t bEndpointAddress;435 uint8_t bmAttributes;436 uint16_t wMaxPacketSize;437 uint8_t bInterval;438 } *pDesc = (struct ep_desc *)pb; NOREF(pDesc);439 Log(("EP)\n"));440 BYTE_FIELD(struct ep_desc, bEndpointAddress);441 BYTE_FIELD(struct ep_desc, bmAttributes);442 WORD_FIELD(struct ep_desc, wMaxPacketSize);443 BYTE_FIELD(struct ep_desc, bInterval);444 SIZE_CHECK(struct ep_desc);445 break;446 }447 448 case VUSB_DT_DEVICE_QUALIFIER:449 {450 struct dq_desc451 {452 uint8_t bLength;453 uint8_t bDescriptorType;454 uint16_t bcdUSB;455 uint8_t bDeviceClass;456 uint8_t bDeviceSubClass;457 uint8_t bDeviceProtocol;458 uint8_t bMaxPacketSize0;459 uint8_t bNumConfigurations;460 uint8_t bReserved;461 } *pDQDesc = (struct dq_desc *)pb; NOREF(pDQDesc);462 Log(("DEVQ)\n"));463 BCD_FIELD( struct dq_desc, bcdUSB);464 BYTE_FIELD(struct dq_desc, bDeviceClass);465 BYTE_FIELD(struct dq_desc, bDeviceSubClass);466 BYTE_FIELD(struct dq_desc, bDeviceProtocol);467 BYTE_FIELD(struct dq_desc, bMaxPacketSize0);468 BYTE_FIELD(struct dq_desc, bNumConfigurations);469 BYTE_FIELD(struct dq_desc, bReserved);470 SIZE_CHECK(struct dq_desc);471 break;472 }473 474 case VUSB_DT_OTHER_SPEED_CFG:475 {476 struct oth_cfg_desc477 {478 uint8_t bLength;479 uint8_t bDescriptorType;480 uint16_t wTotalLength;481 uint8_t bNumInterfaces;482 uint8_t bConfigurationValue;483 uint8_t iConfiguration;484 uint8_t bmAttributes;485 uint8_t MaxPower;486 } *pDesc = (struct oth_cfg_desc *)pb; NOREF(pDesc);487 Log(("OCFG)\n"));488 WORD_FIELD(struct oth_cfg_desc, wTotalLength);489 BYTE_FIELD(struct oth_cfg_desc, bNumInterfaces);490 BYTE_FIELD(struct oth_cfg_desc, bConfigurationValue);491 BYTE_FIELD(struct oth_cfg_desc, iConfiguration);492 BYTE_FIELD_START(struct oth_cfg_desc, bmAttributes);493 static const char * const s_apszTransType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };494 static const char * const s_apszSyncType[4] = { "NoSync", "Asynchronous", "Adaptive", "Synchronous" };495 static const char * const s_apszUsageType[4] = { "Data ep", "Feedback ep.", "Implicit feedback Data ep.", "Reserved" };496 Log((" %s - %s - %s", s_apszTransType[(pDesc->bmAttributes & 0x3)],497 s_apszSyncType[((pDesc->bmAttributes >> 2) & 0x3)], s_apszUsageType[((pDesc->bmAttributes >> 4) & 0x3)]));498 BYTE_FIELD_END(struct oth_cfg_desc, bmAttributes);499 BYTE_FIELD(struct oth_cfg_desc, MaxPower);500 SIZE_CHECK(struct oth_cfg_desc);501 break;502 }503 504 case 0x21:505 {506 struct hid_desc507 {508 uint8_t bLength;509 uint8_t bDescriptorType;510 uint16_t bcdHid;511 uint8_t bCountry;512 uint8_t bNumDescriptors;513 uint8_t bReportType;514 uint16_t wReportLength;515 } *pDesc = (struct hid_desc *)pb; NOREF(pDesc);516 Log(("EP)\n"));517 BCD_FIELD( struct hid_desc, bcdHid);518 BYTE_FIELD(struct hid_desc, bCountry);519 BYTE_FIELD(struct hid_desc, bNumDescriptors);520 BYTE_FIELD(struct hid_desc, bReportType);521 WORD_FIELD(struct hid_desc, wReportLength);522 SIZE_CHECK(struct hid_desc);523 break;524 }525 526 case 0xff:527 Log(("UNKNOWN-ignore)\n"));528 break;529 530 default:531 Log(("UNKNOWN)!!!\n"));532 break;533 }534 535 #undef BYTE_FIELD536 #undef WORD_FIELD537 #undef BCD_FIELD538 #undef SIZE_CHECK539 #pragma pack()540 }541 else542 {543 Log(("URB: %*s: DESC: %04x: bLength=%d bDescriptorType=%d - invalid length\n",544 s_cchMaxMsg, pszMsg, pb - pbData, cb, bDescriptorType));545 break;546 }547 548 /* next */549 pb += cb;550 }551 }552 553 /*554 * SCSI555 */556 if ( pUrb->enmType == VUSBXFERTYPE_BULK557 && pUrb->enmDir == VUSBDIRECTION_OUT558 && pUrb->cbData >= 12559 && !memcmp(pUrb->abData, "USBC", 4))560 {561 const struct usbc562 {563 uint32_t Signature;564 uint32_t Tag;565 uint32_t DataTransferLength;566 uint8_t Flags;567 uint8_t Lun;568 uint8_t Length;569 uint8_t CDB[13];570 } *pUsbC = (struct usbc *)pUrb->abData;571 Log(("URB: %*s: SCSI: Tag=%#x DataTransferLength=%#x Flags=%#x Lun=%#x Length=%#x CDB=%.*Rhxs\n",572 s_cchMaxMsg, pszMsg, pUsbC->Tag, pUsbC->DataTransferLength, pUsbC->Flags, pUsbC->Lun,573 pUsbC->Length, pUsbC->Length, pUsbC->CDB));574 const uint8_t *pb = &pUsbC->CDB[0];575 switch (pb[0])576 {577 case 0x00: /* test unit read */578 Log(("URB: %*s: SCSI: TEST_UNIT_READY LUN=%d Ctrl=%#RX8\n",579 s_cchMaxMsg, pszMsg, pb[1] >> 5, pb[5]));580 break;581 case 0x03: /* Request Sense command */582 Log(("URB: %*s: SCSI: REQUEST_SENSE LUN=%d AlcLen=%#RX16 Ctrl=%#RX8\n",583 s_cchMaxMsg, pszMsg, pb[1] >> 5, pb[4], pb[5]));584 break;585 case 0x12: /* Inquiry command. */586 Log(("URB: %*s: SCSI: INQUIRY EVPD=%d LUN=%d PgCd=%#RX8 AlcLen=%#RX8 Ctrl=%#RX8\n",587 s_cchMaxMsg, pszMsg, pb[1] & 1, pb[1] >> 5, pb[2], pb[4], pb[5]));588 break;589 case 0x1a: /* Mode Sense(6) command */590 Log(("URB: %*s: SCSI: MODE_SENSE6 LUN=%d DBD=%d PC=%d PgCd=%#RX8 AlcLen=%#RX8 Ctrl=%#RX8\n",591 s_cchMaxMsg, pszMsg, pb[1] >> 5, !!(pb[1] & RT_BIT(3)), pb[2] >> 6, pb[2] & 0x3f, pb[4], pb[5]));592 break;593 case 0x5a:594 Log(("URB: %*s: SCSI: MODE_SENSE10 LUN=%d DBD=%d PC=%d PgCd=%#RX8 AlcLen=%#RX16 Ctrl=%#RX8\n",595 s_cchMaxMsg, pszMsg, pb[1] >> 5, !!(pb[1] & RT_BIT(3)), pb[2] >> 6, pb[2] & 0x3f,596 RT_MAKE_U16(pb[8], pb[7]), pb[9]));597 break;598 case 0x25: /* Read Capacity(6) command. */599 Log(("URB: %*s: SCSI: READ_CAPACITY\n",600 s_cchMaxMsg, pszMsg));601 break;602 case 0x28: /* Read(10) command. */603 Log(("URB: %*s: SCSI: READ10 RelAdr=%d FUA=%d DPO=%d LUN=%d LBA=%#RX32 Len=%#RX16 Ctrl=%#RX8\n",604 s_cchMaxMsg, pszMsg,605 pb[1] & 1, !!(pb[1] & RT_BIT(3)), !!(pb[1] & RT_BIT(4)), pb[1] >> 5,606 RT_MAKE_U32_FROM_U8(pb[5], pb[4], pb[3], pb[2]),607 RT_MAKE_U16(pb[8], pb[7]), pb[9]));608 break;609 case 0xa8: /* Read(12) command. */610 Log(("URB: %*s: SCSI: READ12 RelAdr=%d FUA=%d DPO=%d LUN=%d LBA=%#RX32 Len=%#RX32 Ctrl=%#RX8\n",611 s_cchMaxMsg, pszMsg,612 pb[1] & 1, !!(pb[1] & RT_BIT(3)), !!(pb[1] & RT_BIT(4)), pb[1] >> 5,613 RT_MAKE_U32_FROM_U8(pb[5], pb[4], pb[3], pb[2]),614 RT_MAKE_U32_FROM_U8(pb[9], pb[8], pb[7], pb[6]),615 pb[11]));616 break;617 case 0x3e: /* Read Long command. */618 Log(("URB: %*s: SCSI: READ LONG RelAdr=%d Correct=%d LUN=%d LBA=%#RX16 ByteLen=%#RX16 Ctrl=%#RX8\n",619 s_cchMaxMsg, pszMsg,620 pb[1] & 1, !!(pb[1] & RT_BIT(1)), pb[1] >> 5,621 RT_MAKE_U16(pb[3], pb[2]), RT_MAKE_U16(pb[6], pb[5]),622 pb[11]));623 break;624 case 0x2a: /* Write(10) command. */625 Log(("URB: %*s: SCSI: WRITE10 RelAdr=%d EBP=%d FUA=%d DPO=%d LUN=%d LBA=%#RX32 Len=%#RX16 Ctrl=%#RX8\n",626 s_cchMaxMsg, pszMsg,627 pb[1] & 1, !!(pb[1] & RT_BIT(2)), !!(pb[1] & RT_BIT(3)),628 !!(pb[1] & RT_BIT(4)), pb[1] >> 5,629 RT_MAKE_U32_FROM_U8(pb[5], pb[4], pb[3], pb[2]),630 RT_MAKE_U16(pb[8], pb[7]), pb[9]));631 break;632 case 0xaa: /* Write(12) command. */633 Log(("URB: %*s: SCSI: WRITE12 RelAdr=%d EBP=%d FUA=%d DPO=%d LUN=%d LBA=%#RX32 Len=%#RX32 Ctrl=%#RX8\n",634 s_cchMaxMsg, pszMsg,635 pb[1] & 1, !!(pb[1] & RT_BIT(3)), !!(pb[1] & RT_BIT(4)),636 !!(pb[1] & RT_BIT(4)), pb[1] >> 5,637 RT_MAKE_U32_FROM_U8(pb[5], pb[4], pb[3], pb[2]),638 RT_MAKE_U32_FROM_U8(pb[9], pb[8], pb[7], pb[6]),639 pb[11]));640 break;641 case 0x3f: /* Write Long command. */642 Log(("URB: %*s: SCSI: WRITE LONG RelAdr=%d LUN=%d LBA=%#RX16 ByteLen=%#RX16 Ctrl=%#RX8\n",643 s_cchMaxMsg, pszMsg,644 pb[1] & 1, pb[1] >> 5,645 RT_MAKE_U16(pb[3], pb[2]), RT_MAKE_U16(pb[6], pb[5]),646 pb[11]));647 break;648 case 0x35: /* Synchronize Cache(10) command. */649 Log(("URB: %*s: SCSI: SYNCHRONIZE_CACHE10\n",650 s_cchMaxMsg, pszMsg));651 break;652 case 0xa0: /* Report LUNs command. */653 Log(("URB: %*s: SCSI: REPORT_LUNS\n",654 s_cchMaxMsg, pszMsg));655 break;656 default:657 Log(("URB: %*s: SCSI: cmd=%#x\n",658 s_cchMaxMsg, pszMsg, pb[0]));659 break;660 }661 if (pDev)662 pDev->Urb.u8ScsiCmd = pb[0];663 }664 else if ( fComplete665 && pUrb->enmType == VUSBXFERTYPE_BULK666 && pUrb->enmDir == VUSBDIRECTION_IN667 && pUrb->cbData >= 12668 && !memcmp(pUrb->abData, "USBS", 4))669 {670 const struct usbs671 {672 uint32_t Signature;673 uint32_t Tag;674 uint32_t DataResidue;675 uint8_t Status;676 uint8_t CDB[3];677 } *pUsbS = (struct usbs *)pUrb->abData;678 static const char * const s_apszStatuses[] = { "PASSED", "FAILED", "PHASE ERROR", "RESERVED" };679 Log(("URB: %*s: SCSI: Tag=%#x DataResidue=%#RX32 Status=%#RX8 %s\n",680 s_cchMaxMsg, pszMsg, pUsbS->Tag, pUsbS->DataResidue, pUsbS->Status,681 s_apszStatuses[pUsbS->Status < RT_ELEMENTS(s_apszStatuses) ? pUsbS->Status : RT_ELEMENTS(s_apszStatuses) - 1]));682 if (pDev)683 pDev->Urb.u8ScsiCmd = 0xff;684 }685 else if ( fComplete686 && pUrb->enmType == VUSBXFERTYPE_BULK687 && pUrb->enmDir == VUSBDIRECTION_IN688 && pDev689 && pDev->Urb.u8ScsiCmd != 0xff)690 {691 const uint8_t *pb = pUrb->abData;692 switch (pDev->Urb.u8ScsiCmd)693 {694 case 0x03: /* REQUEST_SENSE */695 Log(("URB: %*s: SCSI: RESPONSE: REQUEST_SENSE (%s)\n",696 s_cchMaxMsg, pszMsg, pb[0] & 7 ? "scsi compliant" : "not scsi compliant"));697 Log(("URB: %*s: SCSI: ErrCd=%#RX8 (%s) Seg=%#RX8 Filemark=%d EOM=%d ILI=%d\n",698 s_cchMaxMsg, pszMsg, pb[0] & 0x7f, GetScsiErrCd(pb[0] & 0x7f), pb[1],699 pb[2] >> 7, !!(pb[2] & RT_BIT(6)), !!(pb[2] & RT_BIT(5))));700 Log(("URB: %*s: SCSI: SenseKey=%#x ASC=%#RX8 ASCQ=%#RX8 : %s\n",701 s_cchMaxMsg, pszMsg, pb[2] & 0xf, pb[12], pb[13],702 GetScsiKCQ(pb[2] & 0xf, pb[12], pb[13])));703 /** @todo more later */704 break;705 706 case 0x12: /* INQUIRY. */707 {708 unsigned cb = pb[4] + 5;709 Log(("URB: %*s: SCSI: RESPONSE: INQUIRY\n"710 "URB: %*s: SCSI: PeripheralQualifier=%d PeripheralType=%#RX8 RMB=%d DevTypeMod=%#RX8\n",711 s_cchMaxMsg, pszMsg, s_cchMaxMsg, pszMsg,712 pb[0] >> 5, pb[0] & 0x1f, pb[1] >> 7, pb[1] & 0x7f));713 Log(("URB: %*s: SCSI: ISOVer=%d ECMAVer=%d ANSIVer=%d\n",714 s_cchMaxMsg, pszMsg, pb[2] >> 6, (pb[2] >> 3) & 7, pb[2] & 7));715 Log(("URB: %*s: SCSI: AENC=%d TrmlOP=%d RespDataFmt=%d (%s) AddLen=%d\n",716 s_cchMaxMsg, pszMsg, pb[3] >> 7, (pb[3] >> 6) & 1,717 pb[3] & 0xf, pb[3] & 0xf ? "legacy" : "scsi", pb[4]));718 if (cb < 8)719 break;720 Log(("URB: %*s: SCSI: RelAdr=%d WBus32=%d WBus16=%d Sync=%d Linked=%d CmdQue=%d SftRe=%d\n",721 s_cchMaxMsg, pszMsg, pb[7] >> 7, !!(pb[7] >> 6), !!(pb[7] >> 5), !!(pb[7] >> 4),722 !!(pb[7] >> 3), !!(pb[7] >> 1), pb[7] & 1));723 if (cb < 16)724 break;725 Log(("URB: %*s: SCSI: VendorId=%.8s\n", s_cchMaxMsg, pszMsg, &pb[8]));726 if (cb < 32)727 break;728 Log(("URB: %*s: SCSI: ProductId=%.16s\n", s_cchMaxMsg, pszMsg, &pb[16]));729 if (cb < 36)730 break;731 Log(("URB: %*s: SCSI: ProdRevLvl=%.4s\n", s_cchMaxMsg, pszMsg, &pb[32]));732 if (cb > 36)733 Log(("URB: %*s: SCSI: VendorSpecific=%.*s\n",734 s_cchMaxMsg, pszMsg, RT_MIN(cb - 36, 20), &pb[36]));735 if (cb > 96)736 Log(("URB: %*s: SCSI: VendorParam=%.*Rhxs\n",737 s_cchMaxMsg, pszMsg, cb - 96, &pb[96]));738 break;739 }740 741 case 0x25: /* Read Capacity(6) command. */742 Log(("URB: %*s: SCSI: RESPONSE: READ_CAPACITY\n"743 "URB: %*s: SCSI: LBA=%#RX32 BlockLen=%#RX32\n",744 s_cchMaxMsg, pszMsg, s_cchMaxMsg, pszMsg,745 RT_MAKE_U32_FROM_U8(pb[3], pb[2], pb[1], pb[0]),746 RT_MAKE_U32_FROM_U8(pb[7], pb[6], pb[5], pb[4])));747 break;748 }749 750 pDev->Urb.u8ScsiCmd = 0xff;751 }752 753 /*754 * The Quickcam control pipe.755 */756 if ( pSetup757 && ((pSetup->bmRequestType >> 5) & 0x3) >= 2 /* vendor */758 && (fComplete || !(pSetup->bmRequestType >> 7))759 && pDev760 && pDev->pDescCache761 && pDev->pDescCache->pDevice762 && pDev->pDescCache->pDevice->idVendor == 0x046d763 && ( pDev->pDescCache->pDevice->idProduct == 0x8f6764 || pDev->pDescCache->pDevice->idProduct == 0x8f5765 || pDev->pDescCache->pDevice->idProduct == 0x8f0)766 )767 {768 pbData = (const uint8_t *)(pSetup + 1);769 cbData = pUrb->cbData - sizeof(*pSetup);770 771 if ( pSetup->bRequest == 0x04772 && pSetup->wIndex == 0773 && (cbData == 1 || cbData == 2))774 {775 /* the value */776 unsigned uVal = pbData[0];777 if (cbData > 1)778 uVal |= (unsigned)pbData[1] << 8;779 780 const char *pszReg = NULL;781 switch (pSetup->wValue)782 {783 case 0: pszReg = "i2c init"; break;784 case 0x0423: pszReg = "STV_REG23"; break;785 case 0x0509: pszReg = "RED something"; break;786 case 0x050a: pszReg = "GREEN something"; break;787 case 0x050b: pszReg = "BLUE something"; break;788 case 0x143f: pszReg = "COMMIT? INIT DONE?"; break;789 case 0x1440: pszReg = "STV_ISO_ENABLE"; break;790 case 0x1442: pszReg = uVal & (RT_BIT(7)|RT_BIT(5)) ? "BUTTON PRESSED" : "BUTTON" ; break;791 case 0x1443: pszReg = "STV_SCAN_RATE"; break;792 case 0x1445: pszReg = "LED?"; break;793 case 0x1500: pszReg = "STV_REG00"; break;794 case 0x1501: pszReg = "STV_REG01"; break;795 case 0x1502: pszReg = "STV_REG02"; break;796 case 0x1503: pszReg = "STV_REG03"; break;797 case 0x1504: pszReg = "STV_REG04"; break;798 case 0x15c1: pszReg = "STV_ISO_SIZE"; break;799 case 0x15c3: pszReg = "STV_Y_CTRL"; break;800 case 0x1680: pszReg = "STV_X_CTRL"; break;801 case 0xe00a: pszReg = "ProductId"; break;802 default: pszReg = "[no clue]"; break;803 }804 if (pszReg)805 Log(("URB: %*s: QUICKCAM: %s %#x (%d) %s '%s' (%#x)\n",806 s_cchMaxMsg, pszMsg,807 (pSetup->bmRequestType >> 7) ? "read" : "write", uVal, uVal, (pSetup->bmRequestType >> 7) ? "from" : "to",808 pszReg, pSetup->wValue));809 }810 else if (cbData)811 Log(("URB: %*s: QUICKCAM: Unknown request: bRequest=%#x bmRequestType=%#x wValue=%#x wIndex=%#x: %.*Rhxs\n", s_cchMaxMsg, pszMsg,812 pSetup->bRequest, pSetup->bmRequestType, pSetup->wValue, pSetup->wIndex, cbData, pbData));813 else814 Log(("URB: %*s: QUICKCAM: Unknown request: bRequest=%#x bmRequestType=%#x wValue=%#x wIndex=%#x: (no data)\n", s_cchMaxMsg, pszMsg,815 pSetup->bRequest, pSetup->bmRequestType, pSetup->wValue, pSetup->wIndex));816 }817 818 #if 1819 if ( cbData /** @todo Fix RTStrFormatV to communicate .* so formatter doesn't apply defaults when cbData=0. */820 && (fComplete821 ? pUrb->enmDir != VUSBDIRECTION_OUT822 : pUrb->enmDir == VUSBDIRECTION_OUT))823 Log3(("%16.*Rhxd\n", cbData, pbData));824 #endif825 if (pUrb->enmType == VUSBXFERTYPE_MSG && pUrb->pVUsb && pUrb->pVUsb->pCtrlUrb)826 vusbUrbTrace(pUrb->pVUsb->pCtrlUrb, "NESTED MSG", fComplete);827 }828 #endif /* LOG_ENABLED */829 55 830 56
Note:
See TracChangeset
for help on using the changeset viewer.