Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92bcb4a591 | ||
|
|
bd071d588b | ||
|
|
9ec66b0eba | ||
|
|
95bcf78537 | ||
|
|
6f3cae4e0c | ||
|
|
b59e371c0e | ||
|
|
939505198f | ||
|
|
75cb80fd33 | ||
|
|
6ba901606d | ||
|
|
b1d329da2a | ||
|
|
df9946fe80 | ||
|
|
e3d744f1b5 |
No files matched your search
@@ -54,3 +54,27 @@
|
||||
src: "{{ stable_artifact_path }}/"
|
||||
dest: "{{ storage_path }}/../"
|
||||
mode: preserve
|
||||
|
||||
# older builds shrink to compressed images and lose their unpacked tree; the newest few keep both
|
||||
- name: Looking for zstd on the storage server
|
||||
ansible.builtin.shell: command -v zstd
|
||||
register: zstd_present
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Requiring zstd for compaction
|
||||
ansible.builtin.assert:
|
||||
that: zstd_present.rc == 0
|
||||
fail_msg: >-
|
||||
zstd is not installed on the storage server, so older builds cannot
|
||||
be compacted. Install it and re-run this build.
|
||||
|
||||
- name: Compacting older builds
|
||||
ansible.builtin.script:
|
||||
cmd: >-
|
||||
../../utils/compact-builds.sh
|
||||
{{ storage_path | quote }}
|
||||
{{ compact_keep | default(5) | int }}
|
||||
{{ compact_max | default(10) | int }}
|
||||
register: compaction
|
||||
changed_when: "'compacted 0 of' not in compaction.stdout"
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-FileCopyrightText: 2026 KolibriOS team
|
||||
|
||||
# Shrink older builds on the storage server: compress their images and drop
|
||||
# their unpacked tree, which is rebuildable from the commit. sha256sums.txt
|
||||
# keeps naming the bare images, so a compacted build has to be decompressed
|
||||
# before it can be verified.
|
||||
#
|
||||
# Layout: <root>/<version>/<lang>/kolibrios-<descr>-<lang>.{img,iso,raw} -> .zst
|
||||
# <root>/<version>/<lang>/data/ -> removed
|
||||
#
|
||||
# Usage: compact-builds.sh <storage-root> [keep] [max-per-run]
|
||||
# DRY_RUN=1 walks the same selection and changes nothing
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
root=${1:?storage root required}
|
||||
# the build just published is always among these, so an upload in flight is safe
|
||||
keep=${2:-5}
|
||||
# a build is hundreds of MiB to re-compress: cap the first pass over the backlog
|
||||
max=${3:-10}
|
||||
dry=${DRY_RUN:-0}
|
||||
verb=compacted
|
||||
[ "$dry" = 1 ] && verb="would compact"
|
||||
|
||||
# --rm drops the source only once the archive is written; the box serves the
|
||||
# site over NFS, so compaction yields to it
|
||||
compress_image() {
|
||||
nice -n 10 ionice -c3 zstd -12 -T1 -q --rm "$1"
|
||||
}
|
||||
export -f compress_image
|
||||
|
||||
leftovers() {
|
||||
local build=$1
|
||||
find "$build" -mindepth 2 -maxdepth 2 \
|
||||
\( -type d -name data \
|
||||
-o -type f \( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) \) \
|
||||
-print -quit
|
||||
}
|
||||
|
||||
compacted=0
|
||||
pending=0
|
||||
|
||||
while IFS= read -r version; do
|
||||
dir="$root/$version"
|
||||
[ -n "$(leftovers "$dir")" ] || continue
|
||||
|
||||
pending=$((pending + 1))
|
||||
[ "$compacted" -lt "$max" ] || continue
|
||||
|
||||
if [ "$dry" = 1 ]; then
|
||||
compacted=$((compacted + 1))
|
||||
echo "$verb $version"
|
||||
continue
|
||||
fi
|
||||
|
||||
# a build holds nine images: one per core, each zstd kept to one thread so
|
||||
# the two levels of parallelism do not fight. Archive before dropping the
|
||||
# tree, so a failure here leaves the build merely uncompacted and the next
|
||||
# run picks it up again
|
||||
find "$dir" -mindepth 2 -maxdepth 2 -type f \
|
||||
\( -name '*.img' -o -name '*.iso' -o -name '*.raw' \) -print0 \
|
||||
| xargs -0 -r -P "$(nproc)" -I{} bash -c 'compress_image "$@"' _ {}
|
||||
|
||||
find "$dir" -mindepth 2 -maxdepth 2 -type d -name data -exec rm -rf {} +
|
||||
|
||||
compacted=$((compacted + 1))
|
||||
echo "$verb $version"
|
||||
# <tag>-<commit count>-g<sha>: order by the count, never by mtime
|
||||
done < <(find "$root" -mindepth 1 -maxdepth 1 -type d -name '*-*-g*' -printf '%f\n' \
|
||||
| sort -t- -k2,2n | head -n "-$keep")
|
||||
|
||||
echo "$verb $compacted of $pending older build(s), $((pending - compacted)) left for the next run"
|
||||
@@ -34,10 +34,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Bump ${{ matrix.name }} and open PR
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
API: ${{ github.api_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
NAME: ${{ matrix.name }}
|
||||
|
||||
+20
-18
@@ -41,10 +41,6 @@ img_files = {
|
||||
{"LIB/KMENU.OBJ", "common/lib/kmenu.obj"},
|
||||
{"LIB/PIXLIB.OBJ", "common/lib/pixlib.obj"},
|
||||
{"MEDIA/AC97SND", "common/media/ac97snd"},
|
||||
{"MEDIA/IMGF/IMGF", "common/media/ImgF/ImgF"},
|
||||
{"MEDIA/IMGF/CEDG.OBJ", "common/media/ImgF/cEdg.obj"},
|
||||
{"MEDIA/IMGF/DITHER.OBJ", "common/media/ImgF/dither.obj"},
|
||||
{"MEDIA/IMGF/INVSOL.OBJ", "common/media/ImgF/invSol.obj"},
|
||||
{"NETWORK/FTPC.INI", SRC_PROGS .. "/network/ftpc/ftpc.ini"},
|
||||
{"NETWORK/FTPD.INI", "common/network/ftpd.ini"},
|
||||
{"NETWORK/KNMAP", "common/network/knmap"},
|
||||
@@ -58,8 +54,7 @@ img_files = {
|
||||
{"SETTINGS/FB2READ.INI", "common/settings/fb2read.ini"},
|
||||
{"SETTINGS/HA.CFG", SRC_PROGS .. "/other/ha/SETTINGS/HA.CFG"},
|
||||
{"SETTINGS/ICON.INI", build_type .. "/settings/icon.ini"},
|
||||
{"SETTINGS/KEYMAP.KEY", SRC_PROGS .. "/system/taskbar/KEYMAP.KEY"},
|
||||
{"SETTINGS/KOLIBRI.LBL", build_type .. "/settings/kolibri.lbl"},
|
||||
{"SETTINGS/KEYMAP.KEY", VAR_PROGS .. "/system/taskbar/keymap.key.kpack"},
|
||||
{"SETTINGS/LANG.INI", build_type .. "/settings/lang.ini"},
|
||||
{"SETTINGS/MENU.DAT", build_type .. "/settings/menu.dat"},
|
||||
{"SETTINGS/NETWORK.INI", "common/settings/network.ini"},
|
||||
@@ -273,6 +268,10 @@ extra_files = {
|
||||
{"kolibrios/lib/i915_dri.drv", "common/lib/i915_dri.drv"},
|
||||
{"kolibrios/media/fplay", "common/media/fplay"},
|
||||
{"kolibrios/media/fplay_run", "common/media/fplay_run"},
|
||||
{"kolibrios/media/ImgF/ImgF", "common/media/ImgF/ImgF"},
|
||||
{"kolibrios/media/ImgF/cEdg.obj", "common/media/ImgF/cEdg.obj"},
|
||||
{"kolibrios/media/ImgF/dither.obj", "common/media/ImgF/dither.obj"},
|
||||
{"kolibrios/media/ImgF/invSol.obj", "common/media/ImgF/invSol.obj"},
|
||||
{"kolibrios/media/minimp3", "common/media/minimp3"},
|
||||
{"kolibrios/media/updf", SRC .. "/contrib/media/updf/build/uPDF"},
|
||||
{"kolibrios/media/vttf", "common/media/vttf"},
|
||||
@@ -487,11 +486,6 @@ tup.append_table(img_files, {
|
||||
{"DEVELOP/MTDBG", VAR_PROGS .. "/develop/mtdbg/mtdbg"},
|
||||
{"DEVELOP/MSTATE", VAR_PROGS .. "/develop/mstate/mstate"},
|
||||
{"DEVELOP/SCANCODE", VAR_PROGS .. "/develop/scancode/scancode"},
|
||||
{"DEVELOP/EXAMPLES/CIRCLE", VAR_PROGS .. "/develop/examples/circle/circle"},
|
||||
{"DEVELOP/EXAMPLES/COLORREF", VAR_PROGS .. "/demos/colorref/colorref"},
|
||||
{"DEVELOP/EXAMPLES/CONGET", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
|
||||
{"DEVELOP/EXAMPLES/CSLIDE", VAR_PROGS .. "/demos/cslide/cslide"},
|
||||
{"DEVELOP/EXAMPLES/THREAD", VAR_PROGS .. "/develop/examples/thread/thread"},
|
||||
{"File Managers/KFAR", VAR_PROGS .. "/fs/kfar/kfar"},
|
||||
{"File Managers/OPENDIAL", VAR_PROGS .. "/fs/opendial/opendial"},
|
||||
{"LOD", VAR_PROGS .. "/fs/lod/lod"},
|
||||
@@ -652,20 +646,28 @@ tup.append_table(extra_files, {
|
||||
{"kolibrios/3D/blocks/block.bin", VAR_PROGS .. "/bcc32/games/blocks/block.bin"},
|
||||
{"kolibrios/develop/tcc/lib/crt0.o", VAR_PROGS .. "/develop/ktcc/bin/lib/crt0.o", group = "../programs/develop/ktcc/<crt0.o>"},
|
||||
{"kolibrios/develop/tcc/lib/tiny.o", VAR_PROGS .. "/develop/ktcc/bin/lib/tiny.o", group = "../programs/develop/ktcc/<tiny.o>"},
|
||||
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"}
|
||||
{"kolibrios/develop/tcc/lib/libsound.a", VAR_PROGS .. "/develop/ktcc/bin/lib/libsound.a", group = "../programs/develop/ktcc/<libsound.a>"},
|
||||
{"kolibrios/develop/examples/circle", VAR_PROGS .. "/develop/examples/circle/circle"},
|
||||
{"kolibrios/develop/examples/colorref", VAR_PROGS .. "/demos/colorref/colorref"},
|
||||
{"kolibrios/develop/examples/conget", VAR_PROGS .. "/develop/libraries/console_coff/examples/test_gets"},
|
||||
{"kolibrios/develop/examples/cslide", VAR_PROGS .. "/demos/cslide/cslide"},
|
||||
{"kolibrios/develop/examples/thread", VAR_PROGS .. "/develop/examples/thread/thread"}
|
||||
})
|
||||
-- For russian build, add russian-only programs.
|
||||
if build_type == "ru_RU" then tup.append_table(img_files, {
|
||||
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
}) else tup.append_table(img_files, {
|
||||
{"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
}) end
|
||||
-- -- For russian build, add russian-only programs.
|
||||
-- if build_type == "ru_RU" then tup.append_table(img_files, {
|
||||
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
-- }) else tup.append_table(img_files, {
|
||||
-- {"DEVELOP/EXAMPLES/TESTCON2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
-- }) end
|
||||
|
||||
if build_type == "ru_RU" then tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"},
|
||||
{"kolibrios/utils/period", VAR_PROGS .. "/other/period/period"},
|
||||
{"kolibrios/games/Dungeons/Dungeons", VAR_PROGS .. "/games/Dungeons/Dungeons"},
|
||||
{"kolibrios/games/klavisha/klavisha", VAR_PROGS .. "/games/klavisha/klavisha"},
|
||||
{"kolibrios/games/klavisha/basekurs.kla", "ru_RU/games/basekurs.kla"},
|
||||
}) else tup.append_table(extra_files, {
|
||||
{"kolibrios/develop/examples/testcon2", VAR_PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"},
|
||||
}) end
|
||||
|
||||
end -- tup.getconfig('NO_FASM') ~= 'full'
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
06 zSea Image Viewer * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
40 Image Filtering |media/imgf/imgf
|
||||
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
16 Image viewer KIV |media/kiv
|
||||
16 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
16 Animage |media/animage
|
||||
16 Efectos de imаgenes |media/imgf/imgf
|
||||
16 Efectos de imаgenes * |/kolibrios/media/ImgF/ImgF
|
||||
16 Palitra |media/palitra
|
||||
#4 **** MULTIMEDIA
|
||||
16 Pixie Audioplayer |media/pixie
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
16 Image Filtering |media/imgf/imgf
|
||||
16 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA ****
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
06 Image viewer zSea * |/kolibrios/media/zsea/zsea
|
||||
38 Animage |media/animage
|
||||
38 IconEdit |media/iconedit
|
||||
40 Image Filtering |media/imgf/imgf
|
||||
40 Image Filtering * |/kolibrios/media/ImgF/ImgF
|
||||
52 Palitra |media/palitra
|
||||
39 Pipet |develop/pipet
|
||||
#4 **** MULTIMEDIA
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
06 Просмотр фото zSea |/kolibrios/media/zsea/zsea
|
||||
38 Редактор Animage |media/animage
|
||||
38 Редактор иконок |media/iconedit
|
||||
40 Наложение фильтров |media/imgf/imgf
|
||||
40 Наложение фильтров * |/kolibrios/media/ImgF/ImgF
|
||||
52 Палитра |media/palitra
|
||||
39 Пипетка |develop/pipet
|
||||
#4 **** Звук и видео
|
||||
|
||||
+100
-14
@@ -130,6 +130,8 @@ RU_STATUS_IDLE = 0000b shl 2
|
||||
RU_STATUS_SUSPENDED = 0001b shl 2
|
||||
RU_STATUS_NO_RESOURCES = 0010b shl 2
|
||||
RU_STATUS_READY = 0100b shl 2
|
||||
SCB_STATUS_CUS = 11000000b ; CU Status
|
||||
CU_STATUS_ACTIVE = 10b shl 6
|
||||
SCB_STATUS_FCP = 1 shl 8 ; Flow Control Pause
|
||||
SCB_STATUS_SWI = 1 shl 10 ; Software Interrupt
|
||||
SCB_STATUS_MDI = 1 shl 11 ; MDI read/write complete
|
||||
@@ -183,6 +185,8 @@ struct txfd
|
||||
|
||||
ends
|
||||
|
||||
TXFD_STATUS_C = 1 shl 15
|
||||
|
||||
TXFD_CMD_IA = 1 shl 0
|
||||
TXFD_CMD_CFG = 1 shl 1
|
||||
TXFD_CMD_TX = 1 shl 2
|
||||
@@ -628,6 +632,9 @@ reset:
|
||||
mov ax, CU_START or INT_MASK
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
; cmd_wait only means the SCB accepted the command. The Configure below
|
||||
; reuses confcmd, so a slow chip would read it instead of our MAC.
|
||||
call confcmd_wait
|
||||
|
||||
;-------------
|
||||
; Configure CU
|
||||
@@ -652,6 +659,7 @@ reset:
|
||||
mov ax, CU_START ; expect Interrupts from now on
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
call confcmd_wait
|
||||
|
||||
; Start media check timer
|
||||
mov [ebx + device.state], ETH_LINK_DOWN
|
||||
@@ -678,6 +686,11 @@ init_rx_ring:
|
||||
;---------------------
|
||||
; build rxfd structure
|
||||
|
||||
cmp [ebx + device.rx_desc], 0 ; the RFD of an earlier reset
|
||||
je @f
|
||||
invoke NetFree, [ebx + device.rx_desc]
|
||||
mov [ebx + device.rx_desc], 0
|
||||
@@:
|
||||
invoke NetAlloc, 2000
|
||||
test eax, eax
|
||||
jz .out_of_mem
|
||||
@@ -689,6 +702,7 @@ init_rx_ring:
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
|
||||
|
||||
ret
|
||||
@@ -709,6 +723,15 @@ init_tx_ring:
|
||||
invoke GetPhysAddr
|
||||
mov ecx, TX_RING_SIZE
|
||||
.next_desc:
|
||||
; after a reset with frames still unreclaimed: free them, or transmit sees the
|
||||
; descriptor busy (virt_addr) and reports TX overrun forever
|
||||
cmp [esi + txfd.virt_addr], 0
|
||||
je @f
|
||||
push eax ecx
|
||||
invoke NetFree, [esi + txfd.virt_addr]
|
||||
pop ecx eax
|
||||
mov [esi + txfd.virt_addr], 0
|
||||
@@:
|
||||
mov [esi + txfd.status], 0
|
||||
mov [esi + txfd.command], 0
|
||||
lea edx, [eax + txfd.buf_addr]
|
||||
@@ -763,7 +786,7 @@ proc transmit stdcall bufferptr
|
||||
lea edi, [ebx + device.tx_ring + eax]
|
||||
|
||||
; Check if current descriptor is free or still in use
|
||||
cmp [edi + txfd.status], 0
|
||||
cmp [edi + txfd.virt_addr], 0 ; buffer not reclaimed yet
|
||||
jne .overrun
|
||||
|
||||
; Fill in status and command values
|
||||
@@ -786,6 +809,22 @@ proc transmit stdcall bufferptr
|
||||
mov eax, edi
|
||||
invoke GetPhysAddr
|
||||
set_io [ebx + device.io_addr], 0
|
||||
|
||||
; CU_START is only valid while the CU is idle or suspended:
|
||||
; wait for the previous frame to leave (1.2 ms at 10 Mbit)
|
||||
push eax ecx
|
||||
set_io [ebx + device.io_addr], REG_SCB_STATUS
|
||||
mov ecx, 100000
|
||||
.cu_busy:
|
||||
in al, dx
|
||||
and al, SCB_STATUS_CUS
|
||||
cmp al, CU_STATUS_ACTIVE
|
||||
jne .cu_free
|
||||
dec ecx
|
||||
jnz .cu_busy
|
||||
DEBUGF 2, "CU still active, starting anyway\n"
|
||||
.cu_free:
|
||||
pop ecx eax
|
||||
set_io [ebx + device.io_addr], REG_SCB_PTR
|
||||
out dx, eax
|
||||
|
||||
@@ -854,7 +893,7 @@ int_handler:
|
||||
|
||||
DEBUGF 1,"Status: %x\n", ax
|
||||
|
||||
test ax, SCB_STATUS_FR ; did we receive a frame?
|
||||
test ax, SCB_STATUS_FR or SCB_STATUS_RNR ; frame received or receiver stopped?
|
||||
jz .no_rx
|
||||
|
||||
push ax
|
||||
@@ -901,6 +940,7 @@ int_handler:
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.rx_buf_addr], 0xffffffff ; simplified mode, no RBD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
|
||||
|
||||
; restart RX
|
||||
@@ -916,11 +956,22 @@ int_handler:
|
||||
mov ax, RX_START
|
||||
out dx, ax
|
||||
call cmd_wait
|
||||
.out_of_mem:
|
||||
|
||||
; Hand the frame over to the kernel
|
||||
jmp [EthInput]
|
||||
|
||||
.out_of_mem:
|
||||
; The buffer is still our only RFD: drop the frame and reuse it
|
||||
mov esi, [esp] ; the buffer
|
||||
mov ecx, [esi + NET_BUFF.length]
|
||||
dec [ebx + device.packets_rx] ; counted above, before the allocation
|
||||
sub dword [ebx + device.bytes_rx], ecx
|
||||
sbb dword [ebx + device.bytes_rx + 4], 0
|
||||
inc [ebx + device.packets_rx_drop]
|
||||
add esp, 12 ; buffer, .rx_loop, ebx
|
||||
mov esi, [ebx + device.rx_desc]
|
||||
jmp .not_ok
|
||||
|
||||
.not_ok:
|
||||
; Reset the FD
|
||||
mov [esi + sizeof.NET_BUFF + rxfd.status], 0
|
||||
@@ -945,6 +996,27 @@ int_handler:
|
||||
|
||||
.no_rx_:
|
||||
DEBUGF 1, "no more data\n"
|
||||
|
||||
; With a single RFD the receiver sits in No Resources/Suspended whenever a
|
||||
; frame arrived before we re-armed it. Nothing restarts it but us.
|
||||
set_io [ebx + device.io_addr], 0
|
||||
set_io [ebx + device.io_addr], REG_SCB_STATUS
|
||||
in al, dx
|
||||
and al, SCB_STATUS_RUS
|
||||
cmp al, RU_STATUS_READY
|
||||
je .ru_ready
|
||||
test byte[esp], 1 ; bit 0 of the saved status is reserved,
|
||||
jnz .ru_ready ; we mark it: one restart per IRQ
|
||||
or byte[esp], 1
|
||||
movzx eax, al
|
||||
DEBUGF 1, "Restarting receiver, RU status %x\n", eax:2
|
||||
mov esi, [ebx + device.rx_desc]
|
||||
push ebx
|
||||
test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C
|
||||
jnz .rx_loop ; a frame completed meanwhile
|
||||
add esp, 4
|
||||
jmp .not_ok ; re-arm the empty RFD
|
||||
.ru_ready:
|
||||
pop ax
|
||||
|
||||
.no_rx:
|
||||
@@ -955,13 +1027,13 @@ int_handler:
|
||||
|
||||
push eax
|
||||
.loop_tx:
|
||||
mov edi, [ebx + device.last_tx]
|
||||
mov eax, sizeof.txfd
|
||||
mul eax
|
||||
mov eax, [ebx + device.last_tx]
|
||||
mov edx, sizeof.txfd
|
||||
mul edx
|
||||
lea edi, [ebx + device.tx_ring + eax]
|
||||
|
||||
cmp [edi + txfd.status], 0
|
||||
je .tx_done
|
||||
test [edi + txfd.status], TXFD_STATUS_C ; sent by the device?
|
||||
jz .tx_done
|
||||
|
||||
cmp [edi + txfd.virt_addr], 0
|
||||
je .tx_done
|
||||
@@ -970,6 +1042,7 @@ int_handler:
|
||||
|
||||
push [edi + txfd.virt_addr]
|
||||
mov [edi + txfd.virt_addr], 0
|
||||
mov [edi + txfd.status], 0 ; free for transmit again
|
||||
invoke NetFree
|
||||
|
||||
inc [ebx + device.last_tx]
|
||||
@@ -980,12 +1053,6 @@ int_handler:
|
||||
pop eax
|
||||
.no_tx:
|
||||
|
||||
test ax, RU_STATUS_NO_RESOURCES
|
||||
jz .not_out_of_resources
|
||||
|
||||
DEBUGF 2, "Out of resources!\n"
|
||||
|
||||
.not_out_of_resources:
|
||||
pop edi esi ebx
|
||||
xor eax, eax
|
||||
inc eax
|
||||
@@ -1079,6 +1146,25 @@ proc check_media_mii stdcall dev:dword
|
||||
endp
|
||||
|
||||
|
||||
; Wait (up to 1 s) until the device has executed the command in confcmd.
|
||||
align 4
|
||||
confcmd_wait:
|
||||
mov ecx, 1000 ; udelay = Sleep(1), 1 ms
|
||||
.loop:
|
||||
test [ebx + device.confcmd.status], TXFD_STATUS_C
|
||||
jnz .done
|
||||
call udelay
|
||||
dec ecx
|
||||
jnz .loop
|
||||
movzx eax, [ebx + device.confcmd.command]
|
||||
DEBUGF 2, "Command 0x%x not completed\n", eax:4
|
||||
ret
|
||||
.done:
|
||||
movzx eax, [ebx + device.confcmd.command]
|
||||
movzx ecx, [ebx + device.confcmd.status]
|
||||
DEBUGF 1, "Command 0x%x done, status 0x%x\n", eax:4, ecx:4
|
||||
ret
|
||||
|
||||
align 4
|
||||
cmd_wait:
|
||||
|
||||
|
||||
+24
-249
@@ -167,8 +167,6 @@ LogicalDevices dd ? ; pointer to array of usb_unit_data
|
||||
; 1 for a connected USB device, 1 for each disk device
|
||||
; the structure can be freed when .NumReferences decreases to zero
|
||||
NumReferences dd ? ; number of references
|
||||
PollNext dd ?
|
||||
PollPrev dd ?
|
||||
ConfigRequest rb 8 ; buffer for configuration requests
|
||||
LengthRest dd ? ; Length - (size of data which were transferred)
|
||||
; All requests to a given device are serialized,
|
||||
@@ -195,7 +193,7 @@ Parent dd ? ; pointer to parent usb_device_data
|
||||
LUN db ? ; index in usb_device_data.LogicalDevices array
|
||||
DiskIndex db ? ; for name "usbhd<index>"
|
||||
MediaPresent db ?
|
||||
Polled db ?
|
||||
db ? ; alignment
|
||||
DiskDevice dd ? ; handle of disk device or NULL
|
||||
SectorSize dd ? ; sector size
|
||||
; For some devices, the first request to the medium fails with 'unit not ready'.
|
||||
@@ -250,20 +248,6 @@ end virtual
|
||||
; The name is my_driver = 'usbstor'; IOCTL interface is not supported;
|
||||
; usb_functions is an offset of a structure with callback functions.
|
||||
invoke RegUSBDriver, my_driver, 0, usb_functions
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
push eax ebx
|
||||
mov ecx, poll_lock
|
||||
invoke MutexInit
|
||||
mov [poll_head], poll_list
|
||||
mov [poll_head+4], poll_list
|
||||
movi ebx, 1
|
||||
mov ecx, poll_thread
|
||||
xor edx, edx
|
||||
invoke CreateThread
|
||||
cmp eax, -1
|
||||
setnz [poll_running]
|
||||
pop ebx eax
|
||||
; 4. Return the returned value of RegUSBDriver.
|
||||
.nothing:
|
||||
ret
|
||||
@@ -340,9 +324,6 @@ endp
|
||||
proc complete_request
|
||||
; 1. Print common debug messages on fails.
|
||||
if DEBUG
|
||||
mov ebx, [esi+usb_device_data.RequestsQueue+request_queue_item.Next]
|
||||
cmp [ebx+request_queue_item.Callback], poll_tur_callback
|
||||
jz .normal
|
||||
cmp [esi+usb_device_data.Status.Status], CSW_STATUS_FAIL
|
||||
jb .normal
|
||||
jz .fail
|
||||
@@ -1312,7 +1293,6 @@ end virtual
|
||||
mov [esi+usb_unit_data.LUN], cl
|
||||
xor eax, eax
|
||||
mov [esi+usb_unit_data.MediaPresent], al
|
||||
mov [esi+usb_unit_data.Polled], al
|
||||
mov [esi+usb_unit_data.DiskDevice], eax
|
||||
mov [esi+usb_unit_data.SectorSize], eax
|
||||
mov [esi+usb_unit_data.UnitReadyAttempts], eax
|
||||
@@ -1325,19 +1305,6 @@ end virtual
|
||||
add esi, sizeof.usb_unit_data
|
||||
cmp ecx, [ebx+usb_device_data.MaxLUN]
|
||||
jbe .looplun
|
||||
cmp [poll_running], 0
|
||||
jz @f
|
||||
lock inc [ebx+usb_device_data.NumReferences]
|
||||
mov ecx, poll_lock
|
||||
invoke MutexLock
|
||||
mov eax, [poll_head+4]
|
||||
mov [ebx+usb_device_data.PollNext], poll_list
|
||||
mov [ebx+usb_device_data.PollPrev], eax
|
||||
mov [eax+usb_device_data.PollNext], ebx
|
||||
mov [poll_head+4], ebx
|
||||
mov ecx, poll_lock
|
||||
invoke MutexUnlock
|
||||
@@:
|
||||
; 4. Return.
|
||||
pop esi ebx
|
||||
ret 20
|
||||
@@ -1371,14 +1338,11 @@ proc inquiry_callback
|
||||
test al, al
|
||||
jnz .nothing
|
||||
DEBUGF 1,'K : direct-access mass storage device detected\n'
|
||||
; Units that report 'medium not present' (the empty card slot of an LTE
|
||||
; modem or card reader) are not registered: the kernel has no media
|
||||
; change detection, so such a disk would only sit dead in the file
|
||||
; managers. Replugging the device after inserting a card registers it.
|
||||
mov edx, [esp+8]
|
||||
cmp [ecx+usb_device_data.MaxLUN], 0
|
||||
jnz .poll
|
||||
cmp [edx+usb_unit_data.MediaPresent], 0
|
||||
jnz @f
|
||||
.poll:
|
||||
mov [edx+usb_unit_data.Polled], 1
|
||||
@@:
|
||||
cmp [edx+usb_unit_data.MediaPresent], 0
|
||||
jnz @f
|
||||
DEBUGF 1,'K : no media, not registering the disk\n'
|
||||
@@ -1471,16 +1435,15 @@ end virtual
|
||||
endp
|
||||
|
||||
; Temporary thread for initial actions with a new disk device.
|
||||
new_disk_thread:
|
||||
stdcall add_disk, [esp]
|
||||
or eax, -1
|
||||
int 0x40
|
||||
|
||||
proc add_disk
|
||||
push ebx esi edi
|
||||
mov esi, [esp+16]
|
||||
proc new_disk_thread
|
||||
sub esp, 32
|
||||
virtual at esp
|
||||
.name rb 32 ; device name
|
||||
.param dd ? ; contents of edx at the moment of int 0x40/eax=51
|
||||
dd ? ; stack segment
|
||||
end virtual
|
||||
; We are ready to notify the kernel about a new disk device.
|
||||
mov esi, [.param]
|
||||
; 1. Generate name.
|
||||
; 1a. Find a free index.
|
||||
mov ecx, free_numbers_lock
|
||||
@@ -1549,7 +1512,7 @@ proc add_disk
|
||||
jmp .exit
|
||||
.disconnected:
|
||||
invoke MutexUnlock
|
||||
invoke DiskDel, ebx
|
||||
stdcall disk_close, ebx
|
||||
jmp .exit
|
||||
.free_index:
|
||||
mov ecx, free_numbers_lock
|
||||
@@ -1558,7 +1521,6 @@ proc add_disk
|
||||
bts [free_numbers], eax
|
||||
invoke MutexUnlock
|
||||
.drop_reference:
|
||||
mov [esi+usb_unit_data.MediaPresent], 0
|
||||
mov esi, [esi+usb_unit_data.Parent]
|
||||
lock dec [esi+usb_device_data.NumReferences]
|
||||
jnz .exit
|
||||
@@ -1567,186 +1529,8 @@ proc add_disk
|
||||
xchg eax, esi
|
||||
invoke Kfree
|
||||
.exit:
|
||||
add esp, 32
|
||||
pop edi esi ebx
|
||||
ret 4
|
||||
endp
|
||||
|
||||
; Every POLL_INTERVAL, check removable units for inserted or removed media.
|
||||
POLL_INTERVAL = 200
|
||||
|
||||
POLL_READY = 0
|
||||
POLL_NO_MEDIA = 1
|
||||
POLL_CHANGED = 2
|
||||
POLL_OTHER = 3
|
||||
|
||||
proc poll_thread
|
||||
.loop:
|
||||
movi eax, 5
|
||||
mov ebx, POLL_INTERVAL
|
||||
or eax, -1
|
||||
int 0x40
|
||||
mov ecx, poll_lock
|
||||
invoke MutexLock
|
||||
mov ebx, [poll_head]
|
||||
.device:
|
||||
cmp ebx, poll_list
|
||||
jz .done
|
||||
mov ecx, poll_lock
|
||||
invoke MutexUnlock
|
||||
cmp [ebx+usb_device_data.DeviceDisconnected], 0
|
||||
jnz .remove
|
||||
mov esi, [ebx+usb_device_data.LogicalDevices]
|
||||
mov edi, [ebx+usb_device_data.MaxLUN]
|
||||
inc edi
|
||||
.unit:
|
||||
cmp [esi+usb_unit_data.Polled], 0
|
||||
jz .next
|
||||
call poll_unit
|
||||
.next:
|
||||
add esi, sizeof.usb_unit_data
|
||||
dec edi
|
||||
jnz .unit
|
||||
mov ecx, poll_lock
|
||||
invoke MutexLock
|
||||
mov ebx, [ebx+usb_device_data.PollNext]
|
||||
jmp .device
|
||||
.remove:
|
||||
mov ecx, poll_lock
|
||||
invoke MutexLock
|
||||
mov eax, [ebx+usb_device_data.PollNext]
|
||||
mov edx, [ebx+usb_device_data.PollPrev]
|
||||
mov [edx+usb_device_data.PollNext], eax
|
||||
mov [eax+usb_device_data.PollPrev], edx
|
||||
push eax
|
||||
lock dec [ebx+usb_device_data.NumReferences]
|
||||
jnz @f
|
||||
mov eax, [ebx+usb_device_data.LogicalDevices]
|
||||
invoke Kfree
|
||||
xchg eax, ebx
|
||||
invoke Kfree
|
||||
@@:
|
||||
pop ebx
|
||||
jmp .device
|
||||
.done:
|
||||
mov ecx, poll_lock
|
||||
invoke MutexUnlock
|
||||
jmp .loop
|
||||
endp
|
||||
|
||||
proc poll_unit
|
||||
push edi
|
||||
stdcall poll_tur, ebx, esi
|
||||
cmp [esi+usb_unit_data.MediaPresent], 0
|
||||
jnz .registered
|
||||
cmp eax, POLL_CHANGED
|
||||
jnz @f
|
||||
stdcall poll_tur, ebx, esi
|
||||
@@:
|
||||
cmp eax, POLL_READY
|
||||
jnz .done
|
||||
movzx eax, [esi+usb_unit_data.LUN]
|
||||
DEBUGF 1,'K : medium inserted, LUN %d\n',eax
|
||||
mov [esi+usb_unit_data.MediaPresent], 1
|
||||
lock inc [ebx+usb_device_data.NumReferences]
|
||||
stdcall add_disk, esi
|
||||
jmp .done
|
||||
.registered:
|
||||
cmp eax, POLL_NO_MEDIA
|
||||
jz .removed
|
||||
cmp eax, POLL_CHANGED
|
||||
jnz .done
|
||||
.removed:
|
||||
lea ecx, [ebx+usb_device_data.QueueLock]
|
||||
invoke MutexLock
|
||||
xor edi, edi
|
||||
cmp [ebx+usb_device_data.DeviceDisconnected], 0
|
||||
jnz @f
|
||||
xchg edi, [esi+usb_unit_data.DiskDevice]
|
||||
@@:
|
||||
lea ecx, [ebx+usb_device_data.QueueLock]
|
||||
invoke MutexUnlock
|
||||
test edi, edi
|
||||
jz .done
|
||||
movzx eax, [esi+usb_unit_data.LUN]
|
||||
DEBUGF 1,'K : medium removed, LUN %d\n',eax
|
||||
invoke DiskDel, edi
|
||||
.done:
|
||||
pop edi
|
||||
ret
|
||||
endp
|
||||
|
||||
proc poll_tur stdcall uses ebx esi edi, device:dword, unit:dword
|
||||
xor esi, esi
|
||||
xor ecx, ecx
|
||||
invoke CreateEvent
|
||||
test eax, eax
|
||||
jz .fail
|
||||
push eax
|
||||
push edx
|
||||
push POLL_OTHER
|
||||
push [unit]
|
||||
mov edx, esp
|
||||
stdcall queue_request, [device], poll_tur_req, 0, poll_tur_callback, edx
|
||||
mov eax, [esp+12]
|
||||
mov ebx, [esp+8]
|
||||
invoke WaitEvent
|
||||
mov eax, [esp+4]
|
||||
add esp, 16
|
||||
ret
|
||||
.fail:
|
||||
movi eax, POLL_OTHER
|
||||
ret
|
||||
endp
|
||||
|
||||
proc poll_tur_req
|
||||
mov eax, [esp+8]
|
||||
mov eax, [eax]
|
||||
mov al, [eax+usb_unit_data.LUN]
|
||||
mov [edx+command_block_wrapper.Length], 0
|
||||
mov [edx+command_block_wrapper.Flags], CBW_FLAG_IN
|
||||
mov [edx+command_block_wrapper.LUN], al
|
||||
mov byte [edx+usb_device_data.Sense.ErrorCode-usb_device_data.Command], 0
|
||||
ret 8
|
||||
endp
|
||||
|
||||
proc poll_tur_callback
|
||||
mov ecx, [esp+4]
|
||||
xor eax, eax
|
||||
mov dl, [ecx+usb_device_data.Status.Status]
|
||||
cmp dl, CSW_STATUS_OK
|
||||
jz .done
|
||||
mov al, POLL_OTHER
|
||||
cmp dl, CSW_STATUS_FAIL
|
||||
jnz .done
|
||||
mov dl, [ecx+usb_device_data.Sense.ErrorCode]
|
||||
and dl, 7Eh
|
||||
cmp dl, 70h
|
||||
jnz .done
|
||||
mov dl, [ecx+usb_device_data.Sense.SenseKey]
|
||||
and dl, 0Fh
|
||||
mov dh, [ecx+usb_device_data.Sense.AdditionalSenseCode]
|
||||
cmp dx, (3Ah shl 8) + SENSE_NOT_READY
|
||||
jz .no_media
|
||||
cmp dx, (3Ah shl 8) + SENSE_UNIT_ATTENTION
|
||||
jnz @f
|
||||
.no_media:
|
||||
mov al, POLL_NO_MEDIA
|
||||
jmp .done
|
||||
@@:
|
||||
cmp dx, (28h shl 8) + SENSE_UNIT_ATTENTION
|
||||
jnz .done
|
||||
mov al, POLL_CHANGED
|
||||
.done:
|
||||
mov ecx, [esp+8]
|
||||
mov [ecx+4], eax
|
||||
push ebx esi edi
|
||||
mov eax, [ecx+12]
|
||||
mov ebx, [ecx+8]
|
||||
xor edx, edx
|
||||
xor esi, esi
|
||||
invoke RaiseEvent
|
||||
pop edi esi ebx
|
||||
ret 8
|
||||
endp
|
||||
|
||||
; This function is called when the device is disconnected.
|
||||
@@ -1775,15 +1559,16 @@ end virtual
|
||||
invoke MutexLock
|
||||
mov [esi+usb_device_data.DeviceDisconnected], 1
|
||||
invoke MutexUnlock
|
||||
; 3. Notify the kernel that all disk devices are deleted.
|
||||
; 3. Drop one reference to the structure and check whether
|
||||
; that was the last reference.
|
||||
lock dec [esi+usb_device_data.NumReferences]
|
||||
jz .free
|
||||
; 4. If not, there are some additional references due to disk devices;
|
||||
; notify the kernel that those disks are deleted.
|
||||
; Note that new disks cannot be added while we are looping here,
|
||||
; because new_disk_thread checks for .DeviceDisconnected.
|
||||
mov eax, [esi+usb_device_data.LogicalDevices]
|
||||
test eax, eax
|
||||
jz .unref
|
||||
push esi
|
||||
mov ebx, [esi+usb_device_data.MaxLUN]
|
||||
mov esi, eax
|
||||
mov esi, [esi+usb_device_data.LogicalDevices]
|
||||
inc ebx
|
||||
.diskdel:
|
||||
mov eax, [esi+usb_unit_data.DiskDevice]
|
||||
@@ -1794,17 +1579,12 @@ end virtual
|
||||
add esi, sizeof.usb_unit_data
|
||||
dec ebx
|
||||
jnz .diskdel
|
||||
pop esi
|
||||
.unref:
|
||||
; 4. Drop one reference to the structure and check whether
|
||||
; that was the last reference. If not, some operations with the disks
|
||||
; are still possible; disk_close will take care of the rest.
|
||||
lock dec [esi+usb_device_data.NumReferences]
|
||||
jz .free
|
||||
; In this case, some operations with those disks are still possible,
|
||||
; so we can't do anything more now. disk_close will take care of the rest.
|
||||
.return:
|
||||
pop esi ebx
|
||||
ret 4
|
||||
; 5. If that was the last reference, free all resources which were allocated.
|
||||
; 5. If there are no disk devices, free all resources which were allocated.
|
||||
.free:
|
||||
mov eax, [esi+usb_device_data.LogicalDevices]
|
||||
test eax, eax
|
||||
@@ -1837,7 +1617,6 @@ end virtual
|
||||
movzx eax, [esi+usb_unit_data.DiskIndex]
|
||||
bts [free_numbers], eax
|
||||
invoke MutexUnlock
|
||||
mov [esi+usb_unit_data.MediaPresent], 0
|
||||
mov esi, [esi+usb_unit_data.Parent]
|
||||
lock dec [esi+usb_device_data.NumReferences]
|
||||
jnz .nothing
|
||||
@@ -2287,10 +2066,6 @@ data fixups
|
||||
end data
|
||||
|
||||
free_numbers_lock rd 3
|
||||
poll_lock rd 3
|
||||
poll_head rd 2
|
||||
poll_list = poll_head - usb_device_data.PollNext
|
||||
poll_running db ?
|
||||
; 128 devices should be enough for everybody
|
||||
free_numbers dd -1, -1, -1, -1
|
||||
|
||||
|
||||
+970
-105
File diff suppressed because it is too large.
Load diff
@@ -1233,25 +1233,27 @@ f68:
|
||||
mov eax, [ecx + SRV.entry]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
push ecx ;save handl
|
||||
mov eax, -2 ;error free RAM
|
||||
cmp [ecx + SRV.base], 0
|
||||
je .fail
|
||||
|
||||
push ecx ;save handl
|
||||
mov ebp, esp ;START may be cdecl or stdcall
|
||||
push edx ;cmdline
|
||||
push DRV_EXIT
|
||||
call eax ;the result is not checked
|
||||
lea esp, [esp+8]
|
||||
push ecx
|
||||
call [ecx + SRV.entry] ;the result is not checked
|
||||
mov esp, ebp
|
||||
pop esi
|
||||
|
||||
mov ebx, [ecx + SRV.base]
|
||||
mov eax, -2 ;error free RAM
|
||||
test ebx, ebx
|
||||
jz .fail
|
||||
stdcall kernel_free, ebx ;del driver
|
||||
|
||||
mov eax, [ecx + SRV.fd]
|
||||
mov edx, [ecx + SRV.bk]
|
||||
mov eax, [esi + SRV.fd]
|
||||
mov edx, [esi + SRV.bk]
|
||||
mov [edx + SRV.fd], eax
|
||||
mov [eax + SRV.bk], edx
|
||||
stdcall free, ecx
|
||||
push eax
|
||||
stdcall kernel_free, [esi + SRV.base] ;del driver
|
||||
mov eax, esi
|
||||
call free ;eax = mem
|
||||
pop eax
|
||||
;dec [count_services]
|
||||
|
||||
mov [esp + SYSCALL_STACK.eax], eax
|
||||
|
||||
@@ -83,6 +83,31 @@ macro arp_init {
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; arp_clear_device: Empty the ARP table and counters of a removed ;
|
||||
; device. ;
|
||||
; ;
|
||||
; IN: edi = device number * 4 ;
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
macro arp_clear_device {
|
||||
|
||||
xor eax, eax
|
||||
mov [ARP_entries + edi], eax
|
||||
mov [ARP_packets_tx + edi], eax
|
||||
mov [ARP_packets_rx + edi], eax
|
||||
mov [ARP_conflicts + edi], eax
|
||||
|
||||
push edi
|
||||
imul edi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
|
||||
add edi, ARP_table
|
||||
mov ecx, (ARP_TABLE_SIZE * sizeof.ARP_entry)/2
|
||||
rep stosw
|
||||
pop edi
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; arp_decrease_entry_ttls ;
|
||||
@@ -313,6 +338,9 @@ arp_output_request:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
|
||||
[esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
|
||||
|
||||
test ebx, ebx ; device is gone
|
||||
jz .exit
|
||||
|
||||
mov ax, ETHER_PROTO_ARP
|
||||
mov ecx, sizeof.ARP_header
|
||||
mov edx, ETH_BROADCAST ; broadcast mac
|
||||
|
||||
@@ -105,6 +105,29 @@ macro ipv4_init {
|
||||
}
|
||||
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; ipv4_clear_device: Reset the IPv4 settings of a removed device, ;
|
||||
; so no route points to it anymore. ;
|
||||
; ;
|
||||
; IN: edi = device number * 4 ;
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
macro ipv4_clear_device {
|
||||
|
||||
xor eax, eax
|
||||
mov [IPv4_address + edi], eax
|
||||
mov [IPv4_subnet + edi], eax
|
||||
mov [IPv4_nameserver + edi], eax
|
||||
mov [IPv4_gateway + edi], eax
|
||||
mov [IPv4_broadcast + edi], eax
|
||||
mov [IPv4_packets_tx + edi], eax
|
||||
mov [IPv4_packets_rx + edi], eax
|
||||
mov [IPv4_packets_dumped + edi], eax
|
||||
|
||||
}
|
||||
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; Decrease TimeToLive of all fragment slots ;
|
||||
@@ -757,6 +780,8 @@ ipv4_output_raw:
|
||||
push esi eax
|
||||
|
||||
call ipv4_route
|
||||
test eax, eax
|
||||
jz .arp_error
|
||||
call arp_ip_to_mac
|
||||
|
||||
test eax, 0xffff0000 ; error bits
|
||||
@@ -967,6 +992,8 @@ ipv4_route:
|
||||
; Check for on-link
|
||||
xor edi, edi
|
||||
.loop:
|
||||
cmp [net_device_list + edi], 0 ; skip slots without a device
|
||||
je .next
|
||||
mov ebx, [IPv4_address + edi]
|
||||
and ebx, [IPv4_subnet + edi]
|
||||
jz .next
|
||||
@@ -983,7 +1010,10 @@ ipv4_route:
|
||||
mov edi, 4 ; skip loopback device
|
||||
.loop_gw:
|
||||
cmp [IPv4_gateway + edi], 0
|
||||
je .next_gw
|
||||
cmp [net_device_list + edi], 0
|
||||
jne .found_gw
|
||||
.next_gw:
|
||||
add edi, 4
|
||||
cmp edi, 4*NET_DEVICES_MAX
|
||||
jb .loop_gw
|
||||
@@ -1049,14 +1079,23 @@ ipv4_route:
|
||||
cmp eax, 0xffffffff
|
||||
je @f
|
||||
|
||||
; An interface without an address (DHCP not done yet, or the lease
|
||||
; dropped when the link went down) can send nothing but broadcasts: with
|
||||
; address and mask both zero every destination compared as on-link, and
|
||||
; the stack went asking ARP for internet addresses on behalf of 0.0.0.0.
|
||||
test edx, edx
|
||||
jz .fail
|
||||
|
||||
; Check if we should route to gateway or not
|
||||
mov ebx, [IPv4_address + edi]
|
||||
mov ebx, edx
|
||||
and ebx, [IPv4_subnet + edi]
|
||||
mov ecx, eax
|
||||
and ecx, [IPv4_subnet + edi]
|
||||
cmp ecx, ebx
|
||||
je @f
|
||||
mov eax, [IPv4_gateway + edi]
|
||||
test eax, eax
|
||||
jz .fail ; off-link and no gateway
|
||||
@@:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
|
||||
ret
|
||||
|
||||
@@ -61,6 +61,41 @@ macro eth_init {
|
||||
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
; ;
|
||||
; eth_clear_device: Drop the frames of a removed device that are ;
|
||||
; still waiting in the input queue, their ;
|
||||
; NET_BUFF.device will not be valid anymore. ;
|
||||
; ;
|
||||
; IN: ebx = device ptr ;
|
||||
; ;
|
||||
;-----------------------------------------------------------------;
|
||||
macro eth_clear_device {
|
||||
|
||||
local .loop, .done
|
||||
|
||||
spin_lock_irqsave
|
||||
mov esi, [ETH_frame_head]
|
||||
.loop:
|
||||
cmp esi, ETH_frame_head
|
||||
je .done
|
||||
mov eax, esi
|
||||
mov esi, [esi + NET_BUFF.NextPtr]
|
||||
cmp [eax + NET_BUFF.device], ebx
|
||||
jne .loop
|
||||
|
||||
; unlink it, ETH_frame_head/tail double as the NextPtr/PrevPtr of the list head
|
||||
mov ecx, [eax + NET_BUFF.PrevPtr]
|
||||
mov [ecx + NET_BUFF.NextPtr], esi
|
||||
mov [esi + NET_BUFF.PrevPtr], ecx
|
||||
dec [ETH_frame_queued]
|
||||
stdcall net_buff_free, eax
|
||||
jmp .loop
|
||||
.done:
|
||||
spin_unlock_irqrestore
|
||||
|
||||
}
|
||||
|
||||
align 4
|
||||
; This function is called by ethernet drivers.
|
||||
; Push the received ethernet packet onto the ethernet input queue.
|
||||
@@ -245,6 +280,9 @@ eth_output:
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
|
||||
|
||||
test ebx, ebx
|
||||
jz .no_device
|
||||
|
||||
cmp ecx, [ebx + ETH_DEVICE.mtu]
|
||||
ja .too_large
|
||||
|
||||
@@ -295,11 +333,16 @@ eth_output:
|
||||
ret
|
||||
|
||||
.too_large:
|
||||
inc [eax + NET_DEVICE.packets_tx_err]
|
||||
inc [ebx + NET_DEVICE.packets_tx_err]
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: Packet too large!\n"
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.no_device:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: no device!\n"
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------;
|
||||
|
||||
@@ -597,6 +597,16 @@ net_remove_device:
|
||||
mov dword [edi-4], eax
|
||||
dec [net_device_count]
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
; Forget everything the protocols still know about this interface.
|
||||
; Otherwise its IP address keeps matching in ipv4_route, and output
|
||||
; ends up calling through the now empty net_device_list slot.
|
||||
|
||||
sub edi, net_device_list + 4 ; device number * 4
|
||||
ipv4_clear_device
|
||||
arp_clear_device
|
||||
eth_clear_device
|
||||
|
||||
call net_send_event
|
||||
|
||||
xor eax, eax
|
||||
|
||||
@@ -1422,10 +1422,14 @@ endl
|
||||
test [edx + TCP_header.Flags], TH_ACK
|
||||
jz .drop
|
||||
|
||||
mov eax, ebx
|
||||
push ebx
|
||||
lea ecx, [ebx + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
pop eax
|
||||
|
||||
mov ebx, ECONNREFUSED
|
||||
call tcp_drop
|
||||
jmp .drop
|
||||
jmp .drop_no_socket
|
||||
@@:
|
||||
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
@@ -234,23 +234,25 @@ endl
|
||||
mov ebx, TCP_max_win
|
||||
shl ebx, cl
|
||||
pop ecx
|
||||
sub ebx, [eax + TCP_SOCKET.RCV_ADV]
|
||||
add ebx, [eax + TCP_SOCKET.RCV_NXT]
|
||||
|
||||
; Clamp to available window first, then subtract what the peer already knows (as in BSD)
|
||||
|
||||
cmp ebx, ecx
|
||||
jl @f
|
||||
jbe @f
|
||||
mov ebx, ecx
|
||||
@@:
|
||||
sub ebx, [eax + TCP_SOCKET.RCV_ADV]
|
||||
add ebx, [eax + TCP_SOCKET.RCV_NXT]
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: we can increase window by %d bytes\n", ebx
|
||||
|
||||
mov edi, [eax + TCP_SOCKET.t_maxseg]
|
||||
shl edi, 1
|
||||
cmp ebx, edi
|
||||
jae .send
|
||||
cmp ebx, edi ; signed: may be negative if window shrank
|
||||
jge .send
|
||||
|
||||
cmp ebx, SOCKET_BUFFER_SIZE/2
|
||||
jae .send
|
||||
jge .send
|
||||
|
||||
.no_window:
|
||||
|
||||
|
||||
@@ -180,6 +180,8 @@ tcp_connect:
|
||||
|
||||
.nomem:
|
||||
pop edx eax
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, ENOMEM
|
||||
@@ -194,6 +196,8 @@ tcp_connect:
|
||||
.enoroute:
|
||||
pop eax
|
||||
popa
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
dec eax
|
||||
mov ebx, EADDRNOTAVAIL
|
||||
|
||||
+1
-1
Submodule programs/develop/cmm updated: 84fdec8562...4aeaee3386.
@@ -1618,21 +1618,23 @@ endl
|
||||
|
||||
; Open a new TCP socket
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
test eax, eax
|
||||
jz .error3
|
||||
cmp eax, -1
|
||||
je .error3
|
||||
mov [socketnum], eax
|
||||
DEBUGF 1, "Socket: 0x%x\n", eax
|
||||
|
||||
; Connect to the server
|
||||
mcall connect, [socketnum], [sockaddr], 18
|
||||
test eax, eax
|
||||
jnz .error3
|
||||
jnz .error4
|
||||
DEBUGF 1, "Socket is now connected.\n"
|
||||
|
||||
invoke freeaddrinfo ; Free allocated memory
|
||||
mov eax, [socketnum]
|
||||
ret
|
||||
|
||||
.error4:
|
||||
mcall close, [socketnum]
|
||||
.error3:
|
||||
DEBUGF 2, "Could not connect to the remote server\n"
|
||||
invoke freeaddrinfo ; Free allocated memory
|
||||
|
||||
@@ -501,7 +501,8 @@ img.decode.jpg:
|
||||
jnz .no_create_palette
|
||||
push ecx edi
|
||||
mov edi, [eax + Image.Palette]
|
||||
xor eax, eax
|
||||
mov eax, 0xFF000000 ; opaque, like the palettes of the other decoders:
|
||||
; converted to 32 bpp, alpha 0 made the picture invisible
|
||||
mov ecx, 256
|
||||
@@:
|
||||
stosd
|
||||
|
||||
@@ -104,10 +104,26 @@ applyKeymap:
|
||||
cmp al, 9
|
||||
jnc @f
|
||||
push eax
|
||||
push esi edi
|
||||
shl eax,7
|
||||
lea eax,[eax*2+eax]
|
||||
mov [point],eax
|
||||
mcall 70,get_key
|
||||
lea edi,[eax*2+eax] ; offset of the layout = index*384
|
||||
cmp [keymap_file],0
|
||||
jnz .loaded
|
||||
mcall 68,27,keymap_path
|
||||
test eax,eax
|
||||
jz .fail
|
||||
mov [keymap_file],eax
|
||||
mov [keymap_size],edx
|
||||
.loaded:
|
||||
lea eax,[edi+384]
|
||||
cmp eax,[keymap_size]
|
||||
ja .fail
|
||||
mov esi,[keymap_file]
|
||||
add esi,edi
|
||||
mov edi,current_keymap
|
||||
mov ecx,384/4
|
||||
rep movsd
|
||||
pop edi esi
|
||||
mcall 21,2,1,current_keymap
|
||||
inc ecx
|
||||
mcall 21,,,current_keymap_shift
|
||||
@@ -118,6 +134,9 @@ applyKeymap:
|
||||
mcall 21,,9
|
||||
@@:
|
||||
ret
|
||||
.fail:
|
||||
pop edi esi eax
|
||||
ret
|
||||
;---------------------------------------------------------------
|
||||
align 4
|
||||
current_keymap rb 128
|
||||
@@ -132,13 +151,9 @@ point2 dd 0
|
||||
dd inicont
|
||||
db '/sys/settings/lang.ini',0
|
||||
|
||||
get_key:
|
||||
dd 0
|
||||
point dd 0
|
||||
dd 0
|
||||
dd 384
|
||||
dd current_keymap
|
||||
db '/sys/settings/keymap.key',0
|
||||
keymap_path db '/sys/settings/keymap.key',0
|
||||
keymap_file dd 0
|
||||
keymap_size dd 0
|
||||
|
||||
key_r db 0
|
||||
key_r2 db 0
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
-- @taskbar loads keymap.key with f68.27, which unpacks kpack'ed files.
|
||||
tup.rule("KEYMAP.KEY", "cp %f %o" .. tup.getconfig("KPACK_CMD"), "keymap.key.kpack")
|
||||
|
||||
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
|
||||
tup.include(HELPERDIR .. "/use_fasm.lua")
|
||||
|
||||
Reference in new issue
Block a user