mdio interrupt command completion handling was broken,
as the interrupt handler would clear the mii status
register before mdiodone() sees it.
handle errors in miistatus() and miiane(), to not get
confused.
for unknown reasons, multiwrite is busted in usdhc:
sdhc: write error intr 10 stat ff88858e
usdhccmd: need to reset Datinhibit intr 10 stat ff88858e
usdhc: cmd 193a0027 arg 1e5b6b error intr 18010 stat ff88858f
i'm disabling it for now, adding a flag to the SDio struct.
The original intention was to put devskel in to the
kernel to detach what it provides from devsrv.
That is not a good reason, just move it to userspace.
auth/box has been changed to exec skelfs instead
of relying on '#z'.
We don't need to multiply session path by 2, the definition
for NETQID is:
Meaning we don't need to save room between session paths
for individual Qid paths. This doubles the amount of
pipe sessions we can have before a wrap.
This code is checking the return of devwalk for
a walk resulting in a clone of an open pipe file. However,
devclone ensures that the chan we are cloning is not
currently open.
devproc allows changing the noteid of another process
which opens a race condition in sysrfork(), when deciding
to inherit the noteid of "up" to the child and calling
pidalloc() later to take the reference, the noteid could
have been changed and the childs noteid could have been
freed already in the process.
this bug can only happen when one writes the /proc/n/noteid
file of a another process than your own that is in the
process of forking.
the noteid changing functionality of devproc seems questinable
and seems to be only used by ape's setpgrid() implementation.
Avoid calling sdgetdev() for every I/O. Instead,
put the SDunit pointer for #S/sdXX/* files in Chan.aux
and keep a reference to SDev between sdopen()/sdclose().
This avoids having to do the sdindex() lookup and
qlock(),incref(),decref() on every read/write
operation. Removal of SDev's is quite rare and only
can happen with pcmcia ide controllers, and i assume
that for that we can assume thet fileservers having
been exited properly and closed their files before
we attempt to remove a device.
The rest is improving waserror() codepaths, making
sure we release the locks for any of the interface
callbacks (verify/online).
Also get rid of tas() and instead only change the
unit's rawopen flag while holding raw qlock.
pci uarts are detected late and usually do not contain
the console= parameter logic.
for these, we can just enable them when devuart is reset,
and replay the boot messages once enabled.
this is usefull as it allows us to use these uarts for
kernel debugging in interrupt context.
Use an RWlock so readers can work in parallel in
the common case (no cache updates).
When a reader needs to update the cache to add
a new learned source mac address, it will drop
the rlock and aquire the wlock to do the update.
When we get a read error, we now unbind the
port to avoid further packets being forwarded
to it.
This is usefull for hotplug ethernet devices
like usb ones or tunnels.
Simplify the unbind, getting rid of the refcount,
by having only the reader proc call freeport().
Avoid holding the bridge lock while opening
and closing ethernet/tunnel device files during
bind and unbind.
Dont use smalloc() (especially when holding locks).
Allocate bridges dynamically, so we do not waste
the memory when we do not need them.
Reject non-hostowner from allocating new bridges.
Use consistent naming: port -> port
Use consistent comment style: // -> /* */
Sometimes, there is the one-off occation when one needs to
pass a huge list in rc...
This change makes devenv track total memory consumption
of environment groups allowing them to grow up to 1MB in
size (including overhead).
(Before, only the variable size was restricted, but
not the amount of files being created).
The maximum value size of a single environment variable
is set to half of the total size, which allows the
occational large value. (But not many of them).
Because we track all memory consuption, it is also
now possible to create around 10k small environment
variales.
A hashtable is added for name lookups and the qid.path
was changed to allow direct indexing into the entry
array without needing a scan lookup.
All smalloc() calls have been removed, exhaustion is
handled with error(Enomem) avoiding deadlock
in case we run out of kernel memory.
To avoid a MAXMACH limit of 32 and make
txtflush into an array for the bitmap.
Provide portable macros for testing and clearing
the bits: needtxtflush(), donetxtflush().
On pc/pc64, define inittxtflush()/settxtflush()
as no-op macros, avoiding the storage overhead of
the txtflush array alltogether.
SSL is implemented by devssl. It's extremely
obsolete by now, and is not used anywhere but
cpu, import, and oexportfs.
This change strips out the devssl bits, but
does not (yet) remove the code from libsec.
This makes vmap()/vunmap() take a vlong size argument,
and change the type of Pci.mem[].size to vlong as well.
Even if vmap() wont support large mappings, it is nice to
get the original unruncated value for error checking.
pc64 needs a bigger VMAP window, as system76 pangolin
puts the framebuffer at a physical address > 512GB.
Some mmc controllers have no card detect pin, so the only
way to detect card presence is to issue the ACMD41 which will
fail after a pretty long timeout.
To avoid mmconline() blocking, we only try to initialize the
card synchronous once, and then retry in a background process,
while returning immediately from mmconline() while the retry
is in progress.
This speeds up network boot times significantly on a raspi
without a sdcard inserted.
In a few places, we where using a fixed buffer of sizeof(Dir)+100
size for stat. This is not correct and fails if the name returned
in stat is long.
This results in being unable to seek to the end of file with a
long filename.
The kernel should do the same thing as dirfstat() from libc;
handling the conversion and buffer allocation and returning a
freeable Dir* pointer.
For this, a new dirchanstat() function was added.
The fstat syscall was not rewriting the name to the last path
element; fix it.
In addition, gracefully handle the mountfix case, reallocating
the buffer to accomidate the required stat length plus
size of the new name so dirsetname() does not fail.
The timing loop is here for the case if the
controller doesnt produce an interrupt when
becoming broken. In normal case, we should
just get worken up from the interrupt.
In any case, 100 times a second polling is
not neccessary here, increase to 1 second.
The old strategy of wait and retry doesnt seem to
work very well as it keeps all the forking parents
stuck waiting in the kernel worsening the situation.
The idea with this change is to have rfork() return
error quickly; and without whining; as most callers
would just react with a sysfatal() which might be
better for surviving this.
The Mhead structures have two sources of references to them:
- from Pgrp.mnthash hash-table
- from a channels Chan.umh pointer as returned by namec() for a union directory
Unless one holds the Mhead.lock RWLock, the Mhead.mount chain
can be mutated by eigther cmount(), cunmount() or closepgrp().
Readers, skipping acquiering the lock where:
mountfix(): responsible for rewriting directory entries for
union directory reads; was walking the Mhead.mount chain to
detect if the passed channel itself appears in the mount list.
cmount(): had a check and copy when "new" chan was a union itself
and if the MCREATE flag is set and would copy the mount table.
All this needs to be done with Mhead read-locked while copying
the mount entries.
devproc(): in the handler for reading /proc/n/ns file.
namec(): while checking if the Chan->umh should be initialized.
In addition to this, cmount() is changed to do the mountfree()
of the original mount chain when MREPL is done after releasing
the locks.
Also, some cosmetic changes...
tlsbwrite() would call checkstate() before calling tlsrecwrite()
to make sure the channel is open. however, because checkstate()
only raises the error, the Block* passed wont be freed and
would result in a memory leak.
move the checkstate() call inside tlsrecwrite() to reuse the
error handling that frees the block on error.