VirtualBox

Changeset 59523 in vbox for trunk


Ignore:
Timestamp:
Jan 29, 2016 4:36:26 PM (9 years ago)
Author:
vboxsync
Message:

Devices/PC/DevPit-i8254.cpp: update PC speaker passthrough, make it more configurable and improve logging
doc/manual: update for PC speaker passthrough, plus a tweak for the table layouts (doubling the minimum column width as it frequently happens that it makes them too narrow)

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/docbook2latex.xsl

    r58442 r59523  
    120120\usepackage{scrextend}
    121121\definecolor{darkgreen}{rgb}{0,0.6,0}
     122\tymin=21pt
    122123
    123124</xsl:text>
  • trunk/doc/manual/en_US/user_AdvancedTopics.xml

    r59514 r59523  
    17731773
    17741774      <screen>VBoxManage setextradata "VM name" "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1</screen>
    1775 
    1776     </sect2>
    1777 
     1775    </sect2>
    17781776  </sect1>
    17791777
     
    30953093
    30963094      <para>This is a global setting.</para>
    3097 
    3098     </sect2>
    3099 
     3095    </sect2>
    31003096  </sect1>
    31013097
     
    35093505      documentation.</para>
    35103506    </sect2>
    3511 
    35123507  </sect1>
    35133508
     
    37183713       </glosslist>
    37193714     </para>
    3720 
    37213715   </sect1>
    37223716
     
    37503744      command to remove the extra data. This is a per-VM setting and it is disabled by default.
    37513745    </para>
    3752 
    37533746  </sect1>
    37543747
     
    37773770    To enable it for the OHCI or XHCI controller replace <computeroutput>usb-ehci</computeroutput>
    37783771    with <computeroutput>usb-ohci</computeroutput> or <computeroutput>usb-xhci</computeroutput> respectively.</para>
    3779 
    37803772  </sect1>
    37813773
     
    38143806      <emphasis>VMMDev: GuestHeartBeat: Guest is alive.</emphasis>
    38153807    </para>
    3816 
    38173808  </sect1>
    38183809
     
    41794170      </sect3>
    41804171    </sect2>
    4181 
    41824172  </sect1>
    41834173
     
    41874177    <para>As an experimental feature (primarily due to being limited to Linux
    41884178    host only and unknown Linux distribution coverage) VirtualBox supports
    4189     passing through the PC speaker to the host, again as PC speaker. This has
    4190     nothing to do with regular audio/sound card support. The PC speaker
    4191     (sometimes called system speaker) is a much older and separate way to
    4192     produce audible feedback like beeps.</para>
    4193 
    4194     <para>The PC speaker passthrough feature handles beeps only. More advanced
    4195     PC speaker use by the VM (such as PCM audio) will not work, resulting in
    4196     undefined PC speaker behavior on the host.</para>
     4179    passing through the PC speaker to the host. The PC speaker (sometimes
     4180    called system speaker) is a way to produce audible feedback such as beeps
     4181    without the need for regular audio/sound card support.</para>
     4182
     4183    <para>The PC speaker passthrough feature in VirtualBox handles beeps only.
     4184    Advanced PC speaker use by the VM (such as PCM audio) will not work,
     4185    resulting in undefined host behavior.</para>
     4186
     4187    <para>Producing beeps on Linux is unfortunately a very complex topic.
     4188    VirtualBox offers a collection of options, in an attempt to make this work
     4189    deterministically and reliably on as many Linux distributions and system
     4190    configurations as possible:
     4191      <table>
     4192        <title>PC speaker configuration options</title>
     4193        <tgroup cols="3">
     4194          <thead>
     4195            <row>
     4196              <entry><emphasis role="bold">Code</emphasis></entry>
     4197              <entry><emphasis role="bold">Device</emphasis></entry>
     4198              <entry><emphasis role="bold">Notes</emphasis></entry>
     4199            </row>
     4200          </thead>
     4201          <tbody>
     4202            <row>
     4203              <entry>1</entry>
     4204              <entry><computeroutput>/dev/input/ by-path/platform- pcspkr-event-spkr</computeroutput></entry>
     4205              <entry>Direct host PC speaker use.</entry>
     4206            </row>
     4207            <row>
     4208              <entry>2</entry>
     4209              <entry><computeroutput>/dev/tty</computeroutput></entry>
     4210              <entry>Uses the terminal association of the VM process. VM needs
     4211              to be started on a virtual console.</entry>
     4212            </row>
     4213            <row>
     4214              <entry>3</entry>
     4215              <entry><computeroutput>/dev/tty0</computeroutput> or
     4216              <computeroutput>/dev/vc/0</computeroutput></entry>
     4217              <entry>Can only be used by user <computeroutput>root</computeroutput>
     4218              or users with capability <computeroutput>cap_sys_tty_config</computeroutput></entry>
     4219            </row>
     4220            <row>
     4221              <entry>9</entry>
     4222              <entry>user specified console or evdev device path</entry>
     4223              <entry>Like 1-3, just with a custom device path.</entry>
     4224            </row>
     4225            <row>
     4226              <entry>70</entry>
     4227              <entry><computeroutput>/dev/tty</computeroutput></entry>
     4228              <entry>Standard beep only. Loses frequency and length. See code
     4229              2.</entry>
     4230            </row>
     4231            <row>
     4232              <entry>79</entry>
     4233              <entry>user specified terminal device path</entry>
     4234              <entry>Like 70, just with a custom device path.</entry>
     4235            </row>
     4236            <row>
     4237              <entry>100</entry>
     4238              <entry>all of the above</entry>
     4239              <entry>Tries all above codes.</entry>
     4240            </row>
     4241          </tbody>
     4242        </tgroup>
     4243      </table>
     4244    </para>
    41974245
    41984246    <para>To enable PC speaker passthrough use the following command:
    4199       <screen>VBoxManage setextradata "VM name" "VBoxInternal/Devices/i8254/0/Config/PassthroughSpeaker" 1</screen>
    4200     Changing this setting will take effect when the VM is started next. It is
    4201     safe to enable PC speaker passthrough on all host OSes. It will only have
    4202     an effect on Linux.</para>
    4203 
    4204     <para>The VM log file, VBox.log, will contain some lines with the prefix
    4205     <computeroutput>PIT: speaker:</computeroutput> showing the PC speaker
    4206     passthrough setup activities. It gives hints which emulation mode it
    4207     picked.</para>
    4208 
    4209     <para>Enabling PC speaker passthrough is usually the simple part. The real
    4210     difficulty is making sure that VirtualBox can access the necessary device.
    4211     PC speaker passthrough tries these devices:
    4212     <screen>/dev/input/by-path/platform-pcspkr-event-spkr
    4213 /dev/tty0
    4214 /dev/vc/0</screen>
    4215     The first one is the most reliable way to control the host PC speaker and
    4216     not some beep emulation through the sound card (showing as emulation mode
    4217     <computeroutput>evdev</computeroutput>. The other two would show as
    4218     emulation mode <computeroutput>console</computeroutput>. In any case, the
    4219     devices are in most linux distributions only accessible by root, and not by
    4220     the user running an X11 session. You need to find out how your distribution
    4221     allows changing this. Since there are countless variants, we can only give
    4222     the general hints that there is either an explicit way to give the X11
    4223     session user access to additional devices, or you need to find a working
    4224     solution using a udev configuration file. If everything fails you might
    4225     try setting the access rights using a script which is run late in the
    4226     startup.</para>
    4227 
    4228     <para>As a final fallback if none of the devices above are accessible,
    4229     VirtualBox will try to get access to the controlling terminal
    4230     <computeroutput>/dev/tty</computeroutput> and trigger standard beeps. This
    4231     loses the beep length and frequency, and is often not producing any beeps,
    4232     because X11 applications frequently have no controlling terminal.</para>
     4247      <screen>VBoxManage setextradata "VM name" "VBoxInternal/Devices/i8254/0/Config/PassthroughSpeaker" N</screen>
     4248    Replace <computeroutput>N</computeroutput> with the code representing the
     4249    case you want to use. Changing this setting will take effect when the VM is
     4250    started next. It is safe to enable PC speaker passthrough on all host OSes.
     4251    It will only have an effect on Linux.</para>
     4252
     4253    <para>The VM log file, <computeroutput>VBox.log</computeroutput>, will
     4254    contain lines with the prefix <computeroutput>PIT: speaker:</computeroutput>
     4255    showing the PC speaker passthrough setup activities. It gives hints which
     4256    device it picked or why it failed.</para>
     4257
     4258    <para>Enabling PC speaker passthrough for the VM is usually the simple
     4259    part. The real difficulty is making sure that VirtualBox can access the
     4260    necessary device, because in a typical Linux install most of them can only
     4261    be accessed by user <computeroutput>root</computeroutput>. You should
     4262    follow the preferred way to persistently change this, e.g by referring to
     4263    your distribution's documentation. Since there are countless Linux
     4264    distribution variants, we can only give the general hints that there is
     4265    often a way to give the X11 session user access to additional devices, or
     4266    you need to find a working solution using a udev configuration file. If
     4267    everything fails you might try setting the permissions using a script
     4268    which is run late enough in the host system startup.</para>
     4269
     4270    <para>Sometimes additional rules are applied by the kernel to limit access
     4271    (e.g. that the VM process must have the same controlling terminal as the
     4272    device configured to be used for beeping, something which is often very
     4273    difficult to achieve for GUI applications such as VirtualBox). The table
     4274    above contains some hints, but generally refer to the Linux
     4275    documentation.</para>
    42334276
    42344277    <para>If you have trouble getting any beeps even if the device permissions
    42354278    are set up and VBox.log confirms that it uses evdev or console for the
    42364279    PC speaker control, check if your system has a PC speaker. Some systems do
    4237     not have a PC speaker. Other complications can arise from Linux rerouting
    4238     the PC speaker output to a sound card. Check if the beeps are audible if
    4239     you (temporarily) connect speakers to your sound card. Today almost all
    4240     systems have one. Finally, check if the audio mixer control has a channel
    4241     named "beep" (could be hidden in the mixer settings) and that it isn't
    4242     muted.</para>
     4280    not have one. Other complications can arise from Linux rerouting the PC
     4281    speaker output to a sound card. Check if the beeps are audible if you
     4282    connect speakers to your sound card. Today almost all systems have one.
     4283    Finally, check if the audio mixer control has a channel named "beep"
     4284    (could be hidden in the mixer settings) and that it isn't muted.</para>
    42434285  </sect1>
    42444286
  • trunk/src/VBox/Devices/PC/DevPit-i8254.cpp

    r59499 r59523  
    55
    66/*
    7  * Copyright (C) 2006-2015 Oracle Corporation
     7 * Copyright (C) 2006-2016 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    276276
    277277
     278#ifdef IN_RING3
     279# ifdef RT_OS_LINUX
     280static int pitTryDeviceOpen(const char *pszPath, int flags)
     281{
     282    int fd = open(pszPath, flags);
     283    if (fd == -1)
     284        LogRel(("PIT: speaker: cannot open \"%s\", errno=%d\n", pszPath, errno));
     285    else
     286        LogRel(("PIT: speaker: opened \"%s\"\n", pszPath));
     287    return fd;
     288}
     289
     290static int pitTryDeviceOpenSanitizeIoctl(const char *pszPath, int flags)
     291{
     292    int fd = open(pszPath, flags);
     293    if (fd == -1)
     294        LogRel(("PIT: speaker: cannot open \"%s\", errno=%d\n", pszPath, errno));
     295    else
     296    {
     297        int errno_eviocgsnd0 = 0;
     298        int errno_kiocsound = 0;
     299        if (ioctl(fd, EVIOCGSND(0)) != -1)
     300        {
     301            errno_eviocgsnd0 = errno;
     302            if (ioctl(fd, KIOCSOUND, 1) == -1)
     303                errno_kiocsound = errno;
     304            else
     305                ioctl(fd, KIOCSOUND, 0);
     306        }
     307        if (errno_eviocgsnd0 && errno_kiocsound)
     308        {
     309            LogRel(("PIT: speaker: cannot use \"%s\", ioctl failed errno=%d/errno=%d\n", pszPath, errno_eviocgsnd0, errno_kiocsound));
     310            close(fd);
     311            fd = -1;
     312        }
     313        else
     314            LogRel(("PIT: speaker: opened \"%s\"\n", pszPath));
     315    }
     316    return fd;
     317}
     318# endif /* RT_OS_LINUX */
     319#endif /* IN_RING3 */
    278320
    279321static int pit_get_count(PPITCHANNEL pChan)
     
    884926                        if (res == -1)
    885927                        {
    886                             LogRel(("PIT: speaker: ioctl failed errno=%d\n", errno));
     928                            LogRel(("PIT: speaker: ioctl failed errno=%d, disabling emulation\n", errno));
    887929                            pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_NONE;
    888930                        }
     
    901943                        break;
    902944                    default:
    903                         Log2Func(("unknown speaker emulation %d\n", pThis->enmSpeakerEmu));
     945                        Log2Func(("unknown speaker emulation %d, disabling emulation\n", pThis->enmSpeakerEmu));
    904946                        pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_NONE;
    905947                }
     
    911953                {
    912954                    case PIT_SPEAKER_EMU_CONSOLE:
     955                        /* No error checking here. The Linux device driver
     956                         * implementation considers it an error (errno=22,
     957                         * EINVAL) to stop sound if it hasn't been started.
     958                         * Of course we could detect this by checking only
     959                         * for enabled->disabled transitions and ignoring
     960                         * disabled->disabled ones, but it's not worth the
     961                         * effort. */
    913962                        ioctl(pThis->hHostSpeaker, KIOCSOUND, 0);
    914963                        break;
     
    925974                        break;
    926975                    default:
    927                         Log2Func(("unknown speaker emulation %d\n", pThis->enmSpeakerEmu));
     976                        Log2Func(("unknown speaker emulation %d, disabling emulation\n", pThis->enmSpeakerEmu));
    928977                        pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_NONE;
    929978                }
     
    12561305     * Validate configuration.
    12571306     */
    1258     if (!CFGMR3AreValuesValid(pCfg, "Irq\0" "Base\0" "SpeakerEnabled\0" "PassthroughSpeaker\0" "R0Enabled\0"))
     1307    if (!CFGMR3AreValuesValid(pCfg, "Irq\0" "Base\0"
     1308                                    "SpeakerEnabled\0" "PassthroughSpeaker\0" "PassthroughSpeakerDevice\0"
     1309                                    "R0Enabled\0" "GCEnabled\0"))
    12591310        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
    12601311
     
    12771328                                N_("Configuration error: Querying \"SpeakerEnabled\" as a bool failed"));
    12781329
    1279     bool fPassthroughSpeaker;
    1280     rc = CFGMR3QueryBoolDef(pCfg, "PassthroughSpeaker", &fPassthroughSpeaker, false);
     1330    uint8_t uPassthroughSpeaker;
     1331    char *pszPassthroughSpeakerDevice = NULL;
     1332    rc = CFGMR3QueryU8Def(pCfg, "PassthroughSpeaker", &uPassthroughSpeaker, 0);
    12811333    if (RT_FAILURE(rc))
    12821334        return PDMDEV_SET_ERROR(pDevIns, rc,
    1283                                 N_("Configuration error: failed to read PassthroughSpeaker as boolean"));
     1335                                N_("Configuration error: failed to read PassthroughSpeaker as uint8_t"));
     1336    if (uPassthroughSpeaker)
     1337    {
     1338        rc = CFGMR3QueryStringAllocDef(pCfg, "PassthroughSpeakerDevice", &pszPassthroughSpeakerDevice, NULL);
     1339        if (RT_FAILURE(rc))
     1340            return PDMDEV_SET_ERROR(pDevIns, rc,
     1341                                    N_("Configuration error: failed to read PassthroughSpeakerDevice as string"));
     1342    }
    12841343
    12851344    rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
     
    12961355    pThis->IOPortBaseCfg   = u16Base;
    12971356    pThis->fSpeakerCfg     = fSpeaker;
    1298     if (fPassthroughSpeaker)
     1357    pThis->enmSpeakerEmu   = PIT_SPEAKER_EMU_NONE;
     1358    if (uPassthroughSpeaker)
    12991359    {
    13001360        /** @todo r=klaus move this to a (system-specific) driver */
    13011361#ifdef RT_OS_LINUX
    1302         int fd;
    1303         fd = open("/dev/input/by-path/platform-pcspkr-event-spkr", O_WRONLY);
    1304         if (fd == -1)
    1305             fd = open("/dev/tty0", O_WRONLY);
    1306         if (fd == -1)
    1307             fd = open("/dev/vc/0", O_WRONLY);
    1308         if (fd == -1)
     1362        int fd = -1;
     1363        if ((uPassthroughSpeaker == 1 || uPassthroughSpeaker == 100) && fd == -1)
     1364            fd = pitTryDeviceOpenSanitizeIoctl("/dev/input/by-path/platform-pcspkr-event-spkr", O_WRONLY);
     1365        if ((uPassthroughSpeaker == 2 || uPassthroughSpeaker == 100) && fd == -1)
     1366            fd = pitTryDeviceOpenSanitizeIoctl("/dev/tty", O_WRONLY);
     1367        if ((uPassthroughSpeaker == 3 || uPassthroughSpeaker == 100) && fd == -1)
    13091368        {
    1310             LogRel(("PIT: speaker: could not open console/speaker device\n"));
    1311             fd = open("/dev/tty", O_WRONLY);
     1369            fd = pitTryDeviceOpenSanitizeIoctl("/dev/tty0", O_WRONLY);
    13121370            if (fd == -1)
    1313             {
    1314                 pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_NONE;
    1315                 LogRel(("PIT: speaker: no emulation possible\n"));
    1316             }
    1317             else
    1318             {
    1319                 pThis->hHostSpeaker = fd;
    1320                 pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_TTY;
    1321                 LogRel(("PIT: speaker: emulation mode tty\n"));
    1322             }
     1371                fd = pitTryDeviceOpenSanitizeIoctl("/dev/vc/0", O_WRONLY);
    13231372        }
    1324         else
     1373        if ((uPassthroughSpeaker == 9 || uPassthroughSpeaker == 100) && pszPassthroughSpeakerDevice && fd == -1)
     1374            fd = pitTryDeviceOpenSanitizeIoctl(pszPassthroughSpeakerDevice, O_WRONLY);
     1375        if (pThis->enmSpeakerEmu == PIT_SPEAKER_EMU_NONE && fd != -1)
    13251376        {
    13261377            pThis->hHostSpeaker = fd;
     
    13361387            }
    13371388        }
     1389        if ((uPassthroughSpeaker == 70 || uPassthroughSpeaker == 100) && fd == -1)
     1390            fd = pitTryDeviceOpen("/dev/tty", O_WRONLY);
     1391        if ((uPassthroughSpeaker == 79 || uPassthroughSpeaker == 100) && pszPassthroughSpeakerDevice && fd == -1)
     1392            fd = pitTryDeviceOpen(pszPassthroughSpeakerDevice, O_WRONLY);
     1393        if (pThis->enmSpeakerEmu == PIT_SPEAKER_EMU_NONE && fd != -1)
     1394        {
     1395            pThis->hHostSpeaker = fd;
     1396            pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_TTY;
     1397            LogRel(("PIT: speaker: emulation mode tty\n"));
     1398        }
     1399        if (pThis->enmSpeakerEmu == PIT_SPEAKER_EMU_NONE)
     1400        {
     1401            Assert(fd == -1);
     1402            LogRel(("PIT: speaker: no emulation possible\n"));
     1403        }
    13381404#else
    1339         pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_NONE;
     1405        LogRel(("PIT: speaker: emulation deactivated\n"));
    13401406#endif
    1341     }
    1342     else
    1343         pThis->enmSpeakerEmu = PIT_SPEAKER_EMU_NONE;
     1407        RTStrFree(pszPassthroughSpeakerDevice);
     1408        pszPassthroughSpeakerDevice = NULL;
     1409    }
    13441410    pThis->channels[0].irq = u8Irq;
    13451411    for (i = 0; i < RT_ELEMENTS(pThis->channels); i++)
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