- Just grab Giant in the ixp425_iic(4) driver since this driver uses
a shared address/data register window pair to access the actual
I2C registers. None of the other ixp425 drivers lock access to these
shared address/data registers yet and that would need to be done before
this could use any meaningful locking.
- Add locking to the interrupt handler and 'iicbus_reset' methods of the
at91_twi(4) driver.
- Add locking to the pcf(4) driver. Other pcf(4) fixes include:
- Don't needlessly zero the softc.
- Use bus_foo rather than bus_space_foo and remove bus space tag and
handle from softc.
- The lpbb(4) driver just grabs Giant for now. This will be refined later
when ppbus(4) is locked.
- As was done with smbus earlier, move the DRIVER_MODULE() lines to match
the bus driver (either iicbus or iicbb) to the bridge driver into the
bridge drivers.
Tested by: sam (arm/ixp425)
11bits. This limits the maximum interface MTU size in TSO case
as upper stack should not generate TCP segments with MSS greater
than the limit. Armed with this information, disable TSO if
interface MTU is greater than the limit.
well as the 15C since it seems to be required in practice. The Linux
natsemi.c driver mostly does this as well.
PR: kern/112179
Submitted by: Mark Willson mark - hydrus org uk
MFC after: 1 week
generation of RTL810x PCIe fast ethernet controller. Note, Tx/Rx
descriptor format is different from that of first generation of
RTL8101E series. Jumbo frame is not supported for RTL810x
family.
Tested by: NAGATA Shinya ( maya AT negeta DOT com )
ATM Tx/Rx checksum offload is supported but TSO and jumbo frame is
not yet supported. Because these newer controllers use different
descriptor formats, a flag RL_FLAG_DESCV2 flag was introduced to
handle that case in Tx/Rx handler. Also newer controllers seems to
require to not touch 'enable Tx/Rx bit' in RL_CPLUS_CMD register
so don't blindly try to set that bits.
Note, it seems that there is still power-saving related issue where
driver fails to attach PHY. Rebooting seems to fix that issue but
number of required reboots varys.
Many thanks to users that helped during developement. I really
appreciate their patient and test/feedbacks.
a dedicated flag that represents controller capabilities/events.
This will simplify many part of code that requires different
workaround for each controller revisions and will enhance
readability.
While I'm here move PHY wakeup code up before mii_phy_probe() which
seems to help to wake PHY in some cases.
received frame under certain conditions. wpaul said the length
0xfff0 is special meaning that indicates hardware is in the
process of copying a packet into host memory. But it seems
there are other cases that hardware is busy or stuck in bad
situation even if the received frame length is not 0xfff0.
To work-around this condition, add a check that verifys that
recevied frame length is in valid range. If received length is out
of range reinitialize hardware to recover from stuck condition.
Reported by: Mike Tancsa ( mike AT sentex DOT net )
Tested by: Mike Tancsa
Obtained from: OpenBSD
MFC after: 1 week
Removed dead code that assumed that M_TRYWAIT can return NULL; it's not true
since the advent of MBUMA.
Reviewed by: arch
There are ongoing disputes as to whether we want to switch to directly using
UMA flags M_WAITOK/M_NOWAIT for mbuf(9) allocation.
- Take advantage of m_collapse(9).
- Sync with other NIC drivers and prepend a TX mbuf if the first attempt
to load it fails with an error other than EFBIG and stop trying instead
of freeing it and keeping on trying to enqueue more mbufs. Also ensure
the driver queue isn't empty before trying to enqueue mbufs in order to
reduce locking operations.
- In xl_ifmedia_upd() add a missing XL_UNLOCK(). [1]
- Const'ify the xl_devs array.
- Remove an outdated comment.
PR: 113406 [1]
MFC after: 1 month
free function controlable, instead of passing the KVA of the buffer
storage as the first argument.
Fix all conventional users of the API to pass the KVA of the buffer
as the first argument, to make this a no-op commit.
Likely break the only non-convetional user of the API, after informing
the relevant committer.
Update the mbuf(9) manual page, which was already out of sync on
this point.
Bump __FreeBSD_version to 800016 as there is no way to tell how
many arguments a CPP macro needs any other way.
This paves the way for giving sendfile(9) a way to wait for the
passed storage to have been accessed before returning.
This does not affect the memory layout or size of mbufs.
Parental oversight by: sam and rwatson.
No MFC is anticipated.
o Increased number of Rx/Tx descriptors to 256 for 8169 GigEs
because it's hard to push the hardware to the limit with default
64 descriptors.
TSO requires large number of Tx descriptors to pass a full sized
TCP segment(65535 bytes IP packet) to hardware. Previously it
consumed 32 Tx descriptors, assuming MCLBYTES DMA segment size,
to send the TCP segment which means re(4) couldn't queue more
than two full sized IP packets.
For 8139C+ it still uses 64 Rx/Tx descriptors due to its hardware
limitations. With this changes there are (very) small waste of
memory for 8139C+ users but I don't think it would affect 8139C+
users for most cases.
o Various bus_dma(9) fixes.
- The hardware supports DAC so allow 64bit DMA operations.
- Removed BUS_DMA_ALLOC_NOW flag.
- Increased DMA segment size to 4096 from MCLBYTES because TSO
consumes too many descriptors with MCLBYTES DMA segment size.
- Tx/Rx side bus_dmamap_load_mbuf_sg(9) support. With these
changes the code is more readable than previous one and got a
(slightly) better performance as it doesn't need to pass/
decode arguments to/from callback function.
- Removed unnecessary callback function re_dmamap_desc() and
nuked rl_dmaload_arg structure which was used in the callback.
- Additional protection for DMA map load failure. In case of
failure reuse current map instead of returning a bogus DMA
map.
- Deferred DMA map unloading/sync operation for maximum
performance until we really need to load new DMA map. If we
happen to reuse current map(e.g. input error) there is no need
to sync/unload/load again.
- The number of allowable Tx DMA segments for a mbuf chains are
now 32 instead of magic nseg value. If the number of available
Tx descriptors are short enough to send highly fragmented mbuf
chains an optimized re_defrag() is called to collapse mbuf
chains which is supposed to be much faster than m_defrag(9).
re_defrag() was borrowed from ath(4).
- Separated Rx/Tx DMA tag from a common DMA tag such that Rx DMA
tag correctly uses DMA maps that were created with DMA alignment
restriction(8bytes alignments). Tx DMA tag does not have such
alignment limitation.
- Added additional sanity checks for DMA ring map load failure.
- Added additional spare Rx DMA map for graceful handling of Rx
DMA map load failure.
- Fixed misused bus_dmamap_sync(9) and added missing
bus_dmamap_sync(9) in re_encap()/re_txeof()/re_rxeof().
o Enabled TSO again as re(4) have reasonable number of Tx
descriptors.
o Don't touch DMA address of a Tx descriptor in re_txeof(). It's
not needed.
o Fix incorrect update of if_ierrors counter. For Rx buffer
shortage it should update if_qdrops as the buffer is reused.
o Added checks for unsupported H/W revisions and return ENXIO for
these hardwares. This is required to remove resource allocation
code in re_probe as other drivers do in device probe routine.
o Modified descriptor index manipulation macros as it's now possible
to have different number of descriptors for Rx/Tx.
o In re_start, to save a lock operation, use IFQ_DRV_IS_EMPTY before
trying to invoke IFQ_DRV_DEQUEUE. Also don't blindly call re_encap
since we already know the number of available Tx descriptors in
advance.
o Removed RL_TX_DESC_THLD which was used to reserve RL_TX_DESC_THLD
descriptors in Tx path. There is no such a limitation mentioned in
8139C+/8169/8110/8168/8101/8111 datasheet and it seems to work ok
without reserving RL_TX_DESC_THLD descriptors.
o Fix a comment for RL_GTXSTART. The register is 8bits register.
o Added comments for 8169/8139C+ hardware restrictions on descriptors.
o Removed forward declaration for "struct rl_softc", it's not needed.
o Added a new structure rl_txdesc for Tx descriptor managements and
a structure rl_rxdesc for Rx descriptor managements.
o Removed unused member variable rl_intlock in driver softc. There are
still several unused member variables which are supposed to be used
to access hardware statistics counters. But it seems that accessing
hardware counters were not implemented yet.
Ethernet Controller. Multicast filtering wasn't tested and needs more
expore. While I'm here change complex if statements with switch
statement which would improve readability.
Reported by: Abdullah Ibn Hamad Al-Marri < wearabnet AT yahoo DOT ca >
Tested by: Abdullah Ibn Hamad Al-Marri < wearabnet AT yahoo DOT ca >
bumped to 800004 to note the change though userland apps should not be
affected since they use <sys/agpio.h> rather than the headers in
sys/dev/agp.
Discussed with: anholt
Repocopy by: simon
/dev/agpgart and agp_free_res() frees resources like the BAR for the
aperture. Splitting this up lets chipset-specific detach routines
manipulate the aperture during their detach routines without panicing.
MFC after: 1 week
Reviewed by: anholt
VR_STICKHW register would result in unexpected results on these
hardwares. wpaul said the following for the issue.
The vr_attach() routine unconditionally does this for all supported
chips:
/*
* Windows may put the chip in suspend mode when it
* shuts down. Be sure to kick it in the head to wake it
* up again.
*/
VR_CLRBIT(sc, VR_STICKHW, (VR_STICKHW_DS0|VR_STICKHW_DS1));
The problem is, the VR_STICKHW register is not valid on all Rhine
devices. The VT86C100A chip, which is present on the D-Link DFE-530TX
boards, doesn't support power management, and its register space is
only 128 bytes wide. The VR_STICKHW register offset falls outside this
range. This may go unnoticed in most scenarios, but if you happen to have
another PCI device in your system which is assigned the register
space immediately after that of the Rhine, the vr(4) driver will
incorrectly stomp it. In my case, the BIOS on my test board decided
to put the register space for my PRO/100 ethernet board right next
to the Rhine, and the Rhine driver ended up clobbering the IMR register
of the PRO/100 device. (Long story short: the board kept locking up on
boot. Took me the better part of the morning suss out why.)
The strictly correct thing to do would be to check the PCI config space
to make sure the device supports the power management capability and only
write to the VR_STICKHW register if it does.
Instead of inspecting chip revision numbers for the availability of
VR_STICKHW register, check the existence of power management capability
of the hardware as wpaul suggested.
Reported by: wpaul
Suggested by: wpaul
OK'ed by: jhb
previously conditionally acquired Giant based on debug.mpsafenet. As that
has now been removed, they are no longer required. Removing them
significantly simplifies error-handling in the socket layer, eliminated
quite a bit of unwinding of locking in error cases.
While here clean up the now unneeded opt_net.h, which previously was used
for the NET_WITH_GIANT kernel option. Clean up some related gotos for
consistency.
Reviewed by: bz, csjp
Tested by: kris
Approved by: re (kensmith)
Ever since switching to adaptive polling re(4) occasionally spews
watchdog timeouts on systems with MSI capability. This change is
minimal one for supporting MSI and re(4) also needs MSIX support
for RTL8111C in future. Because softc structure of re(4) is shared
with rl(4), rl(4) was touched to use the modified softc.
Reported by: cnst
Tested by: cnst
Approved by: re (kensmith)
This adds a function to agp.c to set the aperture resource ID if it's
not the usual AGP_APBASE. Previously, agp.c had been assuming
AGP_APBASE, which resulted in incorrect agp_info, and contortions by
agp_i810.c to work around it.
This also adds functions to agp.c for default AGP_GET_APERTURE() and
AGP_SET_APERTURE(), which return the aperture resource size and disallow
aperture size changes. Moving to these for our AGP drivers will likely
result in stability improvements. This should fix 855-class aperture
size detection.
Additionally, refuse to attach agp_i810 when some RAM is above 4GB and
the GART can't reference memory that high. This should be very rare.
The correct solution would be bus_dma conversion for agp, which is
beyond the scope of this change. Other AGP drivers could likely use
this change as well.
G33/Q35/Q33 AGP support is also included, but disconnected by default
due to lack of testing.
PR: kern/109724 (855 aperture issue)
Submitted by: FUJIMOTO Kou<fujimoto@j.dendai.ac.jp>
Approved by: re (hrs)
would be 93C46(1Kbit) or 93C56(2Kbit). One of differences between them
is number of address lines required to access the EEPROM. For example,
93C56 EEPROM needs 8 address lines to read/write data. If 93C56
recevied premature end of required number of serial clock(CLK) to set
OP code/address of EEPROM, the result would be unexpected behavior.
Previously it tried to detect 93C46, which requires 6 address lines,
and then assumed it would be 93C56 if read data was not expected
value. However, this approach didn't work in some models/situations
as 93C56 requries 8 address lines to access its data. In order to fix
it, change EEPROM probing order such that 93C56 is detected reliably.
While I'm here change hard-coded address line numbers with defined
constant to enhance readability.
PR: 112710
Approved by: re (mux)
now takes a device_t to be the parent of the bus that is being created.
Most SIMs have been updated with a reasonable argument, but a few exceptions
just pass NULL for now. This argument isn't used yet and the newbus
integration likely won't be ready until after 7.0-RELEASE.
Previously whenever PROMISC mode turned on/off link renegotiation
occurs and it could resulted in network unavailability for serveral
seconds.(Depending on switch STP settings it could last several tens
seconds.)
Reported by: Prokofiev S.P. < proks AT logos DOT uptel DOT net >
Tested by: Prokofiev S.P. < proks AT logos DOT uptel DOT net >
The 6105M and 6102 does not have the DWORD alignment problem, so
don't m_defrag() every packet in the transmit path for those.
More stringent usage of tx-descriptor ring and its flags.
Tested on 6102 and 6105M, other chips may also be able to run
without the m_defrag() but I have neither hardware nor docs to
find out.
Sponsored by: Soekris Engineering
use to synchornize and protect all data objects that are used for that
SIM. Drivers that are not yet MPSAFE register Giant and operate as
usual. RIght now, no drivers are MPSAFE, though a few will be changed
in the coming week as this work settles down.
The driver API has changed, so all CAM drivers will need to be recompiled.
The userland API has not changed, so tools like camcontrol do not need to
be recompiled.
sparc64 GENERIC and the sound device drivers known working on sparc64
to use bus_get_dma_tag() to obtain the parent DMA tag so we can get rid
of the sparc64_root_dma_tag kludge eventually. Except for ath(4), sk(4),
stge(4) and ti(4) these changes are runtime tested (unless I booted up
the wrong kernels again...).
operation as it ran out of free descriptors or if there are too many
segments in the first place, call bus_dmamap_unload() in order to
unload the already loaded segments.
For trying to map the defragmented mbuf (chain) in re_encap() this
introduces re_dma_map_desc() setting arg.rl_maxsegs to 0 as a new
failure mode. Previously we just ignored this case, corrupting our
view of the TX ring.
o In re_txeof():
- Don't clear IFF_DRV_OACTIVE unless there are at least 4 free TX
descriptors. Further down the road re_encap() will bail if there
aren't at least 4 free TX descriptors, causing re_start() to
abort and prepend the dequeued mbuf again so it makes no sense
to pretend we could process mbufs again when in fact we won't.
While at it replace this magic 4 with a macro RL_TX_DESC_THLD
throughout this driver.
- Don't cancel the watchdog timeout as soon as there's at least one
free TX descriptor but instead only if all descriptors have been
handled. It's perfectly normal, especially in the DEVICE_POLLING
case, that re_txeof() is called when only a part of the enqueued
TX descriptors have been handled, causing the watchdog to be
disarmed prematurely.
o In re_encap():
- If m_defrag() fails just drop the packet like other NIC drivers
do. This should only happen when there's a mbuf shortage, in which
case it was possible to end up with an IFQ full of packets which
couldn't be processed as they couldn't be defragmented as they
were taking up all the mbufs themselves. This includes adjusting
re_start() to not trying to prepend the mbuf (chain) if re_encap()
has freed it.
- Remove dupe initialization of members of struct rl_dmaload_arg to
values that didn't change since trying to process the fragmented
mbuf chain.
While at it remove an unused member from struct rl_dmaload_arg.
o In re_start() remove a abandoned, banal comment. The corresponding
code was moved to re_attach() some time ago.
With these changes re(4) now survives one day (until stopped) of
hammering out packets here.
Reviewed by: yongari
MFC after: 2 weeks
only support external PHYs (besides not connectable internal ones
which respond at the usual addresses, but which don't hurt if we
let them show up) and don't wedge when isolating PHYs. Actually,
this change special cases limiting PHYs to Am79C97{3,5,8}, for
which this driver doesn't implement swiching between the internal
and external PHYs, yet, and Am79C971, where isolating the external
PHY (at least in case it's a DP83840A) wedges the chip. Together
with sys/dev/mii/acphy.c rev. 1.21 this adds support for the
100baseFX port of AT-2700 series adaptors, which use two AC101,
one for the copper and one for the fibre port (there might be
variants which only use one PHY though).
- Fix a bug in the previous revision that prevented the address of
the used (external) PHY to be actually recorded.
- Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that.
MFC after: 1 week
- Use printf() and device_printf() instead of log() in ichsmb(4).
- Create the mutex sooner during ichsmb(4) attach.
- Attach the interrupt handler later during ichsmb(4) attach to avoid
races.
- Don't try to set PCIM_CMD_PORTEN in ichsmb(4) attach as the PCI bus
driver does this already.
- Add locking to alpm(4), amdpm(4), amdsmb(4), intsmb(4), nfsmb(4), and
viapm(4).
- Axe ALPM_SMBIO_BASE_ADDR, it's not really safe to write arbitrary values
into BARs, and the PCI bus layer will allocate resources now if needed.
- Merge intpm(4) and intsmb(4) into just intsmb(4). Previously, intpm(4)
attached to the PCI device and created an intsmb(4) child. Now,
intsmb(4) just attaches to PCI directly.
- Change several intsmb functions to take a softc instead of a device_t
to make things simpler.
- Rename confusing AGP_INTEL_I845_MCHCFG to AGP_INTEL_I845_AGPM.
- Move E7205 and E7505 from i8x5 to i8x0 family. It probably worked
because the actual offset is the same.
In fact, all three families have the bit at the exact same place. Only
differences are name and width of the registers, i.e., NBXCFG (0x50, dword),
RDCR (0x51, byte), AGPM (0x51, byte), MCHCFG (0x50, word) depending on
the family of the chipsets.
Because accessing ID registers in rtl81x9 needs 32bit register access
and RL_IDR4/RL_IDR5 registers are reservered registers bzero() is
needed before copying ethernet address.
This fixes unaligned memory accesses panic in sparc64.
PR: kern/106801
MFC after: 3 days
timer in xl_txeof()/xl_txeof_90xB(); xl_poll_locked() unconditionally
invokes xl_txeof()/xl_txeof_90xB(), effectively circumventing that
the watchdog ever fires in the DEVICE_POLLING case as its timer is
constantly reloaded.
- Remove the banal and pedantically outdated comment regarding setting
xl_wdog_timer to 0 in xl_txeof().
Pointed out by: bde
driving xl_watchdog() in order to avoid races accessing if_timer.
While at it relax the watchdog a bit by reloading it in xl_txeof()/
xl_txeof_90xB() if there are still packets enqueued.
- Use bus_get_dma_tag() so xl(4) works on platforms requiring it.
- Don't bother to set if_mtu to ETHERMTU, ether_ifattach() does that.
via the PCN_CSR_MODE register. Along with sys/dev/mii/nsphy.c 1.26
this fixes the case of certain Am79c971-based HP cards and on-board
ones in IBM machines reporting link but not actually passing any
traffic. [1]
- Add support for the internal 10baseT PHY, which actually is used on
at least said HP cards (together with an external DP83840A in a
multiple PHYs configuration). With cards that don't make use of this
internal PHY it'll also show up in FreeBSD but not cause any harm.
This is still missing support for multiple PHYs configuration using
the internal 100baseTX and/or HomePNA PHYs together with external
PHYs or multiple external PHYs though.
- In pcn_ifmedia_upd() call pcn_reset() as otherwise the Am79C971 of
at least said HP cards can wedge when switching from the internal
10baseT PHY to the external PHY. This means that we need to also
initialize and possibly start the chip again in pcn_ifmedia_upd(),
which isn't that bad though as for setting the media port the chip
has to be powered down or stopped anyway and unlike documented
doesn't take effect until the next initialization.
PR: 27995, 25959, 72966 (likely) [1]
MFC after: 2 weeks
by this driver and largely are not even PCI devices in pcn_chipid.
- Use device_printf(9)/if_printf(9) rather than implementing their
functionality with printf(9).
- Sprinkle some const.
the CAM_NEW_TRAN_CODE that has been in the tree for some years now.
This first step consists solely of adding to or correcting
CAM_NEW_TRAN_CODE pieces in the kernel source tree such
that a both a GENERIC (at least on i386) and a LINT build
with CAM_NEW_TRAN_CODE as an option will compile correctly
and run (at least with some the h/w I have).
After a short settle time, the other pieces (making
CAM_NEW_TRAN_CODE the default and updating libcam
and camcontrol) will be brought in.
This will be an incompatible change in that the size of structures
related to XPT_PATH_INQ and XPT_{GET,SET}_TRAN_SETTINGS change
in both size and content. However, basic system operation and
basic system utilities work well enough with this change.
Reviewed by: freebsd-scsi and specific stakeholders
in #ifdef __NO_STRICT_ALIGNMENT rather than #if defined(__i386__) ||
defined(__amd64__). Currently this change is cosmetic only though.
While at it, fix a nearby style(9) bug and remove a no longer used
header.
The key problem was that the aperture size detection using the MSAC bit
doesn't work -- the bit appears to be set even when it shouldn't be. Linux
takes a different approach, testing for a bit of the GMADR (PCIR_BAR(2)) being
set. However, as I don't think that's a safe way to test aperture size, we
just allocate the resource and check its size. This also pointed out that
agp_generic_attach hadn't been allocating our aperture resource, which may
have caused problems in some cases.
Also corrected is a minor copy-and-pasteo in an error case.
PR: kern/103079
Submitted by: mnag
Tested on: i945GM, i915GM
MFC after: 2 weeks
if_ioctl, if_watchdog, etc, or in functions that are used by
these methods only. In all other cases use device_printf().
This also fixes several panics, when if_printf() is called before
softc->ifp was initialized.
Submitted by: Alex Lyashkov <umka sevcity.net>
- Change smbus_callback() to pass a void * rather than caddr_t.
- Change smbus_bread() to pass a pointer to the count and have it be an
in/out parameter. The input is the size of the buffer (same as before),
but on return it will contain the actual amount of data read back from
the bus. Note that this value may be larger than the input value. It
is up to the caller to treat this as an error if desired.
- Change the SMB_BREAD ioctl to write out the updated struct smbcmd which
will contain the actual number of bytes read in the 'count' field. To
preserve the previous ABI, the old ioctl value is mapped to SMB_OLD_BREAD
which doesn't copy the updated smbcmd back out to userland. I doubt anyone
actually used the old BREAD anyway as it was rediculous to do a bulk-read
but not tell the using program how much data was actually read.
- Make the smbus driver and devclass public in the smbus module and
push all the DRIVER_MODULE()'s for attaching the smbus driver to
various foosmb drivers out into the foosmb modules. This makes all
the foosmb logic centralized and allows new foosmb modules to be
self-contained w/o having to hack smbus.c everytime a new smbus driver
is added.
- Add a new SMB_EINVAL error bit and use it in place of EINVAL to return
an error for bad arguments (such as invalid counts for bread and bwrite).
- Map SMB bus error bits to EIO in smbus_error().
- Make the smbus driver call bus_generic_probe() and require child drivers
such as smb(4) to create device_t's via identify routines. Previously,
smbus just created one anonymous device during attach, and if you had
multiple drivers that could attach it was just random chance as to which
driver got to probe for the sole device_t first.
- Add a mutex to the smbus(4) softc and use it in place of dummy splhigh()
to protect the 'owner' field and perform necessary synchronization for
smbus_request_bus() and smbus_release_bus().
- Change the bread() and bwrite() methods of alpm(4), amdpm(4), and
viapm(4) to only perform a single transaction and not try to use a
loop of multiple transactions for a large request. The framing and
commands to use for a large transaction depend on the upper-layer
protocol (such as SSIF for IPMI over SMBus) from what I can tell, and the
smb(4) driver never allowed bulk read/writes of more than 32-bytes
anyway. The other smb drivers only performed single transactions.
- Fix buffer overflows in the bread() methods of ichsmb(4), alpm(4),
amdpm(4), amdsmb(4), intpm(4), and nfsmb(4).
- Use SMB_xxx errors in viapm(4).
- Destroy ichsmb(4)'s mutex after bus_generic_detach() to avoid problems
from child devices making smb upcalls that would use the mutex during
their detach methods.
MFC after: 1 week
Reviewed by: jmg (mostly)
misc. control registers correctly and it is inconsistent with north bridge.
In fact, there are too many broken BIOS implementations out there and we
cannot fix every possible combination but at least it is consistent with
what we advertise with ioctl(2).