HostHardwareFreeBSD.cpp revision 5979821e2c16d1fcec5b9a3ef64e13246fc9a93a
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * Classes for handling hardware detection under FreeBSD.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * Copyright (C) 2008-2013 Oracle Corporation
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * available from http://www.virtualbox.org. This file is free software;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * General Public License (GPL) as published by the Free Software
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync/*******************************************************************************
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync* Header Files *
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync*******************************************************************************/
3238841f4d74fd0e37778c270ae81b177a98e21bvboxsync#endif /* RT_OS_FREEBSD */
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync/******************************************************************************
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync* Typedefs and Defines *
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync******************************************************************************/
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsyncstatic int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList,
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsyncstatic int getDVDInfoFromCAM(DriveInfoList *pList, bool *pfSuccess);
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync/** Find the length of a string, ignoring trailing non-ascii or control
0d9f0399d4356c471af5e68c30b51c73f7909487vboxsync * characters */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsyncstatic void strLenRemoveTrailingWhiteSpace(char *psz, size_t cchStr)
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync while ( (cchStr > 0)
890b5e4f0265eb78919f6a41d1ccaa89eba51768vboxsync * Initialise the device description for a DVD drive based on
d3b1e232c566c55799a7bfc83f66b045c4d82657vboxsync * vendor and model name strings.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * @param pcszVendor the vendor ID string
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * @param pcszModel the product ID string
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * @param pszDesc where to store the description string (optional)
d645696bf70e804f18f661a9b1b8b79c32a1b331vboxsync * @param cchDesc the size of the buffer in @pszDesc
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync/* static */
d645696bf70e804f18f661a9b1b8b79c32a1b331vboxsyncvoid dvdCreateDeviceString(const char *pcszVendor, const char *pcszModel,
f92fba8b6d97160b7c58689eff6c3848702bd7bavboxsync /* Construct the description string as "Vendor Product" */
342d1c2e846281e0bcbde2e97218273216b3fb32vboxsync RTStrPrintf(pszDesc, cchDesc, "%.*s %s", cchVendor, pcszVendor,
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync cchModel > 0 ? pcszModel : "(unknown drive model)");
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync bool fSuccess = false; /* Have we succeeded in finding anything yet? */
df3a016ea59e69ab2758221fd91e62a9782b144evboxsync /* Always allow the user to override our auto-detection using an
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * environment variable. */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync rc = getDriveInfoFromEnv("VBOX_CDROM", &mDVDList, true /* isDVD */,
df3a016ea59e69ab2758221fd91e62a9782b144evboxsync bool fSuccess = false; /* Have we succeeded in finding anything yet? */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync /* Always allow the user to override our auto-detection using an
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * environment variable. */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList, false /* isDVD */,
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * Search for available CD/DVD drives using the CAM layer.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * @returns iprt status code
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * @param pList the list to append the drives found to
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * @param pfSuccess this will be set to true if we found at least one drive
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * and to false otherwise. Optional.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsyncstatic int getDVDInfoFromCAM(DriveInfoList *pList, bool *pfSuccess)
060664c5bfb70021bf92e01127d02b178b8c20acvboxsync rc = RTFileOpen(&FileXpt, "/dev/xpt0", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync /* We want to get all devices. */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync /* Setup the pattern */
060664c5bfb70021bf92e01127d02b178b8c20acvboxsync DeviceMatchPattern.pattern.device_pattern.path_id = CAM_XPT_PATH_ID;
060664c5bfb70021bf92e01127d02b178b8c20acvboxsync DeviceMatchPattern.pattern.device_pattern.target_id = CAM_TARGET_WILDCARD;
060664c5bfb70021bf92e01127d02b178b8c20acvboxsync DeviceMatchPattern.pattern.device_pattern.target_lun = CAM_LUN_WILDCARD;
060664c5bfb70021bf92e01127d02b178b8c20acvboxsync DeviceMatchPattern.pattern.device_pattern.flags = DEV_MATCH_INQUIRY;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync DeviceMatchPattern.pattern.device_pattern.INQ_PAT.type = T_CDROM;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync DeviceMatchPattern.pattern.device_pattern.INQ_PAT.media_type = SIP_MEDIA_REMOVABLE | SIP_MEDIA_FIXED;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync DeviceMatchPattern.pattern.device_pattern.INQ_PAT.vendor[0] = '*'; /* Matches anything */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync DeviceMatchPattern.pattern.device_pattern.INQ_PAT.product[0] = '*'; /* Matches anything */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync DeviceMatchPattern.pattern.device_pattern.INQ_PAT.revision[0] = '*'; /* Matches anything */
83204c5c9e83c7825a8e0537821a199459b783c8vboxsync DeviceCCB.cdm.pattern_buf_len = sizeof(struct dev_match_result);
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * Allocate the buffer holding the matches.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * We will allocate for 10 results and call
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * CAM multiple times if we have more results.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync paMatches = (struct dev_match_result *)RTMemAllocZ(10 * sizeof(struct dev_match_result));
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync DeviceCCB.cdm.match_buf_len = 10 * sizeof(struct dev_match_result);
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync rc = RTFileIoCtl(FileXpt, CAMIOCOMMAND, &DeviceCCB, sizeof(union ccb), NULL);
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync Log(("Error while querying available CD/DVD devices rc=%Rrc\n", rc));
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync for (unsigned i = 0; i < DeviceCCB.cdm.num_matches; i++)
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync /* We have the drive now but need the appropriate device node */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync struct device_match_result *pDevResult = &paMatches[i].result.device_result;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync unsigned iPeriphMatch = 0;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync /* This time we only want the specific nodes for the device. */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphCCB.ccb_h.path_id = paMatches[i].result.device_result.path_id;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphCCB.ccb_h.target_id = paMatches[i].result.device_result.target_id;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphCCB.ccb_h.target_lun = paMatches[i].result.device_result.target_lun;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync /* Setup the pattern */
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphMatchPattern.pattern.periph_pattern.path_id = paMatches[i].result.device_result.path_id;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphMatchPattern.pattern.periph_pattern.target_id = paMatches[i].result.device_result.target_id;
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphMatchPattern.pattern.periph_pattern.target_lun = paMatches[i].result.device_result.target_lun;
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync PeriphMatchPattern.pattern.periph_pattern.flags = PERIPH_MATCH_PATH | PERIPH_MATCH_TARGET |
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync PeriphCCB.cdm.pattern_buf_len = sizeof(struct dev_match_result);
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync PeriphCCB.cdm.match_buf_len = sizeof(aPeriphMatches);
337640774b62333151a0c5cc6407afcb25d93a37vboxsync rc = RTFileIoCtl(FileXpt, CAMIOCOMMAND, &PeriphCCB, sizeof(union ccb), NULL);
dccbbd8ec5b45b567312112e7edd5c7130d56262vboxsync Log(("Error while querying available periph devices rc=%Rrc\n", rc));
41738f3838049e665b571d59d971cc5c74efb6dcvboxsync for (iPeriphMatch = 0; iPeriphMatch < PeriphCCB.cdm.num_matches; iPeriphMatch++)
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync if ( (aPeriphMatches[iPeriphMatch].type == DEV_MATCH_PERIPH)
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync && (!strcmp(aPeriphMatches[iPeriphMatch].result.periph_result.periph_name, "cd")))
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync pPeriphResult = &aPeriphMatches[iPeriphMatch].result.periph_result;
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync break; /* We found the periph device */
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync pPeriphResult->periph_name, pPeriphResult->unit_number);
12bda05d421d110736c4d6127a36e9c438072dadvboxsync /* Remove trailing white space. */
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync strLenRemoveTrailingWhiteSpace(pDevResult->inq_data.vendor,
ba00a478700c77b6b1435cd8a7e7cb64d84f8d93vboxsync strLenRemoveTrailingWhiteSpace(pDevResult->inq_data.product,
f92fba8b6d97160b7c58689eff6c3848702bd7bavboxsync * Extract the names of drives from an environment variable and add them to a
342d1c2e846281e0bcbde2e97218273216b3fb32vboxsync * list if they are valid.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * @returns iprt status code
9b5a120b694c2603a7a3dccbd6cc519164943b17vboxsync * @param pcszVar the name of the environment variable. The variable
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * value should be a list of device node names, separated
9b5a120b694c2603a7a3dccbd6cc519164943b17vboxsync * by ':' characters.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync * @param pList the list to append the drives found to
9b5a120b694c2603a7a3dccbd6cc519164943b17vboxsync * @param isDVD are we looking for DVD drives or for floppies?
9b5a120b694c2603a7a3dccbd6cc519164943b17vboxsync * @param pfSuccess this will be set to true if we found at least one drive
9b5a120b694c2603a7a3dccbd6cc519164943b17vboxsync * and to false otherwise. Optional.
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsyncstatic int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList,
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER);
9f4747a43944848d911353b1bcc99f41aaa5bf81vboxsync LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar,
bool success = false;
if (pcszNext)
success = true;
return rc;
bool halSuccess = false;
#if defined(RT_OS_LINUX)
#ifdef VBOX_WITH_DBUS
if (!success)
return rc;
volatile bool mTriggered;
volatile bool mInterrupt;
delete mContext;
bool connected = true;
unsigned cRealMillies;
if (!connected)
return rc;