VirtualBox

source: vbox/trunk/src/VBox/Main/solaris/USBProxyServiceSolaris.cpp@ 31907

Last change on this file since 31907 was 31892, checked in by vboxsync, 15 years ago

OSE header fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.3 KB
Line 
1/* $Id: USBProxyServiceSolaris.cpp 31892 2010-08-24 08:00:51Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service, Solaris Specialization.
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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include "USBProxyService.h"
23#include "Logging.h"
24
25#include <VBox/usb.h>
26#include <VBox/usblib.h>
27#include <VBox/err.h>
28#include <iprt/semaphore.h>
29#include <iprt/path.h>
30
31#include <sys/usb/usba.h>
32#include <syslog.h>
33
34/*******************************************************************************
35* Internal Functions *
36*******************************************************************************/
37static int solarisWalkDeviceNode(di_node_t Node, void *pvArg);
38static void solarisFreeUSBDevice(PUSBDEVICE pDevice);
39static USBDEVICESTATE solarisDetermineUSBDeviceState(PUSBDEVICE pDevice, di_node_t Node);
40
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45typedef struct USBDEVICELIST
46{
47 PUSBDEVICE pHead;
48 PUSBDEVICE pTail;
49} USBDEVICELIST;
50typedef USBDEVICELIST *PUSBDEVICELIST;
51
52
53/**
54 * Initialize data members.
55 */
56USBProxyServiceSolaris::USBProxyServiceSolaris (Host *aHost)
57 : USBProxyService (aHost), mUSBLibInitialized(false)
58{
59 LogFlowThisFunc(("aHost=%p\n", aHost));
60}
61
62
63/**
64 * Initializes the object (called right after construction).
65 *
66 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
67 */
68HRESULT USBProxyServiceSolaris::init(void)
69{
70 /*
71 * Call the superclass method first.
72 */
73 HRESULT hrc = USBProxyService::init();
74 AssertComRCReturn(hrc, hrc);
75
76 /*
77 * Create semaphore.
78 */
79 int rc = RTSemEventCreate(&mNotifyEventSem);
80 if (RT_FAILURE(rc))
81 {
82 mLastError = rc;
83 return E_FAIL;
84 }
85
86 /*
87 * Initialize the USB library.
88 */
89 rc = USBLibInit();
90 if (RT_FAILURE(rc))
91 {
92 mLastError = rc;
93 return S_OK;
94 }
95 mUSBLibInitialized = true;
96
97 /*
98 * Start the poller thread.
99 */
100 start();
101 return S_OK;
102}
103
104
105/**
106 * Stop all service threads and free the device chain.
107 */
108USBProxyServiceSolaris::~USBProxyServiceSolaris()
109{
110 LogFlowThisFunc(("destruct\n"));
111
112 /*
113 * Stop the service.
114 */
115 if (isActive())
116 stop();
117
118 /*
119 * Terminate the USB library
120 */
121 if (mUSBLibInitialized)
122 {
123 USBLibTerm();
124 mUSBLibInitialized = false;
125 }
126
127 RTSemEventDestroy(mNotifyEventSem);
128 mNotifyEventSem = NULL;
129}
130
131
132void *USBProxyServiceSolaris::insertFilter(PCUSBFILTER aFilter)
133{
134 return USBLibAddFilter(aFilter);
135}
136
137
138void USBProxyServiceSolaris::removeFilter(void *pvID)
139{
140 USBLibRemoveFilter(pvID);
141}
142
143
144int USBProxyServiceSolaris::wait(RTMSINTERVAL aMillies)
145{
146 return RTSemEventWait(mNotifyEventSem, aMillies < 1000 ? 1000 : RT_MIN(aMillies, 5000));
147}
148
149
150int USBProxyServiceSolaris::interruptWait(void)
151{
152 return RTSemEventSignal(mNotifyEventSem);
153}
154
155
156PUSBDEVICE USBProxyServiceSolaris::getDevices(void)
157{
158 USBDEVICELIST DevList;
159 DevList.pHead = NULL;
160 DevList.pTail = NULL;
161 di_node_t RootNode = di_init("/", DINFOCPYALL);
162 if (RootNode != DI_NODE_NIL)
163 di_walk_node(RootNode, DI_WALK_CLDFIRST, &DevList, solarisWalkDeviceNode);
164
165 di_fini(RootNode);
166 return DevList.pHead;
167}
168
169#if 0
170static int solarisWalkMinor(di_node_t Node, di_minor_t Minor, void *pvArg)
171{
172 char *pszDevFsPath = di_devfs_path(Node);
173 char *pszMinorName = di_minor_name(Minor);
174 PUSBDEVICE pDev = (PUSBDEVICE)pvArg;
175
176 AssertRelease(pDev);
177
178 if (!pszDevFsPath || !pszMinorName)
179 return DI_WALK_CONTINUE;
180
181 RTStrAPrintf(&pDev->pszApId, "/devices%s:%s", pszDevFsPath, pszMinorName);
182 di_devfs_path_free(pszDevFsPath);
183
184 syslog(LOG_ERR, "VBoxUsbApId:%s\n", pDev->pszApId);
185 return DI_WALK_TERMINATE;
186}
187
188static bool solarisGetApId(PUSBDEVICE pDev, char *pszDevicePath, di_node_t RootNode)
189{
190 pDev->pszApId = NULL;
191
192 /* Skip "/devices" prefix if any */
193 char achDevicesDir[] = "/devices/";
194 if (strncmp(pszDevicePath, achDevicesDir, sizeof(achDevicesDir)) == 0)
195 pszDevicePath += sizeof(achDevicesDir);
196
197 char *pszPhysical = RTStrDup(pszDevicePath);
198 char *pszTmp = NULL;
199
200 /* Remove dynamic component "::" if any */
201 if ((pszTmp = strstr(pszPhysical, "::")) != NULL)
202 *pszTmp = '\0';
203
204 /* Remove minor name if any */
205 if ((pszTmp = strrchr(pszPhysical, ':')) != NULL)
206 *pszTmp = '\0';
207
208 /* Walk device tree */
209// di_node_t RootNode = di_init("/", DINFOCPYALL);
210// if (RootNode != DI_NODE_NIL)
211// {
212// di_node_t MinorNode = di_lookup_node(RootNode, pszPhysical);
213// if (MinorNode != DI_NODE_NIL)
214 {
215 di_walk_minor(RootNode, NULL, DI_CHECK_ALIAS | DI_CHECK_INTERNAL_PATH, pDev, solarisWalkMinor);
216 return true;
217 }
218// di_fini(RootNode);
219// }
220
221 return false;
222}
223#endif
224
225static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
226{
227 PUSBDEVICELIST pList = (PUSBDEVICELIST)pvArg;
228 AssertPtrReturn(pList, DI_WALK_TERMINATE);
229
230 /*
231 * Check if it's a USB device in the first place.
232 */
233 bool fUSBDevice = false;
234 char *pszCompatNames = NULL;
235 int cCompatNames = di_compatible_names(Node, &pszCompatNames);
236 for (int i = 0; i < cCompatNames; i++, pszCompatNames += strlen(pszCompatNames) + 1)
237 if (!strncmp(pszCompatNames, "usb", 3))
238 {
239 fUSBDevice = true;
240 break;
241 }
242
243 if (!fUSBDevice)
244 return DI_WALK_CONTINUE;
245
246 /*
247 * Check if it's a device node or interface.
248 */
249 int *pInt = NULL;
250 char *pStr = NULL;
251 int rc = DI_WALK_CONTINUE;
252 if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "interface", &pInt) < 0)
253 {
254 /* It's a device node. */
255 char *pszDevicePath = di_devfs_path(Node);
256 PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur));
257 if (!pCur)
258 {
259 LogRel(("USBService: failed to allocate %d bytes for PUSBDEVICE.\n", sizeof(*pCur)));
260 return DI_WALK_TERMINATE;
261 }
262
263 bool fValidDevice = false;
264 do
265 {
266 AssertBreak(pszDevicePath);
267
268 char *pszDriverName = di_driver_name(Node);
269
270 /*
271 * Skip hubs
272 */
273 if ( pszDriverName
274 && !strcmp(pszDriverName, "hubd"))
275 {
276 break;
277 }
278
279 /*
280 * Mandatory.
281 * snv_85 and above have usb-dev-descriptor node properties, but older one's do not.
282 * So if we cannot obtain the entire device descriptor, we try falling back to the
283 * invidividual properties (those must not fail, if it does we drop the device).
284 */
285 uchar_t *pDevData = NULL;
286 int cbProp = di_prop_lookup_bytes(DDI_DEV_T_ANY, Node, "usb-dev-descriptor", &pDevData);
287 if ( cbProp > 0
288 && pDevData)
289 {
290 usb_dev_descr_t *pDeviceDescriptor = (usb_dev_descr_t *)pDevData;
291 pCur->bDeviceClass = pDeviceDescriptor->bDeviceClass;
292 pCur->bDeviceSubClass = pDeviceDescriptor->bDeviceSubClass;
293 pCur->bDeviceProtocol = pDeviceDescriptor->bDeviceProtocol;
294 pCur->idVendor = pDeviceDescriptor->idVendor;
295 pCur->idProduct = pDeviceDescriptor->idProduct;
296 pCur->bcdDevice = pDeviceDescriptor->bcdDevice;
297 pCur->bcdUSB = pDeviceDescriptor->bcdUSB;
298 pCur->bNumConfigurations = pDeviceDescriptor->bNumConfigurations;
299 pCur->fPartialDescriptor = false;
300 }
301 else
302 {
303 AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-vendor-id", &pInt) > 0);
304 pCur->idVendor = (uint16_t)*pInt;
305
306 AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-product-id", &pInt) > 0);
307 pCur->idProduct = (uint16_t)*pInt;
308
309 AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-revision-id", &pInt) > 0);
310 pCur->bcdDevice = (uint16_t)*pInt;
311
312 AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-release", &pInt) > 0);
313 pCur->bcdUSB = (uint16_t)*pInt;
314
315 pCur->fPartialDescriptor = true;
316 }
317
318 char *pszPortAddr = di_bus_addr(Node);
319 if (pszPortAddr)
320 pCur->bPort = RTStrToUInt8(pszPortAddr); /* Bus & Port are mixed up (kernel driver/userland) */
321 else
322 pCur->bPort = 0;
323
324#if 0
325 /*
326 * Obtain the dev_t of the device.
327 */
328 di_minor_t Minor = di_minor_next(Node, DI_MINOR_NIL);
329 AssertBreak(Minor != DI_MINOR_NIL);
330 dev_t DeviceNum = di_minor_devt(Minor);
331
332 int DevInstance = 0;
333 rc = solarisUSBGetInstance(pszDevicePath, &DevInstance);
334
335 char szAddress[PATH_MAX + 128];
336 RTStrPrintf(szAddress, sizeof(szAddress), "/dev/usb/%x.%x|%s", pCur->idVendor, pCur->idProduct, pszDevicePath);
337 /* @todo after binding ugen we need to append the instance number to the address. Not yet sure how we can update PUSBDEVICE at that time. */
338
339 pCur->pszAddress = RTStrDup(szAddress);
340 AssertBreak(pCur->pszAddress);
341#endif
342
343#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
344 char pathBuf[PATH_MAX];
345 RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath);
346 RTPathStripFilename(pathBuf);
347
348 char szBuf[PATH_MAX + 48];
349 RTStrPrintf(szBuf, sizeof(szBuf), "%#x:%#x:%d:%s", pCur->idVendor, pCur->idProduct, pCur->bcdDevice, pathBuf);
350#else
351 char szBuf[2 * PATH_MAX];
352 RTStrPrintf(szBuf, sizeof(szBuf), "/dev/usb/%x.%x/%d|%s", pCur->idVendor, pCur->idProduct, 0, pszDevicePath);
353#endif
354 pCur->pszAddress = RTStrDup(szBuf);
355
356 pCur->pszDevicePath = RTStrDup(pszDevicePath);
357 AssertBreak(pCur->pszDevicePath);
358
359 /*
360 * Optional (some devices don't have all these)
361 */
362 if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-product-name", &pStr) > 0)
363 pCur->pszProduct = RTStrDup(pStr);
364
365 if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-vendor-name", &pStr) > 0)
366 pCur->pszManufacturer = RTStrDup(pStr);
367
368 if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-serialno", &pStr) > 0)
369 pCur->pszSerialNumber = RTStrDup(pStr);
370
371 if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "low-speed", &pInt) >= 0)
372 pCur->enmSpeed = USBDEVICESPEED_LOW;
373 else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "high-speed", &pInt) >= 0)
374 pCur->enmSpeed = USBDEVICESPEED_HIGH;
375 else
376 pCur->enmSpeed = USBDEVICESPEED_FULL;
377
378 /* Determine state of the USB device. */
379 pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node);
380
381// fValidDevice = solarisGetApId(pCur, pszDevicePath, Node);
382 fValidDevice = true;
383
384 /*
385 * Valid device, add it to the list.
386 */
387 if (fValidDevice)
388 {
389 pCur->pPrev = pList->pTail;
390 if (pList->pTail)
391 pList->pTail = pList->pTail->pNext = pCur;
392 else
393 pList->pTail = pList->pHead = pCur;
394 }
395 rc = DI_WALK_CONTINUE;
396 } while(0);
397
398 di_devfs_path_free(pszDevicePath);
399 if (!fValidDevice)
400 solarisFreeUSBDevice(pCur);
401 }
402 return rc;
403}
404
405
406static USBDEVICESTATE solarisDetermineUSBDeviceState(PUSBDEVICE pDevice, di_node_t Node)
407{
408 char *pszDriverName = di_driver_name(Node);
409
410 /* Not possible unless a user explicitly unbinds the default driver. */
411 if (!pszDriverName)
412 return USBDEVICESTATE_UNUSED;
413
414#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
415 if (!strncmp(pszDriverName, VBOXUSB_DRIVER_NAME, sizeof(VBOXUSB_DRIVER_NAME) - 1))
416 return USBDEVICESTATE_HELD_BY_PROXY;
417
418 NOREF(pDevice);
419 return USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
420#else
421
422 USBDEVICESTATE enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
423
424 /* Filter out keyboards, mouse */
425 if (!pDevice->fPartialDescriptor)
426 {
427 /*
428 * Here we have a fully valid device descriptor, so we fine
429 * tune what's usable and what's not.
430 */
431 if ( pDevice->bDeviceClass == 3 /* HID */
432 && ( pDevice->bDeviceProtocol == 1 /* Mouse */
433 || pDevice->bDeviceProtocol == 2)) /* Keyboard */
434 {
435 return USBDEVICESTATE_USED_BY_HOST;
436 }
437 }
438 else
439 {
440 /*
441 * Old Nevadas don't give full device descriptor in ring-3.
442 * So those Nevadas we just filter out all HIDs as unusable.
443 */
444 if (!strcmp(pszDriverName, "hid"))
445 return USBDEVICESTATE_USED_BY_HOST;
446 }
447
448 return enmState;
449#endif
450}
451
452
453int USBProxyServiceSolaris::captureDevice(HostUSBDevice *aDevice)
454{
455 /*
456 * Check preconditions.
457 */
458 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
459 LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
460 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
461 Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
462 AssertReturn(aDevice->mUsb, VERR_INVALID_POINTER);
463
464#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
465 /*
466 * Create a one-shot capture filter for the device and reset the device.
467 */
468 USBFILTER Filter;
469 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_CAPTURE);
470 initFilterFromDevice(&Filter, aDevice);
471
472 void *pvId = USBLibAddFilter(&Filter);
473 if (!pvId)
474 {
475 LogRel(("USBService: failed to add filter\n"));
476 return VERR_GENERAL_FAILURE;
477 }
478
479 PUSBDEVICE pDev = aDevice->mUsb;
480 int rc = USBLibResetDevice(pDev->pszDevicePath, true);
481 if (RT_SUCCESS(rc))
482 aDevice->mOneShotId = pvId;
483 else
484 {
485 USBLibRemoveFilter(pvId);
486 pvId = NULL;
487 }
488 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
489 return rc;
490
491#else
492
493 /*
494 * Add the driver alias for binding the USB device to our driver.
495 */
496 PUSBDEVICE pDev = aDevice->mUsb;
497 int rc = USBLibAddDeviceAlias(pDev);
498 if (RT_SUCCESS(rc))
499 {
500 /*
501 * Reconnect and configure the device into an 'online' state because hard reset via
502 * usb_reset_device(9F) leaves the devices in an indeterminent state sometimes.
503 * In case of errors here, ignore them and prod further...
504 */
505 rc = USBLibResetDevice(pDev->pszDevicePath, true);
506 if (rc)
507 LogRel(("USBService: USBLibResetDevice failed. device=%s rc=%d\n", pDev->pszDevicePath, rc));
508
509 /*
510 * Get device driver instance number.
511 */
512 int iInstance;
513 rc = USBLibDeviceInstance(pDev->pszDevicePath, &iInstance);
514 if (RT_SUCCESS(rc))
515 {
516 /*
517 * Check device node to verify driver binding.
518 */
519 char szDevNode[PATH_MAX];
520 RTStrPrintf(szDevNode, sizeof(szDevNode), "/dev/usb/%x.%x/%d", pDev->idVendor, pDev->idProduct, 0);
521
522 /*
523 * Wait for the driver to export the device nodes with a timeout of ~5 seconds.
524 */
525 unsigned cTimeout = 0;
526 bool fExportedNodes = false;
527 while (cTimeout < 5000)
528 {
529 if (RTPathExists(szDevNode))
530 {
531 fExportedNodes = true;
532 break;
533 }
534 RTThreadSleep(500);
535 cTimeout += 500;
536 }
537 if (fExportedNodes)
538 {
539#if 0
540 /*
541 * This does not work. ProxyDevice somehow still gets the old values.
542 * Update our device with the node path as well as the device tree path.
543 */
544 RTStrFree((char *)pDev->pszAddress);
545 RTStrAPrintf(const_cast<char **>(&pDev->pszAddress), "%s|/devices%s", szDevNode, pDev->pszDevicePath);
546#endif
547
548 /*
549 * We don't need the system alias for this device anymore now that we've captured it.
550 * This will also ensure that in case VirtualBox crashes at a later point with
551 * a captured device it will not affect the user's USB devices.
552 */
553 USBLibRemoveDeviceAlias(pDev);
554 syslog(LOG_ERR, "USBPService: Success captured %s\n", aDevice->getName().c_str());
555 return VINF_SUCCESS;
556 }
557 else
558 {
559 rc = VERR_PATH_NOT_FOUND;
560 LogRel(("USBService: failed to stat %s for device.\n", szDevNode));
561 syslog(LOG_ERR, "USBService: failed to stat %s for device.\n", szDevNode);
562 }
563 }
564 else
565 LogRel(("USBService: failed to obtain device instance number for %s rc=%Rrc\n", aDevice->getName().c_str(), rc));
566 }
567 else
568 LogRel(("USBService: failed to add alias for device %s devicepath=%s rc=%Rrc\n", aDevice->getName().c_str(), pDev->pszDevicePath, rc));
569
570 USBLibRemoveDeviceAlias(pDev);
571 syslog(LOG_ERR, "USBPService: failed to capture device %s.\n", aDevice->getName().c_str());
572 return VERR_OPEN_FAILED;
573
574#endif
575
576}
577
578
579void USBProxyServiceSolaris::captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
580{
581#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
582 /*
583 * Remove the one-shot filter if necessary.
584 */
585 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->getName().c_str(), aSuccess, aDevice->mOneShotId));
586 if (!aSuccess && aDevice->mOneShotId)
587 USBLibRemoveFilter(aDevice->mOneShotId);
588 aDevice->mOneShotId = NULL;
589#endif
590}
591
592
593int USBProxyServiceSolaris::releaseDevice(HostUSBDevice *aDevice)
594{
595 /*
596 * Check preconditions.
597 */
598 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
599 LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
600 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
601 Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
602 AssertReturn(aDevice->mUsb, VERR_INVALID_POINTER);
603
604#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
605
606 /*
607 * Create a one-shot ignore filter for the device and reset it.
608 */
609 USBFILTER Filter;
610 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_IGNORE);
611 initFilterFromDevice(&Filter, aDevice);
612
613 void *pvId = USBLibAddFilter(&Filter);
614 if (!pvId)
615 {
616 LogRel(("USBService: Adding ignore filter failed!\n"));
617 return VERR_GENERAL_FAILURE;
618 }
619
620 PUSBDEVICE pDev = aDevice->mUsb;
621 int rc = USBLibResetDevice(pDev->pszDevicePath, true /* Re-attach */);
622 if (RT_SUCCESS(rc))
623 aDevice->mOneShotId = pvId;
624 else
625 {
626 USBLibRemoveFilter(pvId);
627 pvId = NULL;
628 }
629 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
630 return rc;
631
632#else
633
634 /*
635 * Though may not be strictly remove the driver alias for releasing the USB device
636 * from our driver, ignore errors here as we usually remove the alias immediately after capturing.
637 */
638 PUSBDEVICE pDev = aDevice->mUsb;
639 int rc = USBLibRemoveDeviceAlias(pDev);
640 Assert(pDev->pszDevicePath);
641 rc = USBLibResetDevice(pDev->pszDevicePath, true /* Re-attach */);
642 if (RT_SUCCESS(rc))
643 return VINF_SUCCESS;
644
645 /* The Solaris specifics are free'd in USBProxyService::freeDeviceMembers */
646
647 LogRel(("USBService: failed to reset device %s devicepath=%s rc=%Rrc\n", aDevice->getName().c_str(), pDev->pszDevicePath, rc));
648 return rc;
649
650#endif
651
652}
653
654
655void USBProxyServiceSolaris::releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
656{
657#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
658 /*
659 * Remove the one-shot filter if necessary.
660 */
661 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->getName().c_str(), aSuccess, aDevice->mOneShotId));
662 if (!aSuccess && aDevice->mOneShotId)
663 USBLibRemoveFilter(aDevice->mOneShotId);
664 aDevice->mOneShotId = NULL;
665#endif
666}
667
668
669bool USBProxyServiceSolaris::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
670{
671#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
672 return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
673#else
674 return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
675#endif
676}
677
678/**
679 * Wrapper called by walkDeviceNode.
680 *
681 * @param pDevice The USB device to free.
682 */
683void solarisFreeUSBDevice(PUSBDEVICE pDevice)
684{
685 USBProxyService::freeDevice(pDevice);
686}
687
Note: See TracBrowser for help on using the repository browser.

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