VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp@ 36963

Last change on this file since 36963 was 35812, checked in by vboxsync, 14 years ago

Main: fixed format specifiers (%ls versus %s)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 91.5 KB
Line 
1/* $Id: HostUSBDeviceImpl.cpp 35812 2011-02-01 13:46:37Z vboxsync $ */
2/** @file
3 * VirtualBox IHostUSBDevice COM interface implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <iprt/types.h> /* for UINT64_C */
19
20#include "HostUSBDeviceImpl.h"
21#include "MachineImpl.h"
22#include "HostImpl.h"
23#include "VirtualBoxErrorInfoImpl.h"
24#include "USBProxyService.h"
25
26#include "AutoCaller.h"
27#include "Logging.h"
28
29#include <VBox/err.h>
30#include <iprt/cpp/utils.h>
31
32// constructor / destructor
33/////////////////////////////////////////////////////////////////////////////
34
35DEFINE_EMPTY_CTOR_DTOR (HostUSBDevice)
36
37HRESULT HostUSBDevice::FinalConstruct()
38{
39 mUSBProxyService = NULL;
40 mUsb = NULL;
41
42 return BaseFinalConstruct();
43}
44
45void HostUSBDevice::FinalRelease()
46{
47 uninit();
48 BaseFinalRelease();
49}
50
51// public initializer/uninitializer for internal purposes only
52/////////////////////////////////////////////////////////////////////////////
53
54/**
55 * Initializes the USB device object.
56 *
57 * @returns COM result indicator
58 * @param aUsb Pointer to the usb device structure for which the object is to be a wrapper.
59 * This structure is now fully owned by the HostUSBDevice object and will be
60 * freed when it is destructed.
61 * @param aUSBProxyService Pointer to the USB Proxy Service object.
62 */
63HRESULT HostUSBDevice::init(PUSBDEVICE aUsb, USBProxyService *aUSBProxyService)
64{
65 ComAssertRet(aUsb, E_INVALIDARG);
66
67 /* Enclose the state transition NotReady->InInit->Ready */
68 AutoInitSpan autoInitSpan(this);
69 AssertReturn(autoInitSpan.isOk(), E_FAIL);
70
71 /*
72 * We need a unique ID for this VBoxSVC session.
73 * The UUID isn't stored anywhere.
74 */
75 unconst(mId).create();
76
77 /*
78 * Set the initial device state.
79 */
80 AssertMsgReturn( aUsb->enmState >= USBDEVICESTATE_UNSUPPORTED
81 && aUsb->enmState < USBDEVICESTATE_USED_BY_GUEST, /* used-by-guest is not a legal initial state. */
82 ("%d\n", aUsb->enmState), E_FAIL);
83 mUniState = (HostUSBDeviceState)aUsb->enmState;
84 mUniSubState = kHostUSBDeviceSubState_Default;
85 mPendingUniState = kHostUSBDeviceState_Invalid;
86 mPrevUniState = mUniState;
87 mIsPhysicallyDetached = false;
88
89 /* Other data members */
90 mUSBProxyService = aUSBProxyService;
91 mUsb = aUsb;
92
93 /* Set the name. */
94 mNameObj = getName();
95 mName = mNameObj.c_str();
96
97 /* Confirm the successful initialization */
98 autoInitSpan.setSucceeded();
99
100 return S_OK;
101}
102
103/**
104 * Uninitializes the instance and sets the ready flag to FALSE.
105 * Called either from FinalRelease() or by the parent when it gets destroyed.
106 */
107void HostUSBDevice::uninit()
108{
109 /* Enclose the state transition Ready->InUninit->NotReady */
110 AutoUninitSpan autoUninitSpan(this);
111 if (autoUninitSpan.uninitDone())
112 return;
113
114 if (mUsb != NULL)
115 {
116 USBProxyService::freeDevice (mUsb);
117 mUsb = NULL;
118 }
119
120 mUSBProxyService = NULL;
121 mUniState = kHostUSBDeviceState_Invalid;
122}
123
124// IUSBDevice properties
125/////////////////////////////////////////////////////////////////////////////
126
127STDMETHODIMP HostUSBDevice::COMGETTER(Id)(BSTR *aId)
128{
129 CheckComArgOutPointerValid(aId);
130
131 AutoCaller autoCaller(this);
132 if (FAILED(autoCaller.rc())) return autoCaller.rc();
133
134 /* mId is constant during life time, no need to lock */
135 mId.toUtf16().cloneTo(aId);
136
137 return S_OK;
138}
139
140STDMETHODIMP HostUSBDevice::COMGETTER(VendorId)(USHORT *aVendorId)
141{
142 CheckComArgOutPointerValid(aVendorId);
143
144 AutoCaller autoCaller(this);
145 if (FAILED(autoCaller.rc())) return autoCaller.rc();
146
147 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
148
149 *aVendorId = mUsb->idVendor;
150
151 return S_OK;
152}
153
154STDMETHODIMP HostUSBDevice::COMGETTER(ProductId)(USHORT *aProductId)
155{
156 CheckComArgOutPointerValid(aProductId);
157
158 AutoCaller autoCaller(this);
159 if (FAILED(autoCaller.rc())) return autoCaller.rc();
160
161 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
162
163 *aProductId = mUsb->idProduct;
164
165 return S_OK;
166}
167
168STDMETHODIMP HostUSBDevice::COMGETTER(Revision)(USHORT *aRevision)
169{
170 CheckComArgOutPointerValid(aRevision);
171
172 AutoCaller autoCaller(this);
173 if (FAILED(autoCaller.rc())) return autoCaller.rc();
174
175 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
176
177 *aRevision = mUsb->bcdDevice;
178
179 return S_OK;
180}
181
182STDMETHODIMP HostUSBDevice::COMGETTER(Manufacturer)(BSTR *aManufacturer)
183{
184 CheckComArgOutPointerValid(aManufacturer);
185
186 AutoCaller autoCaller(this);
187 if (FAILED(autoCaller.rc())) return autoCaller.rc();
188
189 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
190
191 Bstr (mUsb->pszManufacturer).cloneTo(aManufacturer);
192
193 return S_OK;
194}
195
196STDMETHODIMP HostUSBDevice::COMGETTER(Product)(BSTR *aProduct)
197{
198 CheckComArgOutPointerValid(aProduct);
199
200 AutoCaller autoCaller(this);
201 if (FAILED(autoCaller.rc())) return autoCaller.rc();
202
203 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
204
205 Bstr (mUsb->pszProduct).cloneTo(aProduct);
206
207 return S_OK;
208}
209
210STDMETHODIMP HostUSBDevice::COMGETTER(SerialNumber)(BSTR *aSerialNumber)
211{
212 CheckComArgOutPointerValid(aSerialNumber);
213
214 AutoCaller autoCaller(this);
215 if (FAILED(autoCaller.rc())) return autoCaller.rc();
216
217 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
218
219 Bstr (mUsb->pszSerialNumber).cloneTo(aSerialNumber);
220
221 return S_OK;
222}
223
224STDMETHODIMP HostUSBDevice::COMGETTER(Address)(BSTR *aAddress)
225{
226 CheckComArgOutPointerValid(aAddress);
227
228 AutoCaller autoCaller(this);
229 if (FAILED(autoCaller.rc())) return autoCaller.rc();
230
231 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
232
233 Bstr (mUsb->pszAddress).cloneTo(aAddress);
234
235 return S_OK;
236}
237
238STDMETHODIMP HostUSBDevice::COMGETTER(Port)(USHORT *aPort)
239{
240 CheckComArgOutPointerValid(aPort);
241
242 AutoCaller autoCaller(this);
243 if (FAILED(autoCaller.rc())) return autoCaller.rc();
244
245 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
246
247#if !defined(RT_OS_WINDOWS) /// @todo check up the bPort value on Windows before enabling this.
248 *aPort = mUsb->bPort;
249#else
250 *aPort = 0;
251#endif
252
253 return S_OK;
254}
255
256STDMETHODIMP HostUSBDevice::COMGETTER(Version)(USHORT *aVersion)
257{
258 CheckComArgOutPointerValid(aVersion);
259
260 AutoCaller autoCaller(this);
261 if (FAILED(autoCaller.rc())) return autoCaller.rc();
262
263 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
264
265 *aVersion = mUsb->bcdUSB >> 8;
266
267 return S_OK;
268}
269
270STDMETHODIMP HostUSBDevice::COMGETTER(PortVersion)(USHORT *aPortVersion)
271{
272 CheckComArgOutPointerValid(aPortVersion);
273
274 AutoCaller autoCaller(this);
275 if (FAILED(autoCaller.rc())) return autoCaller.rc();
276
277 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
278
279 /* Port version is 2 (EHCI) if and only if the device runs at high speed;
280 * if speed is unknown, fall back to the old and inaccurate method.
281 */
282 if (mUsb->enmSpeed == USBDEVICESPEED_UNKNOWN)
283 *aPortVersion = mUsb->bcdUSB >> 8;
284 else
285 *aPortVersion = (mUsb->enmSpeed == USBDEVICESPEED_HIGH) ? 2 : 1;
286
287 return S_OK;
288}
289
290STDMETHODIMP HostUSBDevice::COMGETTER(Remote)(BOOL *aRemote)
291{
292 CheckComArgOutPointerValid(aRemote);
293
294 AutoCaller autoCaller(this);
295 if (FAILED(autoCaller.rc())) return autoCaller.rc();
296
297 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
298
299 *aRemote = FALSE;
300
301 return S_OK;
302}
303
304// IHostUSBDevice properties
305/////////////////////////////////////////////////////////////////////////////
306
307STDMETHODIMP HostUSBDevice::COMGETTER(State) (USBDeviceState_T *aState)
308{
309 CheckComArgOutPointerValid(aState);
310
311 AutoCaller autoCaller(this);
312 if (FAILED(autoCaller.rc())) return autoCaller.rc();
313
314 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
315
316 *aState = canonicalState();
317
318 return S_OK;
319}
320
321
322// public methods only for internal purposes
323////////////////////////////////////////////////////////////////////////////////
324
325/**
326 * @note Locks this object for reading.
327 */
328Utf8Str HostUSBDevice::getName()
329{
330 Utf8Str name;
331
332 AutoCaller autoCaller(this);
333 AssertComRCReturn (autoCaller.rc(), name);
334
335 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
336
337 bool haveManufacturer = mUsb->pszManufacturer && *mUsb->pszManufacturer;
338 bool haveProduct = mUsb->pszProduct && *mUsb->pszProduct;
339 if (haveManufacturer && haveProduct)
340 name = Utf8StrFmt ("%s %s", mUsb->pszManufacturer, mUsb->pszProduct);
341 else if (haveManufacturer)
342 name = Utf8StrFmt ("%s", mUsb->pszManufacturer);
343 else if (haveProduct)
344 name = Utf8StrFmt ("%s", mUsb->pszProduct);
345 else
346 name = "<unknown>";
347
348 return name;
349}
350
351/**
352 * Requests the USB proxy service capture the device (from the host)
353 * and attach it to a VM.
354 *
355 * As a convenience, this method will operate like attachToVM() if the device
356 * is already held by the proxy. Note that it will then perform IPC to the VM
357 * process, which means it will temporarily leave all locks. (Is this a good idea?)
358 *
359 * @param aMachine Machine this device should be attach to.
360 * @param aSetError Whether to set full error message or not to bother.
361 * @param aMaskedIfs The interfaces to hide from the guest.
362 *
363 * @returns Status indicating whether it was successfully captured and/or attached.
364 * @retval S_OK on success.
365 * @retval E_UNEXPECTED if the device state doesn't permit for any attaching.
366 * @retval E_* as appropriate.
367 *
368 * @note Must be called from under the object write lock.
369 * @note May lock the given machine object for reading.
370 */
371HRESULT HostUSBDevice::requestCaptureForVM(SessionMachine *aMachine, bool aSetError, ULONG aMaskedIfs /* = 0*/)
372{
373 LogFlowThisFunc(("{%s} aMachine=%p aMaskedIfs=%#x\n", mName, aMachine, aMaskedIfs));
374
375 /*
376 * Validate preconditions and input.
377 */
378 AssertReturn(aMachine, E_INVALIDARG);
379 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
380 if (aSetError)
381 {
382 if (mUniState == kHostUSBDeviceState_Unsupported)
383 return setError(E_INVALIDARG,
384 tr("USB device '%s' with UUID {%RTuuid} cannot be accessed by guest computers"),
385 mName, mId.raw());
386 if (mUniState == kHostUSBDeviceState_UsedByHost)
387 return setError(E_INVALIDARG,
388 tr("USB device '%s' with UUID {%RTuuid} is being exclusively used by the host computer"),
389 mName, mId.raw());
390 if (mUniState == kHostUSBDeviceState_UsedByVM)
391 {
392 /* Machine::name() requires a read lock */
393 AutoReadLock machLock(mMachine COMMA_LOCKVAL_SRC_POS);
394 return setError(E_INVALIDARG,
395 tr("USB device '%s' with UUID {%RTuuid} is already captured by the virtual machine '%s'"),
396 mName, mId.raw(), mMachine->getName().c_str());
397 }
398 if (mUniState >= kHostUSBDeviceState_FirstTransitional)
399 return setError(E_INVALIDARG,
400 tr("USB device '%s' with UUID {%RTuuid} is busy with a previous request. Please try again later"),
401 mName, mId.raw());
402 if ( mUniState != kHostUSBDeviceState_Unused
403 && mUniState != kHostUSBDeviceState_HeldByProxy
404 && mUniState != kHostUSBDeviceState_Capturable)
405 return setError(E_INVALIDARG,
406 tr("USB device '%s' with UUID {%RTuuid} is not in the right state for capturing (%s)"),
407 mName, mId.raw(), getStateName());
408 }
409
410 AssertReturn( mUniState == kHostUSBDeviceState_HeldByProxy
411 || mUniState == kHostUSBDeviceState_Unused
412 || mUniState == kHostUSBDeviceState_Capturable,
413 E_UNEXPECTED);
414 Assert(mMachine.isNull());
415
416 /*
417 * If it's already held by the proxy, we'll simply call
418 * attachToVM synchronously.
419 */
420 if (mUniState == kHostUSBDeviceState_HeldByProxy)
421 {
422 HRESULT hrc = attachToVM(aMachine, aMaskedIfs);
423 return SUCCEEDED(hrc);
424 }
425
426 /*
427 * Need to capture the device before it can be used.
428 *
429 * The device will be attached to the VM by the USB proxy service thread
430 * when the request succeeds (i.e. asynchronously).
431 */
432 LogFlowThisFunc(("{%s} capturing the device.\n", mName));
433#if (defined(RT_OS_DARWIN) && defined(VBOX_WITH_NEW_USB_CODE_ON_DARWIN)) /* PORTME */ \
434 || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
435 setState(kHostUSBDeviceState_Capturing, kHostUSBDeviceState_UsedByVM, kHostUSBDeviceSubState_AwaitingDetach);
436#else
437 setState(kHostUSBDeviceState_Capturing, kHostUSBDeviceState_UsedByVM);
438#endif
439 mMachine = aMachine;
440 mMaskedIfs = aMaskedIfs;
441 int rc = mUSBProxyService->captureDevice(this);
442 if (RT_FAILURE(rc))
443 {
444 failTransition();
445 mMachine.setNull();
446 if (rc == VERR_SHARING_VIOLATION)
447 return setError(E_FAIL,
448 tr("USB device '%s' with UUID {%RTuuid} is in use by someone else"),
449 mName, mId.raw());
450 return E_FAIL;
451 }
452
453 return S_OK;
454}
455
456/**
457 * Attempts to attach the USB device to a VM.
458 *
459 * The device must be in the HeldByProxy state or about to exit the
460 * Capturing state.
461 *
462 * This method will make an IPC to the VM process and do the actual
463 * attaching. While in the IPC locks will be abandond.
464 *
465 * @returns Status indicating whether it was successfully attached or not.
466 * @retval S_OK on success.
467 * @retval E_UNEXPECTED if the device state doesn't permit for any attaching.
468 * @retval E_* as appropriate.
469 *
470 * @param aMachine Machine this device should be attach to.
471 * @param aMaskedIfs The interfaces to hide from the guest.
472 */
473HRESULT HostUSBDevice::attachToVM(SessionMachine *aMachine, ULONG aMaskedIfs /* = 0*/)
474{
475 /*
476 * Validate and update the state.
477 */
478 AssertReturn( mUniState == kHostUSBDeviceState_Capturing
479 || mUniState == kHostUSBDeviceState_HeldByProxy
480 || mUniState == kHostUSBDeviceState_AttachingToVM,
481 E_UNEXPECTED);
482 setState(kHostUSBDeviceState_AttachingToVM, kHostUSBDeviceState_UsedByVM);
483
484 /*
485 * The VM process will query the object, so grab a reference to ourselves and leave the locks.
486 */
487 ComPtr<IUSBDevice> d = this;
488
489 AutoWriteLock alockSelf(this COMMA_LOCKVAL_SRC_POS);
490 alockSelf.leave();
491 AutoWriteLock alockProxy(mUSBProxyService COMMA_LOCKVAL_SRC_POS);
492 alockProxy.leave();
493
494 /*
495 * Call the VM process (IPC) and request it to attach the device.
496 *
497 * There are many reasons for this to fail, so, as a consequence we don't
498 * assert the return code as it will crash the daemon and annoy the heck
499 * out of people.
500 */
501 LogFlowThisFunc(("{%s} Calling machine->onUSBDeviceAttach()...\n", mName));
502 HRESULT hrc = aMachine->onUSBDeviceAttach (d, NULL, aMaskedIfs);
503 LogFlowThisFunc(("{%s} Done machine->onUSBDeviceAttach()=%08X\n", mName, hrc));
504
505 /*
506 * As we re-enter the lock, we'll have to check if the device was
507 * physically detached while we were busy.
508 */
509 alockProxy.enter();
510 alockSelf.enter();
511
512 if (SUCCEEDED(hrc))
513 {
514 mMachine = aMachine;
515 if (!mIsPhysicallyDetached)
516 setState(kHostUSBDeviceState_UsedByVM);
517 else
518 {
519 detachFromVM(kHostUSBDeviceState_PhysDetached);
520 hrc = E_UNEXPECTED;
521 }
522 }
523 else
524 {
525 mMachine.setNull();
526 if (!mIsPhysicallyDetached)
527 {
528 setState(kHostUSBDeviceState_HeldByProxy);
529 if (hrc == E_UNEXPECTED)
530 hrc = E_FAIL; /* No confusion. */
531 }
532 else
533 {
534 onPhysicalDetachedInternal();
535 hrc = E_UNEXPECTED;
536 }
537 }
538 return hrc;
539}
540
541
542/**
543 * Detaches the device from the VM.
544 *
545 * This is used for a special scenario in attachToVM() and from
546 * onPhysicalDetachedInternal().
547 *
548 * @param aFinalState The final state (PhysDetached).
549 */
550void HostUSBDevice::detachFromVM(HostUSBDeviceState aFinalState)
551{
552 NOREF(aFinalState);
553
554 /*
555 * Assert preconditions.
556 */
557 Assert(aFinalState == kHostUSBDeviceState_PhysDetached);
558 Assert( mUniState == kHostUSBDeviceState_AttachingToVM
559 || mUniState == kHostUSBDeviceState_UsedByVM);
560 Assert(!mMachine.isNull());
561
562 /*
563 * Change the state and abandond the locks. The VM may query
564 * data and we don't want to deadlock - the state protects us,
565 * so, it's not a bit issue here.
566 */
567 setState(kHostUSBDeviceState_PhysDetachingFromVM, kHostUSBDeviceState_PhysDetached);
568 AutoWriteLock alockSelf(this COMMA_LOCKVAL_SRC_POS);
569 alockSelf.leave();
570 AutoWriteLock alockProxy(mUSBProxyService COMMA_LOCKVAL_SRC_POS);
571 alockProxy.leave();
572
573 /*
574 * Call the VM process (IPC) and request it to detach the device.
575 *
576 * There are many reasons for this to fail, so, as a consequence we don't
577 * assert the return code as it will crash the daemon and annoy the heck
578 * out of people.
579 */
580 LogFlowThisFunc(("{%s} Calling machine->onUSBDeviceDetach()...\n", mName));
581 HRESULT hrc = mMachine->onUSBDeviceDetach(mId.toUtf16().raw(), NULL);
582 LogFlowThisFunc(("{%s} Done machine->onUSBDeviceDetach()=%Rhrc\n", mName, hrc));
583 NOREF(hrc);
584
585 /*
586 * Re-enter the locks and complete the transition.
587 */
588 alockProxy.enter();
589 alockSelf.enter();
590 advanceTransition();
591}
592
593/**
594 * Called when the VM process to inform us about the device being
595 * detached from it.
596 *
597 * This is NOT called when we detach the device via onUSBDeviceDetach.
598 *
599 *
600 * @param[in] aMachine The machine making the request.
601 * This must be the machine this device is currently attached to.
602 * @param[in] aDone When set to false, the VM just informs us that it's about
603 * to detach this device but hasn't done it just yet.
604 * When set to true, the VM informs us that it has completed
605 * the detaching of this device.
606 * @param[out] aRunFilters Whether to run filters.
607 * @param[in] aAbnormal Set if we're cleaning up after a crashed VM.
608 *
609 * @returns S_OK on success, and E_UNEXPECTED if the device isn't in the right state.
610 *
611 * @note Must be called from under the object write lock.
612 */
613HRESULT HostUSBDevice::onDetachFromVM(SessionMachine *aMachine, bool aDone, bool *aRunFilters, bool aAbnormal /*= true*/)
614{
615 LogFlowThisFunc(("{%s} state=%s aDone=%RTbool aAbnormal=%RTbool\n", mName, getStateName(), aDone, aAbnormal));
616
617 /*
618 * Validate preconditions.
619 */
620 AssertPtrReturn(aRunFilters, E_INVALIDARG);
621 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
622 if (!aDone)
623 {
624 if (mUniState != kHostUSBDeviceState_UsedByVM)
625 return setError(E_INVALIDARG,
626 tr("USB device '%s' with UUID {%RTuuid} is busy (state '%s'). Please try again later"),
627 mName, mId.raw(), getStateName());
628 }
629 else
630 AssertMsgReturn( mUniState == kHostUSBDeviceState_DetachingFromVM /** @todo capturing for VM ends up here on termination. */
631 || (mUniState == kHostUSBDeviceState_UsedByVM && aAbnormal),
632 ("{%s} %s\n", mName, getStateName()), E_UNEXPECTED);
633 AssertMsgReturn((mMachine == aMachine), ("%p != %p\n", (void *)mMachine, aMachine), E_FAIL);
634
635 /*
636 * Change the state.
637 */
638 if (!aDone)
639 {
640 *aRunFilters = startTransition(kHostUSBDeviceState_DetachingFromVM, kHostUSBDeviceState_HeldByProxy);
641 /* PORTME: This might require host specific changes if you re-enumerate the device. */
642 }
643 else if (aAbnormal && mUniState == kHostUSBDeviceState_UsedByVM)
644 {
645 /* Fast forward thru the DetachingFromVM state and on to HeldByProxy. */
646 /** @todo need to update the state machine to handle crashed VMs. */
647 startTransition(kHostUSBDeviceState_DetachingFromVM, kHostUSBDeviceState_HeldByProxy);
648 *aRunFilters = advanceTransition();
649 mMachine.setNull();
650 /* PORTME: ditto / trouble if you depend on the VM process to do anything. */
651 }
652 else
653 {
654 /* normal completion. */
655 Assert(mUniSubState == kHostUSBDeviceSubState_Default); /* PORTME: ditto */
656 *aRunFilters = advanceTransition();
657 mMachine.setNull();
658 }
659
660 return S_OK;
661}
662
663/**
664 * Requests the USB proxy service to release the device back to the host.
665 *
666 * This method will ignore (not assert) calls for devices that already
667 * belong to the host because it simplifies the usage a bit.
668 *
669 * @returns COM status code.
670 * @retval S_OK on success.
671 * @retval E_UNEXPECTED on bad state.
672 * @retval E_* as appropriate.
673 *
674 * @note Must be called from under the object write lock.
675 */
676HRESULT HostUSBDevice::requestReleaseToHost()
677{
678 LogFlowThisFunc(("{%s}\n", mName));
679
680 /*
681 * Validate preconditions.
682 */
683 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
684 Assert(mMachine.isNull());
685 if ( mUniState == kHostUSBDeviceState_Unused
686 || mUniState == kHostUSBDeviceState_Capturable)
687 return S_OK;
688 AssertMsgReturn(mUniState == kHostUSBDeviceState_HeldByProxy, ("{%s} %s\n", mName, getStateName()), E_UNEXPECTED);
689
690 /*
691 * Try release it.
692 */
693#if (defined(RT_OS_DARWIN) && defined(VBOX_WITH_NEW_USB_CODE_ON_DARWIN)) /* PORTME */ \
694 || defined(RT_OS_WINDOWS)
695 startTransition(kHostUSBDeviceState_ReleasingToHost, kHostUSBDeviceState_Unused, kHostUSBDeviceSubState_AwaitingDetach);
696#else
697 startTransition(kHostUSBDeviceState_ReleasingToHost, kHostUSBDeviceState_Unused);
698#endif
699 int rc = mUSBProxyService->releaseDevice(this);
700 if (RT_FAILURE(rc))
701 {
702 failTransition();
703 return E_FAIL;
704 }
705 return S_OK;
706}
707
708/**
709 * Requests the USB proxy service to capture and hold the device.
710 *
711 * The device must be owned by the host at the time of the call. But for
712 * the callers convenience, calling this method on a device that is already
713 * being held will success without any assertions.
714 *
715 * @returns COM status code.
716 * @retval S_OK on success.
717 * @retval E_UNEXPECTED on bad state.
718 * @retval E_* as appropriate.
719 *
720 * @note Must be called from under the object write lock.
721 */
722HRESULT HostUSBDevice::requestHold()
723{
724 LogFlowThisFunc(("{%s}\n", mName));
725
726 /*
727 * Validate preconditions.
728 */
729 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
730 AssertMsgReturn( mUniState == kHostUSBDeviceState_Unused
731 || mUniState == kHostUSBDeviceState_Capturable
732 || mUniState == kHostUSBDeviceState_HeldByProxy,
733 ("{%s} %s\n", mName, getStateName()),
734 E_UNEXPECTED);
735
736 Assert(mMachine.isNull());
737 mMachine.setNull();
738
739 if (mUniState == kHostUSBDeviceState_HeldByProxy)
740 return S_OK;
741
742 /*
743 * Do the job.
744 */
745#if (defined(RT_OS_DARWIN) && defined(VBOX_WITH_NEW_USB_CODE_ON_DARWIN)) /* PORTME */ \
746 || defined(RT_OS_WINDOWS)
747 startTransition(kHostUSBDeviceState_Capturing, kHostUSBDeviceState_HeldByProxy, kHostUSBDeviceSubState_AwaitingDetach);
748#else
749 startTransition(kHostUSBDeviceState_Capturing, kHostUSBDeviceState_HeldByProxy);
750#endif
751 int rc = mUSBProxyService->captureDevice(this);
752 if (RT_FAILURE(rc))
753 {
754 failTransition();
755 return E_FAIL;
756 }
757 return S_OK;
758}
759
760
761/**
762 * Check a detach detected by the USB Proxy Service to see if
763 * it's a real one or just a logical following a re-enumeration.
764 *
765 * This will work the internal sub state of the device and do time
766 * outs, so it does more than just querying data!
767 *
768 * @returns true if it was actually detached, false if it's just a re-enumeration.
769 */
770bool HostUSBDevice::wasActuallyDetached()
771{
772 /*
773 * This only applies to the detach and re-attach states.
774 */
775 switch (mUniState)
776 {
777 case kHostUSBDeviceState_Capturing:
778 case kHostUSBDeviceState_ReleasingToHost:
779 case kHostUSBDeviceState_AttachingToVM:
780 case kHostUSBDeviceState_DetachingFromVM:
781 switch (mUniSubState)
782 {
783 /*
784 * If we're awaiting a detach, the this has now occurred
785 * and the state should be advanced.
786 */
787 case kHostUSBDeviceSubState_AwaitingDetach:
788 advanceTransition();
789 return false; /* not physically detached. */
790
791 /*
792 * Check for timeouts.
793 */
794 case kHostUSBDeviceSubState_AwaitingReAttach:
795 {
796#ifndef RT_OS_WINDOWS /* check the implementation details here. */
797 uint64_t elapsedNanoseconds = RTTimeNanoTS() - mLastStateChangeTS;
798 if (elapsedNanoseconds > UINT64_C (60000000000) ) /* 60 seconds */
799 {
800 LogRel (("USB: Async operation timed out for device %s (state: %s)\n", mName, getStateName()));
801 failTransition();
802 }
803#endif
804 return false; /* not physically detached. */
805 }
806
807 /* not applicable.*/
808 case kHostUSBDeviceSubState_Default:
809 break;
810 }
811 break;
812
813 /* not applicable. */
814 case kHostUSBDeviceState_Unsupported:
815 case kHostUSBDeviceState_UsedByHost:
816 case kHostUSBDeviceState_Capturable:
817 case kHostUSBDeviceState_Unused:
818 case kHostUSBDeviceState_HeldByProxy:
819 case kHostUSBDeviceState_UsedByVM:
820 case kHostUSBDeviceState_PhysDetachingFromVM:
821 case kHostUSBDeviceState_PhysDetached:
822 break;
823
824 default:
825 AssertLogRelMsgFailed (("this=%p %s\n", this, getStateName()));
826 break;
827 }
828
829 /* It was detached. */
830 return true;
831}
832
833/**
834 * Notification from the USB Proxy that the device was physically detached.
835 *
836 * If a transition is pending, mIsPhysicallyDetached will be set and
837 * handled when the transition advances forward.
838 *
839 * Otherwise the device will be detached from any VM currently using it - this
840 * involves IPC and will temporarily abandond locks - and all the device data
841 * reset.
842 *
843 * @note Must be called from under the object write lock.
844 */
845void HostUSBDevice::onPhysicalDetached()
846{
847 LogFlowThisFunc(("{%s}\n", mName));
848 AssertReturnVoid(isWriteLockOnCurrentThread());
849
850 mIsPhysicallyDetached = true;
851 if (mUniState < kHostUSBDeviceState_FirstTransitional)
852 onPhysicalDetachedInternal();
853}
854
855
856/**
857 * Do the physical detach work for a device in a stable state or
858 * at a transition state change.
859 *
860 * See onPhysicalDetach() for details.
861 *
862 * @note Must be called from under the object write lock.
863 */
864void HostUSBDevice::onPhysicalDetachedInternal()
865{
866 LogFlowThisFunc(("{%s}\n", mName));
867 AssertReturnVoid(isWriteLockOnCurrentThread());
868 Assert(mIsPhysicallyDetached);
869
870 /*
871 * Do we need to detach it from the VM first?
872 */
873 if ( !mMachine.isNull()
874 && ( mUniState == kHostUSBDeviceState_UsedByVM
875 || mUniState == kHostUSBDeviceState_AttachingToVM))
876 detachFromVM(kHostUSBDeviceState_PhysDetached);
877 else
878 AssertMsg(mMachine.isNull(), ("%s\n", getStateName()));
879
880 /*
881 * Reset the data and enter the final state.
882 */
883 mMachine.setNull();
884 setState(kHostUSBDeviceState_PhysDetached);
885}
886
887
888/**
889 * Returns true if this device matches the given filter data.
890 *
891 * @note It is assumed, that the filter data owner is appropriately
892 * locked before calling this method.
893 *
894 * @note
895 * This method MUST correlate with
896 * USBController::hasMatchingFilter (IUSBDevice *)
897 * in the sense of the device matching logic.
898 *
899 * @note Locks this object for reading.
900 */
901bool HostUSBDevice::isMatch(const USBDeviceFilter::Data &aData)
902{
903 AutoCaller autoCaller(this);
904 AssertComRCReturn(autoCaller.rc(), false);
905
906 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
907
908 if (!aData.mActive)
909 return false;
910
911 if (!aData.mRemote.isMatch(FALSE))
912 return false;
913
914 if (!USBFilterMatchDevice(&aData.mUSBFilter, mUsb))
915 return false;
916
917 /* Don't match busy devices with a 100% wildcard filter - this will
918 later become a filter prop (ring-3 only). */
919 if ( mUsb->enmState == USBDEVICESTATE_USED_BY_HOST_CAPTURABLE
920 && !USBFilterHasAnySubstatialCriteria(&aData.mUSBFilter))
921 return false;
922
923 LogFlowThisFunc(("returns true\n"));
924 return true;
925}
926
927/**
928 * Compares this device with a USBDEVICE and decides if the match or which comes first.
929 *
930 * This will take into account device re-attaching and omit the bits
931 * that may change during a device re-enumeration.
932 *
933 * @param aDev2 Device 2.
934 *
935 * @returns < 0 if this should come before aDev2.
936 * @returns 0 if this and aDev2 are equal.
937 * @returns > 0 if this should come after aDev2.
938 *
939 * @note Must be called from under the object write lock.
940 */
941int HostUSBDevice::compare(PCUSBDEVICE aDev2)
942{
943 AssertReturn(isWriteLockOnCurrentThread(), -1);
944 //Log3(("%Rfn: %p {%s}\n", __PRETTY_FUNCTION__, this, mName));
945 return compare(mUsb, aDev2,
946 mUniSubState == kHostUSBDeviceSubState_AwaitingDetach /* (In case we don't get the detach notice.) */
947 || mUniSubState == kHostUSBDeviceSubState_AwaitingReAttach);
948}
949
950/**
951 * Compares two USBDEVICE structures and decides if the match or which comes first.
952 *
953 * @param aDev1 Device 1.
954 * @param aDev2 Device 2.
955 * @param aIsAwaitingReAttach Whether to omit bits that will change in a device
956 * re-enumeration (true) or not (false).
957 *
958 * @returns < 0 if aDev1 should come before aDev2.
959 * @returns 0 if aDev1 and aDev2 are equal.
960 * @returns > 0 if aDev1 should come after aDev2.
961 */
962/*static*/
963int HostUSBDevice::compare(PCUSBDEVICE aDev1, PCUSBDEVICE aDev2, bool aIsAwaitingReAttach /*= false */)
964{
965 /*
966 * Things that stays the same everywhere.
967 *
968 * The more uniquely these properties identifies a device the less the chance
969 * that we mix similar devices during re-enumeration. Bus+port would help
970 * provide ~99.8% accuracy if the host can provide those attributes.
971 */
972 int iDiff = aDev1->idVendor - aDev2->idVendor;
973 if (iDiff)
974 return iDiff;
975
976 iDiff = aDev1->idProduct - aDev2->idProduct;
977 if (iDiff)
978 return iDiff;
979
980 iDiff = aDev1->bcdDevice - aDev2->bcdDevice;
981 if (iDiff)
982 {
983 //Log3(("compare: bcdDevice: %#x != %#x\n", aDev1->bcdDevice, aDev2->bcdDevice));
984 return iDiff;
985 }
986
987#ifdef RT_OS_WINDOWS /* the string query may fail on windows during replugging, ignore serial mismatch if this is the case. */
988 if ( aDev1->u64SerialHash != aDev2->u64SerialHash
989 && ( !aIsAwaitingReAttach
990 || (aDev2->pszSerialNumber && *aDev2->pszSerialNumber)
991 || (aDev2->pszManufacturer && *aDev2->pszManufacturer)
992 || (aDev2->pszProduct && *aDev2->pszProduct))
993 )
994#else
995 if (aDev1->u64SerialHash != aDev2->u64SerialHash)
996#endif
997 {
998 //Log3(("compare: u64SerialHash: %#llx != %#llx\n", aDev1->u64SerialHash, aDev2->u64SerialHash));
999 return aDev1->u64SerialHash < aDev2->u64SerialHash ? -1 : 1;
1000 }
1001
1002 /* The hub/bus + port should help a lot in a re-attach situation. */
1003#ifdef RT_OS_WINDOWS
1004 iDiff = strcmp(aDev1->pszHubName, aDev2->pszHubName);
1005 if (iDiff)
1006 {
1007 //Log3(("compare: HubName: %s != %s\n", aDev1->pszHubName, aDev2->pszHubName));
1008 return iDiff;
1009 }
1010#else
1011 iDiff = aDev1->bBus - aDev2->bBus;
1012 if (iDiff)
1013 {
1014 //Log3(("compare: bBus: %#x != %#x\n", aDev1->bBus, aDev2->bBus));
1015 return iDiff;
1016 }
1017#endif
1018
1019 iDiff = aDev1->bPort - aDev2->bPort; /* shouldn't change anywhere and help pinpoint it very accurately. */
1020 if (iDiff)
1021 {
1022 //Log3(("compare: bPort: %#x != %#x\n", aDev1->bPort, aDev2->bPort));
1023 return iDiff;
1024 }
1025
1026 /*
1027 * Things that usually doesn't stay the same when re-enumerating
1028 * a device. The fewer things in the category the better chance
1029 * that we avoid messing up when more than one device of the same
1030 * kind is attached.
1031 */
1032 if (aIsAwaitingReAttach)
1033 {
1034 //Log3(("aDev1=%p == aDev2=%p\n", aDev1, aDev2));
1035 return 0;
1036 }
1037 /* device number always changes. */
1038 return strcmp(aDev1->pszAddress, aDev2->pszAddress);
1039}
1040
1041/**
1042 * Updates the state of the device.
1043 *
1044 * If this method returns @c true, Host::onUSBDeviceStateChanged() will be
1045 * called to process the state change (complete the state change request,
1046 * inform the VM process etc.).
1047 *
1048 * If this method returns @c false, it is assumed that the given state change
1049 * is "minor": it doesn't require any further action other than update the
1050 * mState field with the actual state value.
1051 *
1052 * Regardless of the return value, this method always takes ownership of the
1053 * new USBDEVICE structure passed in and updates the pNext and pPrev fiends in
1054 * it using the values of the old structure.
1055 *
1056 * @param[in] aDev The current device state as seen by the proxy backend.
1057 * @param[out] aRunFilters Whether the state change should be accompanied by
1058 * running filters on the device.
1059 * @param[out] aIgnoreMachine Machine to ignore when running filters.
1060 *
1061 * @returns Whether the Host object should be bothered with this state change.
1062 *
1063 * @note Locks this object for writing.
1064 *
1065 * @todo Just do everything here, that is, call filter runners and everything that
1066 * works by state change. Using 3 return codes/parameters is just plain ugly.
1067 */
1068bool HostUSBDevice::updateState(PCUSBDEVICE aDev, bool *aRunFilters, SessionMachine **aIgnoreMachine)
1069{
1070 *aRunFilters = false;
1071 *aIgnoreMachine = NULL;
1072
1073 /*
1074 * Locking.
1075 */
1076 AssertReturn(isWriteLockOnCurrentThread(), false);
1077 AutoCaller autoCaller(this);
1078 AssertComRCReturn(autoCaller.rc(), false);
1079 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1080
1081
1082 /*
1083 * Replace the existing structure by the new one.
1084 */
1085 const USBDEVICESTATE enmOldState = mUsb->enmState; NOREF(enmOldState);
1086 if (mUsb != aDev)
1087 {
1088 aDev->pNext = mUsb->pNext;
1089 aDev->pPrev = mUsb->pPrev;
1090 USBProxyService::freeDevice (mUsb);
1091 mUsb = aDev;
1092 }
1093
1094/** @def HOSTUSBDEVICE_FUZZY_STATE
1095 * Defined on hosts where we have a driver that keeps proper device states.
1096 */
1097# if defined(RT_OS_LINUX) || defined(DOXYGEN_RUNNING)
1098# define HOSTUSBDEVICE_FUZZY_STATE 1
1099# else
1100# undef HOSTUSBDEVICE_FUZZY_STATE
1101# endif
1102 /*
1103 * For some hosts we'll have to be pretty careful here because
1104 * they don't always have a clue what is going on. This is
1105 * particularly true on linux and solaris, while windows and
1106 * darwin generally knows a bit more.
1107 */
1108 bool fIsImportant = false;
1109 if (enmOldState != mUsb->enmState)
1110 {
1111 LogFlowThisFunc(("%p {%s} %s\n", this, mName, getStateName()));
1112 switch (mUsb->enmState)
1113 {
1114 /*
1115 * Little fuzziness here, except where we fake capture.
1116 */
1117 case USBDEVICESTATE_USED_BY_HOST:
1118 switch (mUniState)
1119 {
1120 /* Host drivers installed, that's fine. */
1121 case kHostUSBDeviceState_Capturable:
1122 case kHostUSBDeviceState_Unused:
1123 LogThisFunc(("{%s} %s -> %s\n", mName, getStateName(), stateName(kHostUSBDeviceState_UsedByHost)));
1124 *aRunFilters = setState(kHostUSBDeviceState_UsedByHost);
1125 break;
1126 case kHostUSBDeviceState_UsedByHost:
1127 break;
1128
1129 /* Can only mean that we've failed capturing it. */
1130 case kHostUSBDeviceState_Capturing:
1131 LogThisFunc(("{%s} capture failed!\n", mName));
1132 mUSBProxyService->captureDeviceCompleted(this, false /* aSuccess */);
1133 *aRunFilters = failTransition();
1134 mMachine.setNull();
1135 break;
1136
1137 /* Guess we've successfully released it. */
1138 case kHostUSBDeviceState_ReleasingToHost:
1139 LogThisFunc(("{%s} %s -> %s\n", mName, getStateName(), stateName(kHostUSBDeviceState_UsedByHost)));
1140 mUSBProxyService->releaseDeviceCompleted(this, true /* aSuccess */);
1141 *aRunFilters = setState(kHostUSBDeviceState_UsedByHost);
1142 break;
1143
1144 /* These are IPC states and should be left alone. */
1145 case kHostUSBDeviceState_AttachingToVM:
1146 case kHostUSBDeviceState_DetachingFromVM:
1147 case kHostUSBDeviceState_PhysDetachingFromVM:
1148 LogThisFunc(("{%s} %s - changed to USED_BY_HOST...\n", mName, getStateName()));
1149 break;
1150
1151#ifdef HOSTUSBDEVICE_FUZZY_STATE
1152 /* Fake: We can't prevent anyone from grabbing it. */
1153 case kHostUSBDeviceState_HeldByProxy:
1154 LogThisFunc(("{%s} %s -> %s!\n", mName, getStateName(), stateName(kHostUSBDeviceState_UsedByHost)));
1155 *aRunFilters = setState(kHostUSBDeviceState_UsedByHost);
1156 break;
1157 //case kHostUSBDeviceState_UsedByVM:
1158 // /** @todo needs to be detached from the VM. */
1159 // break;
1160#endif
1161 /* Not supposed to happen... */
1162#ifndef HOSTUSBDEVICE_FUZZY_STATE
1163 case kHostUSBDeviceState_HeldByProxy:
1164#endif
1165 case kHostUSBDeviceState_UsedByVM:
1166 case kHostUSBDeviceState_PhysDetached:
1167 case kHostUSBDeviceState_Unsupported:
1168 default:
1169 AssertMsgFailed(("{%s} %s\n", mName, getStateName()));
1170 break;
1171 }
1172 break;
1173
1174 /*
1175 * It changed to capturable. Fuzzy hosts might easily
1176 * confuse UsedByVM with this one.
1177 */
1178 case USBDEVICESTATE_USED_BY_HOST_CAPTURABLE:
1179 switch (mUniState)
1180 {
1181 /* No change. */
1182#ifdef HOSTUSBDEVICE_FUZZY_STATE
1183 case kHostUSBDeviceState_HeldByProxy:
1184 case kHostUSBDeviceState_UsedByVM:
1185#endif
1186 case kHostUSBDeviceState_Capturable:
1187 break;
1188
1189 /* Changed! */
1190 case kHostUSBDeviceState_UsedByHost:
1191 fIsImportant = true;
1192 case kHostUSBDeviceState_Unused:
1193 LogThisFunc(("{%s} %s -> %s\n", mName, getStateName(), stateName(kHostUSBDeviceState_Capturable)));
1194 *aRunFilters = setState(kHostUSBDeviceState_Capturable);
1195 break;
1196
1197 /* Can only mean that we've failed capturing it. */
1198 case kHostUSBDeviceState_Capturing:
1199 LogThisFunc(("{%s} capture failed!\n", mName));
1200 mUSBProxyService->captureDeviceCompleted(this, false /* aSuccess */);
1201 *aRunFilters = failTransition();
1202 mMachine.setNull();
1203 break;
1204
1205 /* Guess we've successfully released it. */
1206 case kHostUSBDeviceState_ReleasingToHost:
1207 LogThisFunc(("{%s} %s -> %s\n", mName, getStateName(), stateName(kHostUSBDeviceState_Capturable)));
1208 mUSBProxyService->releaseDeviceCompleted(this, true /* aSuccess */);
1209 *aRunFilters = setState(kHostUSBDeviceState_Capturable);
1210 break;
1211
1212 /* These are IPC states and should be left alone. */
1213 case kHostUSBDeviceState_AttachingToVM:
1214 case kHostUSBDeviceState_DetachingFromVM:
1215 case kHostUSBDeviceState_PhysDetachingFromVM:
1216 LogThisFunc(("{%s} %s - changed to USED_BY_HOST_CAPTURABLE...\n", mName, getStateName()));
1217 break;
1218
1219 /* Not supposed to happen*/
1220#ifndef HOSTUSBDEVICE_FUZZY_STATE
1221 case kHostUSBDeviceState_HeldByProxy:
1222 case kHostUSBDeviceState_UsedByVM:
1223#endif
1224 case kHostUSBDeviceState_Unsupported:
1225 case kHostUSBDeviceState_PhysDetached:
1226 default:
1227 AssertMsgFailed(("{%s} %s\n", mName, getStateName()));
1228 break;
1229 }
1230 break;
1231
1232
1233 /*
1234 * It changed to capturable. Fuzzy hosts might easily
1235 * confuse UsedByVM and HeldByProxy with this one.
1236 */
1237 case USBDEVICESTATE_UNUSED:
1238 switch (mUniState)
1239 {
1240 /* No change. */
1241#ifdef HOSTUSBDEVICE_FUZZY_STATE
1242 case kHostUSBDeviceState_HeldByProxy:
1243 case kHostUSBDeviceState_UsedByVM:
1244#endif
1245 case kHostUSBDeviceState_Unused:
1246 break;
1247
1248 /* Changed! */
1249 case kHostUSBDeviceState_UsedByHost:
1250 case kHostUSBDeviceState_Capturable:
1251 fIsImportant = true;
1252 LogThisFunc(("{%s} %s -> %s\n", mName, getStateName(), stateName(kHostUSBDeviceState_Unused)));
1253 *aRunFilters = setState(kHostUSBDeviceState_Unused);
1254 break;
1255
1256 /* Can mean that we've failed capturing it, but on windows it is the detach signal. */
1257 case kHostUSBDeviceState_Capturing:
1258#if defined(RT_OS_WINDOWS)
1259 if (mUniSubState == kHostUSBDeviceSubState_AwaitingDetach)
1260 {
1261 LogThisFunc(("{%s} capture advancing thru UNUSED...\n", mName));
1262 *aRunFilters = advanceTransition();
1263 }
1264 else
1265#endif
1266 {
1267 LogThisFunc(("{%s} capture failed!\n", mName));
1268 mUSBProxyService->captureDeviceCompleted(this, false /* aSuccess */);
1269 *aRunFilters = failTransition();
1270 mMachine.setNull();
1271 }
1272 break;
1273
1274 /* Guess we've successfully released it. */
1275 case kHostUSBDeviceState_ReleasingToHost:
1276 LogThisFunc(("{%s} %s -> %s\n", mName, getStateName(), stateName(kHostUSBDeviceState_Unused)));
1277 mUSBProxyService->releaseDeviceCompleted(this, true /* aSuccess */);
1278 *aRunFilters = setState(kHostUSBDeviceState_Unused);
1279 break;
1280
1281 /* These are IPC states and should be left alone. */
1282 case kHostUSBDeviceState_AttachingToVM:
1283 case kHostUSBDeviceState_DetachingFromVM:
1284 case kHostUSBDeviceState_PhysDetachingFromVM:
1285 LogThisFunc(("{%s} %s - changed to UNUSED...\n", mName, getStateName()));
1286 break;
1287
1288 /* Not supposed to happen*/
1289#ifndef HOSTUSBDEVICE_FUZZY_STATE
1290 case kHostUSBDeviceState_HeldByProxy:
1291 case kHostUSBDeviceState_UsedByVM:
1292#endif
1293 case kHostUSBDeviceState_Unsupported:
1294 case kHostUSBDeviceState_PhysDetached:
1295 default:
1296 AssertMsgFailed(("{%s} %s\n", mName, getStateName()));
1297 break;
1298 }
1299 break;
1300
1301 /*
1302 * This is pretty straight forward, except that everyone
1303 * might sometimes confuse this and the UsedByVM state.
1304 */
1305 case USBDEVICESTATE_HELD_BY_PROXY:
1306 switch (mUniState)
1307 {
1308 /* No change. */
1309 case kHostUSBDeviceState_HeldByProxy:
1310 break;
1311 case kHostUSBDeviceState_UsedByVM:
1312 LogThisFunc(("{%s} %s - changed to HELD_BY_PROXY...\n", mName, getStateName()));
1313 break;
1314
1315 /* Guess we've successfully captured it. */
1316 case kHostUSBDeviceState_Capturing:
1317 LogThisFunc(("{%s} capture succeeded!\n", mName));
1318 mUSBProxyService->captureDeviceCompleted(this, true /* aSuccess */);
1319 *aRunFilters = advanceTransition(true /* fast forward thru re-attach */);
1320
1321 /* Take action if we're supposed to attach it to a VM. */
1322 if (mUniState == kHostUSBDeviceState_AttachingToVM)
1323 attachToVM(mMachine, mMaskedIfs);
1324 break;
1325
1326 /* Can only mean that we've failed capturing it. */
1327 case kHostUSBDeviceState_ReleasingToHost:
1328 LogThisFunc(("{%s} %s failed!\n", mName, getStateName()));
1329 mUSBProxyService->releaseDeviceCompleted(this, false /* aSuccess */);
1330 *aRunFilters = setState(kHostUSBDeviceState_HeldByProxy);
1331 break;
1332
1333 /* These are IPC states and should be left alone. */
1334 case kHostUSBDeviceState_AttachingToVM:
1335 case kHostUSBDeviceState_DetachingFromVM:
1336 case kHostUSBDeviceState_PhysDetachingFromVM:
1337 LogThisFunc(("{%s} %s - changed to HELD_BY_PROXY...\n", mName, getStateName()));
1338 break;
1339
1340 /* Not supposed to happen. */
1341 case kHostUSBDeviceState_Unsupported:
1342 case kHostUSBDeviceState_UsedByHost:
1343 case kHostUSBDeviceState_Capturable:
1344 case kHostUSBDeviceState_Unused:
1345 case kHostUSBDeviceState_PhysDetached:
1346 default:
1347 AssertMsgFailed(("{%s} %s\n", mName, getStateName()));
1348 break;
1349 }
1350 break;
1351
1352 /*
1353 * This is very straight forward and only Darwin implements it.
1354 */
1355 case USBDEVICESTATE_USED_BY_GUEST:
1356 switch (mUniState)
1357 {
1358 /* No change. */
1359 case kHostUSBDeviceState_HeldByProxy:
1360 LogThisFunc(("{%s} %s - changed to USED_BY_GUEST...\n", mName, getStateName()));
1361 break;
1362 case kHostUSBDeviceState_UsedByVM:
1363 break;
1364
1365 /* These are IPC states and should be left alone. */
1366 case kHostUSBDeviceState_AttachingToVM:
1367 case kHostUSBDeviceState_DetachingFromVM:
1368 case kHostUSBDeviceState_PhysDetachingFromVM:
1369 LogThisFunc(("{%s} %s - changed to USED_BY_GUEST...\n", mName, getStateName()));
1370 break;
1371
1372 /* Not supposed to happen. */
1373 case kHostUSBDeviceState_Unsupported:
1374 case kHostUSBDeviceState_Capturable:
1375 case kHostUSBDeviceState_Unused:
1376 case kHostUSBDeviceState_UsedByHost:
1377 case kHostUSBDeviceState_PhysDetached:
1378 case kHostUSBDeviceState_ReleasingToHost:
1379 case kHostUSBDeviceState_Capturing:
1380 default:
1381 AssertMsgFailed(("{%s} %s\n", mName, getStateName()));
1382 break;
1383 }
1384 break;
1385
1386 /*
1387 * This is not supposed to happen and indicates a bug in the backend!
1388 */
1389 case USBDEVICESTATE_UNSUPPORTED:
1390 AssertMsgFailed(("enmOldState=%d {%s} %s\n", enmOldState, mName, getStateName()));
1391 break;
1392 default:
1393 AssertMsgFailed(("enmState=%d {%s} %s\n", mUsb->enmState, mName, getStateName()));
1394 break;
1395 }
1396 }
1397 else if ( mUniSubState == kHostUSBDeviceSubState_AwaitingDetach
1398 && hasAsyncOperationTimedOut())
1399 {
1400 LogRel(("USB: timeout in %s for {%RTuuid} / {%s}\n",
1401 getStateName(), mId.raw(), mName));
1402 *aRunFilters = failTransition();
1403 fIsImportant = true;
1404 }
1405 else
1406 {
1407 LogFlowThisFunc(("%p {%s} %s - no change %d\n", this, mName, getStateName(), enmOldState));
1408 /** @todo might have to handle some stuff here too if we cannot make the release/capture handling deal with that above ... */
1409 }
1410
1411 return fIsImportant;
1412
1413}
1414
1415
1416/**
1417 * Updates the state of the device, checking for cases which we fake.
1418 *
1419 * See HostUSBDevice::updateState() for details.
1420 *
1421 * @param[in] aDev See HostUSBDevice::updateState().
1422 * @param[out] aRunFilters See HostUSBDevice::updateState()
1423 * @param[out] aIgnoreMachine See HostUSBDevice::updateState()
1424 *
1425 * @returns See HostUSBDevice::updateState()
1426 *
1427 * @note Caller must write lock the object.
1428 */
1429bool HostUSBDevice::updateStateFake(PCUSBDEVICE aDev, bool *aRunFilters, SessionMachine **aIgnoreMachine)
1430{
1431 const HostUSBDeviceState enmState = mUniState;
1432 switch (enmState)
1433 {
1434 case kHostUSBDeviceState_Capturing:
1435 case kHostUSBDeviceState_ReleasingToHost:
1436 {
1437 Assert(isWriteLockOnCurrentThread());
1438
1439 *aIgnoreMachine = mUniState == kHostUSBDeviceState_ReleasingToHost ? mMachine : NULL;
1440 *aRunFilters = advanceTransition();
1441 LogThisFunc(("{%s} %s\n", mName, getStateName()));
1442
1443 if (mUsb != aDev)
1444 {
1445 aDev->pNext = mUsb->pNext;
1446 aDev->pPrev = mUsb->pPrev;
1447 USBProxyService::freeDevice(mUsb);
1448 mUsb = aDev;
1449 }
1450
1451 /* call the completion method */
1452 if (enmState == kHostUSBDeviceState_Capturing)
1453 mUSBProxyService->captureDeviceCompleted(this, true /* aSuccess */);
1454 else
1455 mUSBProxyService->releaseDeviceCompleted(this, true /* aSuccess */);
1456
1457 /* Take action if we're supposed to attach it to a VM. */
1458 if (mUniState == kHostUSBDeviceState_AttachingToVM)
1459 attachToVM(mMachine, mMaskedIfs);
1460 return true;
1461 }
1462
1463 default:
1464 return updateState(aDev, aRunFilters, aIgnoreMachine);
1465 }
1466}
1467
1468
1469/**
1470 * Checks if there is a pending asynchronous operation and whether
1471 * it has timed out or not.
1472 *
1473 * @returns true on timeout, false if not.
1474 *
1475 * @note Caller must have read or write locked the object before calling.
1476 */
1477bool HostUSBDevice::hasAsyncOperationTimedOut() const
1478{
1479 switch (mUniSubState)
1480 {
1481#ifndef RT_OS_WINDOWS /* no timeouts on windows yet since I don't have all the details here... */
1482 case kHostUSBDeviceSubState_AwaitingDetach:
1483 case kHostUSBDeviceSubState_AwaitingReAttach:
1484 {
1485 uint64_t elapsedNanoseconds = RTTimeNanoTS() - mLastStateChangeTS;
1486 return elapsedNanoseconds > UINT64_C(60000000000); /* 60 seconds */ /* PORTME */
1487 }
1488#endif
1489 default:
1490 return false;
1491 }
1492}
1493
1494
1495/**
1496 * Translate the state into
1497 *
1498 * @returns
1499 * @param aState
1500 * @param aSubState
1501 * @param aPendingState
1502 */
1503/*static*/ const char *HostUSBDevice::stateName(HostUSBDeviceState aState,
1504 HostUSBDeviceState aPendingState /*= kHostUSBDeviceState_Invalid*/,
1505 HostUSBDeviceSubState aSubState /*= kHostUSBDeviceSubState_Default*/)
1506{
1507 switch (aState)
1508 {
1509 case kHostUSBDeviceState_Unsupported:
1510 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "Unsupported{bad}");
1511 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "Unsupported[bad]");
1512 return "Unsupported";
1513
1514 case kHostUSBDeviceState_UsedByHost:
1515 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "UsedByHost{bad}");
1516 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "UsedByHost[bad]");
1517 return "UsedByHost";
1518
1519 case kHostUSBDeviceState_Capturable:
1520 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "Capturable{bad}");
1521 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "Capturable[bad]");
1522 return "Capturable";
1523
1524 case kHostUSBDeviceState_Unused:
1525 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "Unused{bad}");
1526 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "Unused[bad]");
1527 return "Unused";
1528
1529 case kHostUSBDeviceState_HeldByProxy:
1530 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "HeldByProxy{bad}");
1531 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "HeldByProxy[bad]");
1532 return "HeldByProxy";
1533
1534 case kHostUSBDeviceState_UsedByVM:
1535 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "UsedByVM{bad}");
1536 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "UsedByVM[bad]");
1537 return "UsedByVM";
1538
1539 case kHostUSBDeviceState_PhysDetached:
1540 AssertReturn(aPendingState == kHostUSBDeviceState_Invalid, "PhysDetached{bad}");
1541 AssertReturn(aSubState == kHostUSBDeviceSubState_Default, "PhysDetached[bad]");
1542 return "PhysDetached";
1543
1544 case kHostUSBDeviceState_Capturing:
1545 switch (aPendingState)
1546 {
1547 case kHostUSBDeviceState_UsedByVM:
1548 switch (aSubState)
1549 {
1550 case kHostUSBDeviceSubState_Default:
1551 return "CapturingForVM";
1552 case kHostUSBDeviceSubState_AwaitingDetach:
1553 return "CapturingForVM[Detach]";
1554 case kHostUSBDeviceSubState_AwaitingReAttach:
1555 return "CapturingForVM[Attach]";
1556 default:
1557 AssertFailedReturn("CapturingForVM[bad]");
1558 }
1559 break;
1560
1561 case kHostUSBDeviceState_HeldByProxy:
1562 switch (aSubState)
1563 {
1564 case kHostUSBDeviceSubState_Default:
1565 return "CapturingForProxy";
1566 case kHostUSBDeviceSubState_AwaitingDetach:
1567 return "CapturingForProxy[Detach]";
1568 case kHostUSBDeviceSubState_AwaitingReAttach:
1569 return "CapturingForProxy[Attach]";
1570 default:
1571 AssertFailedReturn("CapturingForProxy[bad]");
1572 }
1573 break;
1574
1575 default:
1576 AssertFailedReturn("Capturing{bad}");
1577 }
1578 break;
1579
1580 case kHostUSBDeviceState_ReleasingToHost:
1581 switch (aPendingState)
1582 {
1583 case kHostUSBDeviceState_Unused:
1584 switch (aSubState)
1585 {
1586 case kHostUSBDeviceSubState_Default:
1587 return "ReleasingToHost";
1588 case kHostUSBDeviceSubState_AwaitingDetach:
1589 return "ReleasingToHost[Detach]";
1590 case kHostUSBDeviceSubState_AwaitingReAttach:
1591 return "ReleasingToHost[Attach]";
1592 default:
1593 AssertFailedReturn("ReleasingToHost[bad]");
1594 }
1595 break;
1596 default:
1597 AssertFailedReturn("ReleasingToHost{bad}");
1598 }
1599 break;
1600
1601 case kHostUSBDeviceState_DetachingFromVM:
1602 switch (aPendingState)
1603 {
1604 case kHostUSBDeviceState_HeldByProxy:
1605 switch (aSubState)
1606 {
1607 case kHostUSBDeviceSubState_Default:
1608 return "DetatchingFromVM>Proxy";
1609 case kHostUSBDeviceSubState_AwaitingDetach:
1610 return "DetatchingFromVM>Proxy[Detach]";
1611 case kHostUSBDeviceSubState_AwaitingReAttach:
1612 return "DetatchingFromVM>Proxy[Attach]";
1613 default:
1614 AssertFailedReturn("DetatchingFromVM>Proxy[bad]");
1615 }
1616 break;
1617
1618 case kHostUSBDeviceState_Unused:
1619 switch (aSubState)
1620 {
1621 case kHostUSBDeviceSubState_Default:
1622 return "DetachingFromVM>Host";
1623 case kHostUSBDeviceSubState_AwaitingDetach:
1624 return "DetachingFromVM>Host[Detach]";
1625 case kHostUSBDeviceSubState_AwaitingReAttach:
1626 return "DetachingFromVM>Host[Attach]";
1627 default:
1628 AssertFailedReturn("DetachingFromVM>Host[bad]");
1629 }
1630 break;
1631
1632 default:
1633 AssertFailedReturn("DetachingFromVM{bad}");
1634 }
1635 break;
1636
1637 case kHostUSBDeviceState_AttachingToVM:
1638 switch (aPendingState)
1639 {
1640 case kHostUSBDeviceState_UsedByVM:
1641 switch (aSubState)
1642 {
1643 case kHostUSBDeviceSubState_Default:
1644 return "AttachingToVM";
1645 case kHostUSBDeviceSubState_AwaitingDetach:
1646 return "AttachingToVM[Detach]";
1647 case kHostUSBDeviceSubState_AwaitingReAttach:
1648 return "AttachingToVM[Attach]";
1649 default:
1650 AssertFailedReturn("AttachingToVM[bad]");
1651 }
1652 break;
1653
1654 default:
1655 AssertFailedReturn("AttachingToVM{bad}");
1656 }
1657 break;
1658
1659
1660 case kHostUSBDeviceState_PhysDetachingFromVM:
1661 switch (aPendingState)
1662 {
1663 case kHostUSBDeviceState_PhysDetached:
1664 switch (aSubState)
1665 {
1666 case kHostUSBDeviceSubState_Default:
1667 return "PhysDetachingFromVM";
1668 default:
1669 AssertFailedReturn("AttachingToVM[bad]");
1670 }
1671 break;
1672
1673 default:
1674 AssertFailedReturn("AttachingToVM{bad}");
1675 }
1676 break;
1677
1678 default:
1679 AssertFailedReturn("BadState");
1680
1681 }
1682
1683 AssertFailedReturn("shouldn't get here");
1684}
1685
1686/**
1687 * Set the device state.
1688 *
1689 * This method will verify that the state transition is a legal one
1690 * according to the statemachine. It will also take care of the
1691 * associated house keeping and determine if filters needs to be applied.
1692 *
1693 * @param aNewState The new state.
1694 * @param aNewPendingState The final state of a transition when applicable.
1695 * @param aNewSubState The new sub-state when applicable.
1696 *
1697 * @returns true if filters should be applied to the device, false if not.
1698 *
1699 * @note The caller must own the write lock for this object.
1700 */
1701bool HostUSBDevice::setState(HostUSBDeviceState aNewState, HostUSBDeviceState aNewPendingState /*= kHostUSBDeviceState_Invalid*/,
1702 HostUSBDeviceSubState aNewSubState /*= kHostUSBDeviceSubState_Default*/)
1703{
1704 Assert(isWriteLockOnCurrentThread());
1705 Assert( aNewSubState == kHostUSBDeviceSubState_Default
1706 || aNewSubState == kHostUSBDeviceSubState_AwaitingDetach
1707 || aNewSubState == kHostUSBDeviceSubState_AwaitingReAttach);
1708
1709 /*
1710 * If the state is unchanged, then don't bother going
1711 * thru the validation and setting. This saves a bit of code.
1712 */
1713 if ( aNewState == mUniState
1714 && aNewPendingState == mPendingUniState
1715 && aNewSubState == mUniSubState)
1716 return false;
1717
1718 /*
1719 * Welcome to the switch orgies!
1720 * You're welcome to check out the ones in startTransition(),
1721 * advanceTransition(), failTransition() and getStateName() too. Enjoy!
1722 */
1723
1724 bool fFilters = false;
1725 HostUSBDeviceState NewPrevState = mUniState;
1726 switch (mUniState)
1727 {
1728 /*
1729 * Not much can be done with a device in this state.
1730 */
1731 case kHostUSBDeviceState_Unsupported:
1732 switch (aNewState)
1733 {
1734 case kHostUSBDeviceState_PhysDetached:
1735 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1736 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1737 break;
1738 default:
1739 AssertLogRelMsgFailedReturn(("this=%p %s -X-> %s\n", this, getStateName(),
1740 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1741 }
1742 break;
1743
1744 /*
1745 * Only the host OS (or the user) can make changes
1746 * that'll make a device get out of this state.
1747 */
1748 case kHostUSBDeviceState_UsedByHost:
1749 switch (aNewState)
1750 {
1751 case kHostUSBDeviceState_Capturable:
1752 case kHostUSBDeviceState_Unused:
1753 fFilters = true;
1754 case kHostUSBDeviceState_PhysDetached:
1755 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1756 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1757 break;
1758 default:
1759 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1760 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1761 }
1762 break;
1763
1764 /*
1765 * Now it gets interesting.
1766 */
1767 case kHostUSBDeviceState_Capturable:
1768 switch (aNewState)
1769 {
1770 /* Host changes. */
1771 case kHostUSBDeviceState_Unused:
1772 fFilters = true; /* Wildcard only... */
1773 case kHostUSBDeviceState_UsedByHost:
1774 case kHostUSBDeviceState_PhysDetached:
1775 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1776 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1777 break;
1778
1779 /* VBox actions */
1780 case kHostUSBDeviceState_Capturing:
1781 switch (aNewPendingState)
1782 {
1783 case kHostUSBDeviceState_HeldByProxy:
1784 case kHostUSBDeviceState_UsedByVM:
1785 break;
1786 default:
1787 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1788 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1789 }
1790 break;
1791 default:
1792 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1793 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1794 }
1795 break;
1796
1797 case kHostUSBDeviceState_Unused:
1798 switch (aNewState)
1799 {
1800 /* Host changes. */
1801 case kHostUSBDeviceState_PhysDetached:
1802 case kHostUSBDeviceState_UsedByHost:
1803 case kHostUSBDeviceState_Capturable:
1804 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1805 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1806 break;
1807
1808 /* VBox actions */
1809 case kHostUSBDeviceState_Capturing:
1810 switch (aNewPendingState)
1811 {
1812 case kHostUSBDeviceState_HeldByProxy:
1813 case kHostUSBDeviceState_UsedByVM:
1814 break;
1815 default:
1816 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1817 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1818 }
1819 break;
1820 default:
1821 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1822 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1823 }
1824 break;
1825
1826 /*
1827 * VBox owns this device now, what's next...
1828 */
1829 case kHostUSBDeviceState_HeldByProxy:
1830 switch (aNewState)
1831 {
1832 /* Host changes. */
1833 case kHostUSBDeviceState_PhysDetached:
1834 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1835 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1836 break;
1837
1838 /* VBox actions */
1839 case kHostUSBDeviceState_AttachingToVM:
1840 switch (aNewPendingState)
1841 {
1842 case kHostUSBDeviceState_UsedByVM:
1843 break;
1844 default:
1845 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1846 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1847 }
1848 break;
1849 case kHostUSBDeviceState_ReleasingToHost:
1850 switch (aNewPendingState)
1851 {
1852 case kHostUSBDeviceState_Unused: /* Only this! */
1853 break;
1854 default:
1855 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1856 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1857 }
1858 break;
1859 default:
1860 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1861 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1862 }
1863 break;
1864
1865
1866 case kHostUSBDeviceState_UsedByVM:
1867 switch (aNewState)
1868 {
1869 /* Host changes. */
1870 case kHostUSBDeviceState_PhysDetachingFromVM:
1871 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1872 Assert(aNewPendingState == kHostUSBDeviceState_PhysDetached);
1873 break;
1874
1875 /* VBox actions */
1876 case kHostUSBDeviceState_DetachingFromVM:
1877 switch (aNewPendingState)
1878 {
1879 case kHostUSBDeviceState_HeldByProxy:
1880 case kHostUSBDeviceState_Unused: /* Only this! */
1881 break;
1882 default:
1883 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1884 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1885 }
1886 break;
1887 default:
1888 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1889 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1890 }
1891 break;
1892
1893 /*
1894 * The final state.
1895 */
1896 case kHostUSBDeviceState_PhysDetached:
1897 switch (mUniState)
1898 {
1899 case kHostUSBDeviceState_Unsupported:
1900 case kHostUSBDeviceState_UsedByHost:
1901 case kHostUSBDeviceState_Capturable:
1902 case kHostUSBDeviceState_Unused:
1903 case kHostUSBDeviceState_HeldByProxy:
1904 case kHostUSBDeviceState_PhysDetachingFromVM:
1905 case kHostUSBDeviceState_DetachingFromVM: // ??
1906 case kHostUSBDeviceState_Capturing:
1907 case kHostUSBDeviceState_ReleasingToHost:
1908 break;
1909
1910 case kHostUSBDeviceState_AttachingToVM: // ??
1911 case kHostUSBDeviceState_UsedByVM:
1912 default:
1913 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1914 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1915 }
1916 break;
1917
1918
1919 /*
1920 * The transitional states.
1921 */
1922 case kHostUSBDeviceState_Capturing:
1923 NewPrevState = mPrevUniState;
1924 switch (aNewState)
1925 {
1926 /* Sub state advance. */
1927 case kHostUSBDeviceState_Capturing:
1928 switch (aNewSubState)
1929 {
1930 case kHostUSBDeviceSubState_AwaitingReAttach:
1931 Assert(mUniSubState == kHostUSBDeviceSubState_AwaitingDetach);
1932 Assert(aNewPendingState == mPendingUniState);
1933 break;
1934 default:
1935 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
1936 }
1937 break;
1938
1939 /* Host/User/Failure. */
1940 case kHostUSBDeviceState_PhysDetached:
1941 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1942 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1943 break;
1944 case kHostUSBDeviceState_UsedByHost:
1945 case kHostUSBDeviceState_Capturable:
1946 case kHostUSBDeviceState_Unused:
1947 Assert(aNewState == mPrevUniState);
1948 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1949 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1950 break;
1951
1952 /* VBox */
1953 case kHostUSBDeviceState_HeldByProxy:
1954 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1955 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1956 Assert( mPendingUniState == kHostUSBDeviceState_HeldByProxy
1957 || mPendingUniState == kHostUSBDeviceState_UsedByVM /* <- failure */ );
1958 break;
1959 case kHostUSBDeviceState_AttachingToVM:
1960 Assert(aNewPendingState == kHostUSBDeviceState_UsedByVM);
1961 NewPrevState = kHostUSBDeviceState_HeldByProxy;
1962 break;
1963
1964 default:
1965 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
1966 stateName(aNewState, aNewPendingState, aNewSubState)), false);
1967 }
1968 break;
1969
1970 case kHostUSBDeviceState_ReleasingToHost:
1971 Assert(mPrevUniState == kHostUSBDeviceState_HeldByProxy);
1972 NewPrevState = mPrevUniState;
1973 switch (aNewState)
1974 {
1975 /* Sub state advance. */
1976 case kHostUSBDeviceState_ReleasingToHost:
1977 switch (aNewSubState)
1978 {
1979 case kHostUSBDeviceSubState_AwaitingReAttach:
1980 Assert(mUniSubState == kHostUSBDeviceSubState_AwaitingDetach);
1981 Assert(aNewPendingState == mPendingUniState);
1982 break;
1983 default:
1984 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
1985 }
1986 break;
1987
1988 /* Host/Failure. */
1989 case kHostUSBDeviceState_PhysDetached:
1990 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1991 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1992 break;
1993 case kHostUSBDeviceState_HeldByProxy:
1994 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
1995 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
1996 Assert(mPendingUniState == kHostUSBDeviceState_Unused);
1997 break;
1998
1999 /* Success */
2000 case kHostUSBDeviceState_UsedByHost:
2001 case kHostUSBDeviceState_Capturable:
2002 case kHostUSBDeviceState_Unused:
2003 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2004 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2005 Assert(mPendingUniState == kHostUSBDeviceState_Unused);
2006 break;
2007
2008 default:
2009 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
2010 stateName(aNewState, aNewPendingState, aNewSubState)), false);
2011 }
2012 break;
2013
2014 case kHostUSBDeviceState_AttachingToVM:
2015 Assert(mPrevUniState == kHostUSBDeviceState_HeldByProxy);
2016 NewPrevState = mPrevUniState;
2017 switch (aNewState)
2018 {
2019 /* Host/Failure. */
2020 case kHostUSBDeviceState_PhysDetachingFromVM:
2021 Assert(aNewPendingState == kHostUSBDeviceState_PhysDetached);
2022 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2023 break;
2024 case kHostUSBDeviceState_HeldByProxy:
2025 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2026 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2027 Assert(mPendingUniState == kHostUSBDeviceState_Unused);
2028 break;
2029
2030 /* Success */
2031 case kHostUSBDeviceState_UsedByVM:
2032 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2033 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2034 Assert(mPendingUniState == kHostUSBDeviceState_UsedByVM);
2035 break;
2036
2037 default:
2038 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
2039 stateName(aNewState, aNewPendingState, aNewSubState)), false);
2040 }
2041 break;
2042
2043 case kHostUSBDeviceState_DetachingFromVM:
2044 Assert(mPrevUniState == kHostUSBDeviceState_UsedByVM);
2045 NewPrevState = mPrevUniState;
2046 switch (aNewState)
2047 {
2048 /* Host/Failure. */
2049 case kHostUSBDeviceState_PhysDetached: //??
2050 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2051 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2052 break;
2053 case kHostUSBDeviceState_PhysDetachingFromVM:
2054 Assert(aNewPendingState == kHostUSBDeviceState_PhysDetached);
2055 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2056 break;
2057
2058 /* Success */
2059 case kHostUSBDeviceState_HeldByProxy:
2060 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2061 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2062 Assert(mPendingUniState == kHostUSBDeviceState_HeldByProxy);
2063 fFilters = true;
2064 break;
2065
2066 case kHostUSBDeviceState_ReleasingToHost:
2067 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2068 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2069 Assert(mPendingUniState == kHostUSBDeviceState_Unused);
2070 NewPrevState = kHostUSBDeviceState_HeldByProxy;
2071 break;
2072
2073 default:
2074 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
2075 stateName(aNewState, aNewPendingState, aNewSubState)), false);
2076 }
2077 break;
2078
2079 case kHostUSBDeviceState_PhysDetachingFromVM:
2080 Assert( mPrevUniState == kHostUSBDeviceState_DetachingFromVM
2081 || mPrevUniState == kHostUSBDeviceState_AttachingToVM
2082 || mPrevUniState == kHostUSBDeviceState_UsedByVM);
2083 NewPrevState = mPrevUniState; /* preserving it is more useful. */
2084 switch (aNewState)
2085 {
2086 case kHostUSBDeviceState_PhysDetached:
2087 Assert(aNewPendingState == kHostUSBDeviceState_Invalid);
2088 Assert(aNewSubState == kHostUSBDeviceSubState_Default);
2089 break;
2090 default:
2091 AssertLogRelMsgFailedReturn (("this=%p %s -X-> %s\n", this, getStateName(),
2092 stateName(aNewState, aNewPendingState, aNewSubState)), false);
2093 }
2094 break;
2095
2096 default:
2097 AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
2098 }
2099
2100 /*
2101 * Make the state change.
2102 */
2103 if (NewPrevState != mPrevUniState)
2104 LogFlowThisFunc(("%s -> %s (prev: %s -> %s) [%s]\n",
2105 getStateName(), stateName(aNewState, aNewPendingState, aNewSubState),
2106 stateName(mPrevUniState), stateName(NewPrevState), mName));
2107 else
2108 LogFlowThisFunc(("%s -> %s (prev: %s) [%s]\n",
2109 getStateName(), stateName(aNewState, aNewPendingState, aNewSubState), stateName(NewPrevState), mName));
2110 mPrevUniState = NewPrevState;
2111 mUniState = aNewState;
2112 mUniSubState = aNewSubState;
2113 mPendingUniState = aNewPendingState;
2114 mLastStateChangeTS = RTTimeNanoTS();
2115
2116 return fFilters;
2117}
2118
2119
2120
2121/**
2122 * A convenience for entering a transitional state.
2123
2124 * @param aNewState The new state (transitional).
2125 * @param aFinalSubState The final state of the transition (non-transitional).
2126 * @param aNewSubState The new sub-state when applicable.
2127 *
2128 * @returns Always false because filters are never applied for the start of a transition.
2129 *
2130 * @note The caller must own the write lock for this object.
2131 */
2132bool HostUSBDevice::startTransition (HostUSBDeviceState aNewState, HostUSBDeviceState aFinalState,
2133 HostUSBDeviceSubState aNewSubState /*= kHostUSBDeviceSubState_Default*/)
2134{
2135 /*
2136 * A quick prevalidation thing. Not really necessary since setState
2137 * verifies this too, but it's very easy here.
2138 */
2139 switch (mUniState)
2140 {
2141 case kHostUSBDeviceState_Unsupported:
2142 case kHostUSBDeviceState_UsedByHost:
2143 case kHostUSBDeviceState_Capturable:
2144 case kHostUSBDeviceState_Unused:
2145 case kHostUSBDeviceState_HeldByProxy:
2146 case kHostUSBDeviceState_UsedByVM:
2147 break;
2148
2149 case kHostUSBDeviceState_DetachingFromVM:
2150 case kHostUSBDeviceState_Capturing:
2151 case kHostUSBDeviceState_ReleasingToHost:
2152 case kHostUSBDeviceState_AttachingToVM:
2153 case kHostUSBDeviceState_PhysDetachingFromVM:
2154 AssertMsgFailedReturn (("this=%p %s is a transitional state.\n", this, getStateName()), false);
2155
2156 case kHostUSBDeviceState_PhysDetached:
2157 default:
2158 AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
2159 }
2160
2161 return setState (aNewState, aFinalState, aNewSubState);
2162}
2163
2164
2165/**
2166 * A convenience for advancing a transitional state forward.
2167 *
2168 * @param aSkipReAttach Fast forwards thru the re-attach substate if
2169 * applicable.
2170 *
2171 * @returns true if filters should be applied to the device, false if not.
2172 *
2173 * @note The caller must own the write lock for this object.
2174 */
2175bool HostUSBDevice::advanceTransition(bool aSkipReAttach /* = false */)
2176{
2177 HostUSBDeviceState enmPending = mPendingUniState;
2178 HostUSBDeviceSubState enmSub = mUniSubState;
2179 HostUSBDeviceState enmState = mUniState;
2180 switch (enmState)
2181 {
2182 case kHostUSBDeviceState_Capturing:
2183 switch (enmSub)
2184 {
2185 case kHostUSBDeviceSubState_AwaitingDetach:
2186 enmSub = kHostUSBDeviceSubState_AwaitingReAttach;
2187 break;
2188 case kHostUSBDeviceSubState_AwaitingReAttach:
2189 enmSub = kHostUSBDeviceSubState_Default;
2190 /* fall thru */
2191 case kHostUSBDeviceSubState_Default:
2192 switch (enmPending)
2193 {
2194 case kHostUSBDeviceState_UsedByVM:
2195 enmState = kHostUSBDeviceState_AttachingToVM;
2196 break;
2197 case kHostUSBDeviceState_HeldByProxy:
2198 enmState = enmPending;
2199 enmPending = kHostUSBDeviceState_Invalid;
2200 break;
2201 default:
2202 AssertMsgFailedReturn(("this=%p invalid pending state %d: %s\n", this, enmPending, getStateName()), false);
2203 }
2204 break;
2205 default:
2206 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
2207 }
2208 break;
2209
2210 case kHostUSBDeviceState_ReleasingToHost:
2211 switch (enmSub)
2212 {
2213 case kHostUSBDeviceSubState_AwaitingDetach:
2214 enmSub = kHostUSBDeviceSubState_AwaitingReAttach;
2215 break;
2216 case kHostUSBDeviceSubState_AwaitingReAttach:
2217 enmSub = kHostUSBDeviceSubState_Default;
2218 /* fall thru */
2219 case kHostUSBDeviceSubState_Default:
2220 switch (enmPending)
2221 {
2222 /* Use Unused here since it implies that filters has been applied
2223 and will make sure they aren't applied if the final state really
2224 is Capturable. */
2225 case kHostUSBDeviceState_Unused:
2226 enmState = enmPending;
2227 enmPending = kHostUSBDeviceState_Invalid;
2228 break;
2229 default:
2230 AssertMsgFailedReturn(("this=%p invalid pending state %d: %s\n", this, enmPending, getStateName()), false);
2231 }
2232 break;
2233 default:
2234 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
2235 }
2236 break;
2237
2238 case kHostUSBDeviceState_AttachingToVM:
2239 switch (enmSub)
2240 {
2241 case kHostUSBDeviceSubState_AwaitingDetach:
2242 enmSub = kHostUSBDeviceSubState_AwaitingReAttach;
2243 break;
2244 case kHostUSBDeviceSubState_AwaitingReAttach:
2245 enmSub = kHostUSBDeviceSubState_Default;
2246 /* fall thru */
2247 case kHostUSBDeviceSubState_Default:
2248 switch (enmPending)
2249 {
2250 case kHostUSBDeviceState_UsedByVM:
2251 enmState = enmPending;
2252 enmPending = kHostUSBDeviceState_Invalid;
2253 break;
2254 default:
2255 AssertMsgFailedReturn(("this=%p invalid pending state %d: %s\n", this, enmPending, getStateName()), false);
2256 }
2257 break;
2258 default:
2259 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
2260 }
2261 break;
2262
2263 case kHostUSBDeviceState_DetachingFromVM:
2264 switch (enmSub)
2265 {
2266 case kHostUSBDeviceSubState_AwaitingDetach:
2267 enmSub = kHostUSBDeviceSubState_AwaitingReAttach;
2268 break;
2269 case kHostUSBDeviceSubState_AwaitingReAttach:
2270 enmSub = kHostUSBDeviceSubState_Default;
2271 /* fall thru */
2272 case kHostUSBDeviceSubState_Default:
2273 switch (enmPending)
2274 {
2275 case kHostUSBDeviceState_HeldByProxy:
2276 enmState = enmPending;
2277 enmPending = kHostUSBDeviceState_Invalid;
2278 break;
2279 case kHostUSBDeviceState_Unused:
2280 enmState = kHostUSBDeviceState_ReleasingToHost;
2281 break;
2282 default:
2283 AssertMsgFailedReturn(("this=%p invalid pending state %d: %s\n", this, enmPending, getStateName()), false);
2284 }
2285 break;
2286 default:
2287 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
2288 }
2289 break;
2290
2291 case kHostUSBDeviceState_PhysDetachingFromVM:
2292 switch (enmSub)
2293 {
2294 case kHostUSBDeviceSubState_Default:
2295 switch (enmPending)
2296 {
2297 case kHostUSBDeviceState_PhysDetached:
2298 enmState = enmPending;
2299 enmPending = kHostUSBDeviceState_Invalid;
2300 break;
2301 default:
2302 AssertMsgFailedReturn(("this=%p invalid pending state %d: %s\n", this, enmPending, getStateName()), false);
2303 }
2304 break;
2305 default:
2306 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, mUniState), false);
2307 }
2308 break;
2309
2310 case kHostUSBDeviceState_Unsupported:
2311 case kHostUSBDeviceState_UsedByHost:
2312 case kHostUSBDeviceState_Capturable:
2313 case kHostUSBDeviceState_Unused:
2314 case kHostUSBDeviceState_HeldByProxy:
2315 case kHostUSBDeviceState_UsedByVM:
2316 AssertMsgFailedReturn(("this=%p %s is not transitional\n", this, getStateName()), false);
2317 case kHostUSBDeviceState_PhysDetached:
2318 default:
2319 AssertReleaseMsgFailedReturn(("this=%p mUniState=%d\n", this, enmState), false);
2320
2321 }
2322
2323 bool fRc = setState(enmState, enmPending, enmSub);
2324 if (aSkipReAttach && mUniSubState == kHostUSBDeviceSubState_AwaitingReAttach)
2325 fRc |= advanceTransition(false /* don't fast forward re-attach */);
2326 return fRc;
2327}
2328
2329/**
2330 * A convenience for failing a transitional state.
2331 *
2332 * @return true if filters should be applied to the device, false if not.
2333 *
2334 * @note The caller must own the write lock for this object.
2335 */
2336bool HostUSBDevice::failTransition()
2337{
2338 HostUSBDeviceSubState enmSub = mUniSubState;
2339 HostUSBDeviceState enmState = mUniState;
2340 switch (enmState)
2341 {
2342 /*
2343 * There are just two cases, either we got back to the
2344 * previous state (assumes Capture+Attach-To-VM updates it)
2345 * or we assume the device has been unplugged (physically).
2346 */
2347 case kHostUSBDeviceState_DetachingFromVM:
2348 case kHostUSBDeviceState_Capturing:
2349 case kHostUSBDeviceState_ReleasingToHost:
2350 case kHostUSBDeviceState_AttachingToVM:
2351 switch (enmSub)
2352 {
2353 case kHostUSBDeviceSubState_AwaitingDetach:
2354 enmSub = kHostUSBDeviceSubState_Default;
2355 /* fall thru */
2356 case kHostUSBDeviceSubState_Default:
2357 enmState = mPrevUniState;
2358 break;
2359 case kHostUSBDeviceSubState_AwaitingReAttach:
2360 enmSub = kHostUSBDeviceSubState_Default;
2361 enmState = kHostUSBDeviceState_PhysDetached;
2362 break;
2363 default:
2364 AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
2365 }
2366 break;
2367
2368 case kHostUSBDeviceState_PhysDetachingFromVM:
2369 AssertMsgFailedReturn (("this=%p %s shall not fail\n", this, getStateName()), false);
2370
2371 case kHostUSBDeviceState_Unsupported:
2372 case kHostUSBDeviceState_UsedByHost:
2373 case kHostUSBDeviceState_Capturable:
2374 case kHostUSBDeviceState_Unused:
2375 case kHostUSBDeviceState_HeldByProxy:
2376 case kHostUSBDeviceState_UsedByVM:
2377 AssertMsgFailedReturn (("this=%p %s is not transitional\n", this, getStateName()), false);
2378 case kHostUSBDeviceState_PhysDetached:
2379 default:
2380 AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), false);
2381
2382 }
2383
2384 return setState(enmState, kHostUSBDeviceState_Invalid, enmSub);
2385}
2386
2387
2388/**
2389 * Determines the canonical state of the device.
2390 *
2391 * @returns canonical state.
2392 *
2393 * @note The caller must own the read (or write) lock for this object.
2394 */
2395USBDeviceState_T HostUSBDevice::canonicalState() const
2396{
2397 switch (mUniState)
2398 {
2399 /*
2400 * Straight forward.
2401 */
2402 case kHostUSBDeviceState_Unsupported:
2403 return USBDeviceState_NotSupported;
2404
2405 case kHostUSBDeviceState_UsedByHost:
2406 return USBDeviceState_Unavailable;
2407
2408 case kHostUSBDeviceState_Capturable:
2409 return USBDeviceState_Busy;
2410
2411 case kHostUSBDeviceState_Unused:
2412 return USBDeviceState_Available;
2413
2414 case kHostUSBDeviceState_HeldByProxy:
2415 return USBDeviceState_Held;
2416
2417 case kHostUSBDeviceState_UsedByVM:
2418 return USBDeviceState_Captured;
2419
2420 /*
2421 * Pretend we've reached the final state.
2422 */
2423 case kHostUSBDeviceState_Capturing:
2424 Assert( mPendingUniState == kHostUSBDeviceState_UsedByVM
2425 || mPendingUniState == kHostUSBDeviceState_HeldByProxy);
2426 return mPendingUniState == kHostUSBDeviceState_UsedByVM
2427 ? (USBDeviceState_T)USBDeviceState_Captured
2428 : (USBDeviceState_T)USBDeviceState_Held;
2429 /* The cast ^^^^ is because xidl is using different enums for
2430 each of the values. *Very* nice idea... :-) */
2431
2432 case kHostUSBDeviceState_AttachingToVM:
2433 return USBDeviceState_Captured;
2434
2435 /*
2436 * Return the previous state.
2437 */
2438 case kHostUSBDeviceState_ReleasingToHost:
2439 Assert( mPrevUniState == kHostUSBDeviceState_UsedByVM
2440 || mPrevUniState == kHostUSBDeviceState_HeldByProxy);
2441 return mPrevUniState == kHostUSBDeviceState_UsedByVM
2442 ? (USBDeviceState_T)USBDeviceState_Captured
2443 : (USBDeviceState_T)USBDeviceState_Held;
2444 /* The cast ^^^^ is because xidl is using different enums for
2445 each of the values. *Very* nice idea... :-) */
2446
2447 case kHostUSBDeviceState_DetachingFromVM:
2448 return USBDeviceState_Captured;
2449 case kHostUSBDeviceState_PhysDetachingFromVM:
2450 return USBDeviceState_Captured;
2451
2452 case kHostUSBDeviceState_PhysDetached:
2453 default:
2454 AssertReleaseMsgFailedReturn (("this=%p mUniState=%d\n", this, mUniState), USBDeviceState_NotSupported);
2455 }
2456 /* won't ever get here. */
2457}
2458/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette