We now only reset the PCM out channel during initialization, and handle
the case where the channel's current index has passed the last valid
index properly.
This fixes issues with stuttering audio between multiple subsequent
`aplay` invocations, for example.
This might help with debugging on bare metal. Since the minimum version
that can be specified is revision 2.1, and we do not use any feature
from revision 2.2 or newer, this is merely future-proofing ourselves
for new features yet to be built. Additionally, removing the `VERIFY()`
ensures we will not crash on cards that only support earlier revisions.
The Qemu AC'97 device stops its PCM channel's DMA engine when it is
running and the sample rate is changed. We now make sure the DMA engine
is restarted after changing the sample rate, allowing you to e.g. run
`asctl set r 22050` during `aplay` playback.
This driver is not tested and probably not used on any modern hardware
machine, because it is plugged into the ISA bus and not the PCI bus.
Also, the run script doesn't utilize this device anymore, making it more
hard to test this driver and to ensure it doesn't rot.
Some hardware controllers might reset when trying to do self-test, so
keep the configuration byte to restore it later on.
To ensure we are not missing the response from the i8042 controller,
bump the attempts count to 20 times after initiating self-test check.
Also, try to drain the i8042 controller output buffer as it might be a
early good indication on whether i8042 is present or not.
To ensure we drain all the output buffer, we attempt to read from the
buffer 50 times and not 20 times.
This is very similar to the change that was done in 32053e8, except it
turned out that the new limit of 50 iterations was not enough when
testing on bare metal - most IO operations would succeed in the first or
second iteration, but two of them took 140 and 150 iterations
respectively.
Increase the limit from 50 to 250 to account for this, and have some
additional headroom.
This caused an initialization failure of the i8042 when I tested on
bare metal. We cannot entirely get rid of this method as QEMU for
example doesn't indicate the existence of an i8042 via ACPI, but we can
get away with only doing the manual probing if ACPI is disabled or we
didn't get a 'yes' from it.
Increasing the number of maximum loops did eventually lead to a
successful return from the function, but would later fail the actual
self test.
The SB16 card driver doesn't swallow more than 4096 bytes of data at
once, so instead of asserting just return ENOSPC for now.
To test this, either play normal sound or just this (very!) loud noise:
dd if=/dev/random of=/dev/audio/0 bs=4096
We have 3 new components:
1. The AudioManagement singleton. This class like in other subsystems,
is responsible to find hardware audio controllers and keep a reference
to them.
2. AudioController class - this class is the parent class for hardware
controllers like the Sound Blaster 16 or Intel 82801AA (AC97). For now,
this class has simple interface for getting and controlling sample rate
of audio channels, as well a write interface for specific audio channel
but not reading from it. One AudioController object might have multiple
AudioChannel "child" objects to hold with reference counting.
3. AudioChannel class - this is based on the CharacterDevice class, and
represents hardware PCM audio channel. It facilitates an ioctl interface
which should be consistent across all supported hardware currently.
It has a weak reference to a parent AudioController, and when trying to
write to a channel, it redirects the data to the parent AudioController.
Each audio channel device should be added into a new directory under the
/dev filesystem called "audio".
Since we're in an IRQ each of these evaluate_block_conditions() calls
enqueues a new deferred call, so to save on some space in the deferred
call queue let's just do it once.
Apparently on VirtualBox the keyboard device refused to complete the
reset sequence. With longer delays and more attempts before giving up,
it seems like the problem is gone.
Not only does it makes the code more robust and correct as it allows
error propagation, it allows us to enforce timeouts on waiting loops so
we don't hang forever, by waiting for the i8042 controller to respond to
us.
Therefore, it makes the i8042 more resilient against faulty hardware and
bad behaving chipsets out there.
If we don't do so, we just hang forever because we assume there's i8042
controller in the system, which is not a valid assumption for modern PC
hardware.
As make<T> is infallible, it really should not be used anywhere in the
Kernel. Instead replace with fallible `new (nothrow)` calls, that will
eventually be error-propagated.
We currently support the left super key. This poses an issue on
keyboards that only have a right super key, such as my Steelseries 6G.
The implementation mirrors the left/right shift key logic and
effectively considers the right super key identical to the left one.
Devices such as NVMe can have blocks bigger that 512. Use the
m_block_size variable in read/write_block function instead of the
hardcoded 512 block size.
This makes sure DeviceManagement::try_create_device will call the
static factory function (if available) instead of directly calling the
constructor, which will allow us to move OOM-fallible calls out of
Device constructors.
This device will assist userspace to manage hotplug events.
A userspace application reads a DeviceEvent entry until the return value
is zero which indicates no events that are queued and waiting for
processing.
Trying to read with a buffer smaller than sizeof(DeviceEvent) results in
EOVERFLOW.
For now, there's no ioctl mechanism for this device but in the future an
acknowledgement mechanism can be implemented via ioctl(2) interface.
This was easily done, as the Kernel and Userland don't actually share
any of the APIs exposed by it, so instead the Kernel APIs were moved to
the Kernel, and the Userland APIs stayed in LibKeyboard.
This has multiple advantages:
* The non OOM-fallible String is not longer used for storing the
character map name in the Kernel
* The kernel no longer has to link to the userland LibKeyboard code
* A lot of #ifdef KERNEL cruft can be removed from LibKeyboard
This mostly just moved the problem, as a lot of the callers are not
capable of propagating the errors themselves, but it's a step in the
right direction.
This was broken in commit 0a1b34c753 / PR #11687 since the buffer
descriptor list size was not page-aligned, and the new
`MM.allocate_dma_buffer_pages` expects a page-aligned size.
Although we can still consider this impossible to happen now, because
the mmap syscall entry code verifies that specified offset must be page
aligned, it's still a good practice to VERIFY we actually take a start
address as page-aligned in case of doing mmap on /dev/mem.
As for read(2) on /dev/mem, we don't map anything to userspace so it's
safe to read from whatever offset userspace specified as long as it does
not break the original rules of reading physical memory from /dev/mem.
So far we only had mmap(2) functionality on the /dev/mem device, but now
we can also do read(2) on it.
The test unit was updated to check we are doing it safely.
Previously, one could put '\b' in a keymap, but in non-Terminal
applications, it would just insert a literal '\b' character instead of
behaving like backspace. This patch modifes
`visible_code_point_to_key_code` to include backspace, as well as
renaming it to `code_point_to_key_code` since '\b' is not a visible
character. Additionally, `KeyboardDevice::key_state_changed` has been
rearranged to apply the user's keymap before checking for things like
caps lock.
Add a basic NVMe driver support to serenity
based on NVMe spec 1.4.
The driver can support multiple NVMe drives (subsystems).
But in a NVMe drive, the driver can support one controller
with multiple namespaces.
Each core will get a separate NVMe Queue.
As the system lacks MSI support, PIN based interrupts are
used for IO.
Tested the NVMe support by replacing IDE driver
with the NVMe driver :^)
This will allow File and it's descendants to use RefCounted instead of
having a custom implementation of unref. (Since RefCounted calls
will_be_destroyed automatically)
This commit also removes an erroneous call to `before_removing` in
AHCIPort, this is a duplicate call, as the only reference to the device
is immediately dropped following the call, which in turns calls
`before_removing` via File::unref.
This was a premature optimization from the early days of SerenityOS.
The eternal heap was a simple bump pointer allocator over a static
byte array. My original idea was to avoid heap fragmentation and improve
data locality, but both ideas were rooted in cargo culting, not data.
We would reserve 4 MiB at boot and only ended up using ~256 KiB, wasting
the rest.
This patch replaces all kmalloc_eternal() usage by regular kmalloc().