VirtualBox

Changeset 19968 in vbox


Ignore:
Timestamp:
May 24, 2009 12:14:19 PM (15 years ago)
Author:
vboxsync
Message:

HostDVD: Add basic support for FreeBSD. Passthrough is working quite well so far.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/scsi.h

    r18322 r19968  
    3333#include <iprt/assert.h>
    3434
    35 #define SCSI_MAX_BUFFER_SIZE (100 * _1K)
    36 
     35#ifdef RT_OS_FREEBSD
     36/* The cam subsystem doesn't allow more */
     37# define SCSI_MAX_BUFFER_SIZE (64  * _1K)
     38#else
     39# define SCSI_MAX_BUFFER_SIZE (100 * _1K)
     40#endif
    3741
    3842/**
  • trunk/src/VBox/Devices/Builtins.cpp

    r19624 r19968  
    207207    if (RT_FAILURE(rc))
    208208        return rc;
    209 #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
     209#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(RT_OS_FREEBSD)
    210210    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDVD);
    211211    if (RT_FAILURE(rc))
  • trunk/src/VBox/Devices/Makefile.kmk

    r19845 r19968  
    736736ifeq ($(KBUILD_TARGET),freebsd)
    737737Drivers_SOURCES      := $(filter-out \
    738         Storage/DrvHost% \
     738        Storage/DrvHostFloppy% \
    739739        , $(Drivers_SOURCES)) \
    740740        Audio/ossaudio.c
  • trunk/src/VBox/Devices/Storage/DrvHostBase.cpp

    r18645 r19968  
    101101        /*IN*/ FS_INFORMATION_CLASS FileSystemInformationClass );
    102102
     103#elif defined(RT_OS_FREEBSD)
     104# include <sys/cdefs.h>
     105# include <sys/param.h>
     106# include <errno.h>
     107# include <stdio.h>
     108# include <cam/cam.h>
     109# include <cam/cam_ccb.h>
     110# include <cam/scsi/scsi_message.h>
     111# include <cam/scsi/scsi_pass.h>
     112# include <VBox/scsi.h>
     113# include <iprt/log.h>
    103114#else
    104115# error "Unsupported Platform."
     
    140151        &&  pThis->ppScsiTaskDI
    141152        &&  pThis->cbBlock)
     153#elif RT_OS_FREEBSD
     154    if (    pThis->fMediaPresent
     155        &&  pThis->cbBlock)
    142156#else
    143157    if (pThis->fMediaPresent)
    144158#endif
    145159    {
    146 #ifdef RT_OS_DARWIN
     160#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    147161        /*
    148162         * Issue a READ(12) request.
     
    214228        if (pThis->fMediaPresent)
    215229        {
    216 #ifdef RT_OS_DARWIN
     230#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    217231            /** @todo write support... */
    218232            rc = VERR_WRITE_PROTECT;
     
    259273    if (pThis->fMediaPresent)
    260274    {
    261 #ifdef RT_OS_DARWIN
     275#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    262276        rc = VINF_SUCCESS;
    263277        /** @todo scsi device buffer flush... */
     
    934948    return VINF_SUCCESS;
    935949
     950#elif defined(RT_OS_FREEBSD)
     951    int rc = VINF_SUCCESS;
     952    RTFILE FileDevice;
     953
     954    rc = RTFileOpen(&FileDevice, pThis->pszDeviceOpen, RTFILE_O_READWRITE);
     955    if (RT_FAILURE(rc))
     956        return rc;
     957
     958    /*
     959     * The current device handle can't passthrough SCSI commands.
     960     * We have to get he passthrough device path and open this.
     961     */
     962    union ccb DeviceCCB;
     963    memset(&DeviceCCB, 0, sizeof(DeviceCCB));
     964
     965    DeviceCCB.ccb_h.func_code = XPT_GDEVLIST;
     966    int rcBSD = ioctl(FileDevice, CAMGETPASSTHRU, &DeviceCCB);
     967    if (!rcBSD)
     968    {
     969        char *pszPassthroughDevice = NULL;
     970        rc = RTStrAPrintf(&pszPassthroughDevice, "/dev/%s%u",
     971                          DeviceCCB.cgdl.periph_name, DeviceCCB.cgdl.unit_number);
     972        if (RT_SUCCESS(rc))
     973        {
     974            RTFILE PassthroughDevice;
     975
     976            rc = RTFileOpen(&PassthroughDevice, pszPassthroughDevice, RTFILE_O_READWRITE);
     977
     978            RTStrFree(pszPassthroughDevice);
     979
     980            if (RT_SUCCESS(rc))
     981            {
     982                /* Get needed device parameters. */
     983                union ccb DeviceCCB;
     984
     985                /*
     986                 * The device path, target id and lun id. Those are
     987                 * needed for the SCSI passthrough ioctl.
     988                 */
     989                memset(&DeviceCCB, 0, sizeof(DeviceCCB));
     990                DeviceCCB.ccb_h.func_code = XPT_GDEVLIST;
     991
     992                rcBSD = ioctl(PassthroughDevice, CAMGETPASSTHRU, &DeviceCCB);
     993                if (!rcBSD)
     994                {
     995                    if (DeviceCCB.cgdl.status != CAM_GDEVLIST_ERROR)
     996                    {
     997                        pThis->ScsiBus      = DeviceCCB.ccb_h.path_id;
     998                        pThis->ScsiTargetID = DeviceCCB.ccb_h.target_id;
     999                        pThis->ScsiLunID    = DeviceCCB.ccb_h.target_lun;
     1000                        *pFileDevice = PassthroughDevice;
     1001                    }
     1002                    else
     1003                    {
     1004                        /* The passthrough device wasn't found. */
     1005                        rc = VERR_NOT_FOUND;
     1006                    }
     1007                }
     1008                else
     1009                    rc = RTErrConvertFromErrno(errno);
     1010
     1011                if (RT_FAILURE(rc))
     1012                    RTFileClose(PassthroughDevice);
     1013            }
     1014        }
     1015    }
     1016    else
     1017        rc = RTErrConvertFromErrno(errno);
     1018
     1019    RTFileClose(FileDevice);
     1020    return rc;
    9361021#else
    9371022    return RTFileOpen(pFileDevice, pThis->pszDeviceOpen,
     
    10371122static int drvHostBaseGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
    10381123{
    1039 #ifdef RT_OS_DARWIN
     1124#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    10401125    /*
    10411126     * Try a READ_CAPACITY command...
     
    11151200
    11161201
    1117 #ifdef RT_OS_DARWIN
     1202#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    11181203/**
    11191204 * Execute a SCSI command.
     
    12261311    (*ppScsiTaskI)->Release(ppScsiTaskI);
    12271312
     1313# elif defined(RT_OS_FREEBSD)
     1314    int rc = VINF_SUCCESS;
     1315    int rcBSD = 0;
     1316    union ccb DeviceCCB;
     1317    union ccb *pDeviceCCB = &DeviceCCB;
     1318    u_int32_t fFlags;
     1319
     1320    memset(pDeviceCCB, 0, sizeof(DeviceCCB));
     1321    pDeviceCCB->ccb_h.path_id   = pThis->ScsiBus;
     1322    pDeviceCCB->ccb_h.target_id = pThis->ScsiTargetID;
     1323    pDeviceCCB->ccb_h.target_lun = pThis->ScsiLunID;
     1324
     1325    /* The SCSI INQUIRY command can't be passed through directly. */
     1326    if (pbCmd[0] == SCSI_INQUIRY)
     1327    {
     1328        pDeviceCCB->ccb_h.func_code = XPT_GDEV_TYPE;
     1329
     1330        rcBSD = ioctl(pThis->FileDevice, CAMIOCOMMAND, pDeviceCCB);
     1331        if (!rcBSD)
     1332        {
     1333            uint32_t cbCopy =   cbBuf < sizeof(struct scsi_inquiry_data)
     1334                              ? cbBuf
     1335                              : sizeof(struct scsi_inquiry_data);;
     1336            memcpy(pvBuf, &pDeviceCCB->cgd.inq_data, cbCopy);
     1337            memset(pbSense, 0, cbSense);
     1338
     1339            if (pcbBuf)
     1340                *pcbBuf = cbCopy;
     1341        }
     1342        else
     1343            rc = RTErrConvertFromErrno(errno);
     1344    }
     1345    else
     1346    {
     1347        /* Copy the CDB. */
     1348        memcpy(&pDeviceCCB->csio.cdb_io.cdb_bytes, pbCmd, cbCmd);
     1349
     1350        /* Set direction. */
     1351        if (enmTxDir == PDMBLOCKTXDIR_NONE)
     1352            fFlags = CAM_DIR_NONE;
     1353        else if (enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
     1354            fFlags = CAM_DIR_IN;
     1355        else
     1356            fFlags = CAM_DIR_OUT;
     1357
     1358        fFlags |= CAM_DEV_QFRZDIS;
     1359
     1360        cam_fill_csio(&pDeviceCCB->csio, 1, NULL, fFlags, MSG_SIMPLE_Q_TAG,
     1361                      (u_int8_t *)pvBuf, cbBuf, cbSense, cbCmd,
     1362                      cTimeoutMillies ? cTimeoutMillies : 30000/* timeout */);
     1363
     1364        /* Send command */
     1365        rcBSD = ioctl(pThis->FileDevice, CAMIOCOMMAND, pDeviceCCB);
     1366        if (!rcBSD)
     1367        {
     1368            switch (pDeviceCCB->ccb_h.status & CAM_STATUS_MASK)
     1369            {
     1370                case CAM_REQ_CMP:
     1371                    rc = VINF_SUCCESS;
     1372                    break;
     1373                case CAM_SEL_TIMEOUT:
     1374                    rc = VERR_DEV_IO_ERROR;
     1375                    break;
     1376                case CAM_CMD_TIMEOUT:
     1377                    rc = VERR_TIMEOUT;
     1378                    break;
     1379                default:
     1380                    rc = VERR_DEV_IO_ERROR;
     1381            }
     1382
     1383            if (pcbBuf)
     1384                *pcbBuf = cbBuf - pDeviceCCB->csio.resid;
     1385
     1386            if (pbSense)
     1387                memcpy(pbSense, &pDeviceCCB->csio.sense_data,
     1388                       cbSense - pDeviceCCB->csio.sense_resid);
     1389        }
     1390        else
     1391            rc = RTErrConvertFromErrno(errno);
     1392    }
    12281393# endif
    12291394
     
    19262091     * Open the device.
    19272092     */
    1928 #ifdef RT_OS_DARWIN
     2093#if defined(RT_OS_DARWIN)
    19292094    rc = drvHostBaseOpen(pThis, NULL, pThis->fReadOnlyConfig);
    19302095#else
  • trunk/src/VBox/Devices/Storage/DrvHostBase.h

    r18436 r19968  
    8181     * This is invalid if no drive is in the drive. */
    8282    uint64_t volatile       cbSize;
    83 #ifndef RT_OS_DARWIN
     83#if !defined(RT_OS_DARWIN)
    8484    /** The filehandle of the device. */
    8585    RTFILE                  FileDevice;
     
    137137#endif
    138138
     139#ifdef RT_OS_FREEBSD
     140    /** The block size. Set when querying the media size. */
     141    uint32_t                cbBlock;
     142    /** SCSI bus number. */
     143    path_id_t               ScsiBus;
     144    /** target ID of the passthrough device. */
     145    target_id_t             ScsiTargetID;
     146    /** LUN of the passthrough device. */
     147    lun_id_t                ScsiLunID;
     148#endif
    139149
    140150    /**
     
    176186void DRVHostBaseMediaNotPresent(PDRVHOSTBASE pThis);
    177187DECLCALLBACK(void) DRVHostBaseDestruct(PPDMDRVINS pDrvIns);
    178 #ifdef RT_OS_DARWIN
     188#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    179189DECLCALLBACK(int) DRVHostBaseScsiCmd(PDRVHOSTBASE pThis, const uint8_t *pbCmd, size_t cbCmd, PDMBLOCKTXDIR enmTxDir,
    180190                                     void *pvBuf, uint32_t *pcbBuf, uint8_t *pbSense, size_t cbSense, uint32_t cTimeoutMillies);
  • trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp

    r18446 r19968  
    8484# undef USE_MEDIA_POLLING
    8585
     86#elif defined(RT_OS_FREEBSD)
     87# include <sys/cdefs.h>
     88# include <sys/param.h>
     89# include <stdio.h>
     90# include <cam/cam.h>
     91# include <cam/cam_ccb.h>
     92# define USE_MEDIA_POLLING
     93
    8694#else
    8795# error "Unsupported Platform."
     
    129137          * Eject the disc.
    130138          */
    131 #ifdef RT_OS_DARWIN
     139#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    132140         uint8_t abCmd[16] =
    133141         {
     
    306314     * Poll for media change.
    307315     */
     316#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    308317#ifdef RT_OS_DARWIN
    309318    AssertReturn(pThis->ppScsiTaskDI, VERR_INTERNAL_ERROR);
     319#endif
    310320
    311321    /*
     
    376386         * Poll for media change.
    377387         */
    378 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
     388#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
    379389        /* taken care of above. */
    380390#elif defined(RT_OS_LINUX)
     
    406416    LogFlow(("%s: cmd[0]=%#04x txdir=%d pcbBuf=%d timeout=%d\n", __FUNCTION__, pbCmd[0], enmTxDir, *pcbBuf, cTimeoutMillies));
    407417
    408 #ifdef RT_OS_DARWIN
     418#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    409419    /*
    410420     * Pass the request on to the internal scsi command interface.
  • trunk/src/VBox/Main/HostImpl.cpp

    r19239 r19968  
    8787#endif /* RT_OS_WINDOWS */
    8888
     89#ifdef RT_OS_FREEBSD
     90# ifdef VBOX_USE_LIBHAL
     91#  include "vbox-libhal.h"
     92# endif
     93#endif
    8994
    9095#include "HostImpl.h"
     
    396401        RTMemFree(freeMe);
    397402    }
    398 
     403#elif defined(RT_OS_FREEBSD)
     404# ifdef VBOX_USE_LIBHAL
     405    if (!getDVDInfoFromHal(list))
     406# endif
     407    {
     408        /** @todo: Scan for accessible /dev/cd* devices. */
     409    }
    399410#else
    400411    /* PORTME */
     
    15971608////////////////////////////////////////////////////////////////////////////////
    15981609
    1599 #if defined(RT_OS_SOLARIS) && defined(VBOX_USE_LIBHAL)
    1600 /* Solaris hosts, loading libhal at runtime */
     1610#if (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)) && defined(VBOX_USE_LIBHAL)
     1611/* Solaris and FreeBSD hosts, loading libhal at runtime */
    16011612
    16021613/**
     
    16431654                            devNode = tmp;
    16441655#endif
     1656
     1657#ifdef RT_OS_FREEBSD
     1658                            /*
     1659                             * Don't show devices handled by the 'acd' driver.
     1660                             * The ioctls don't work with it.
     1661                             */
     1662                            char *driverName = gLibHalDeviceGetPropertyString(halContext,
     1663                                                       halDevices[i], "freebsd.driver", &dbusError);
     1664                            if (driverName)
     1665                            {
     1666                                if (RTStrCmp(driverName, "acd") == 0)
     1667                                {
     1668                                    gLibHalFreeString(devNode);
     1669                                    devNode = NULL;
     1670                                }
     1671                                gLibHalFreeString(driverName);
     1672                            }
     1673#endif
     1674
    16451675                            if (devNode != 0)
    16461676                            {
  • trunk/src/VBox/Main/Makefile.kmk

    r19960 r19968  
    228228# VBoxSVC_DEFS.linux += VBOX_USE_LIBHAL
    229229VBoxSVC_DEFS.solaris += VBOX_USE_LIBHAL
     230VBoxSVC_DEFS.freebsd += VBOX_USE_LIBHAL
    230231ifdef VBOX_SOLARIS_NSL_RESOLVED
    231232 VBoxSVC_DEFS.solaris += VBOX_SOLARIS_NSL_RESOLVED
     
    336337        solaris/DynLoadLibSolaris.cpp
    337338
     339VBoxSVC_SOURCES.freebsd = \
     340        linux/vbox-libhal.cpp
     341
    338342ifdef VBOX_WITH_USB
    339343 VBoxSVC_SOURCES  += \
  • trunk/src/VBox/Main/include/HostImpl.h

    r19239 r19968  
    133133private:
    134134
    135 #if defined(RT_OS_SOLARIS)
    136 # if defined(VBOX_USE_LIBHAL)
     135#if (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)) && defined(VBOX_USE_LIBHAL)
    137136    bool getDVDInfoFromHal(std::list <ComObjPtr <HostDVDDrive> > &list);
    138137    bool getFloppyInfoFromHal(std::list <ComObjPtr <HostFloppyDrive> > &list);
    139 # endif
     138#endif
     139
     140#if defined(RT_OS_SOLARIS)
    140141    void parseMountTable(char *mountTable, std::list <ComObjPtr <HostDVDDrive> > &list);
    141142    bool validateDevice(const char *deviceNode, bool isCDROM);
Note: See TracChangeset for help on using the changeset viewer.

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