Compare commits

..
Author SHA1 Message Date
Doczom b6e583d41c Krn/network: added getsockname and getpeername
Check kernel codestyle / Check kernel codestyle (pull_request) Successful in 21s
Test PR / Build (en_US) (pull_request) Successful in 2m2s
Test PR / Build (ru_RU) (pull_request) Successful in 2m9s
Test PR / Build (es_ES) (pull_request) Successful in 2m13s
2026-07-30 13:29:22 +05:00
330 changed files with 6649 additions and 67137 deletions

No files matched your search

-54
View File
@@ -1,54 +0,0 @@
# =============================================================================
# Apps
# User-facing applications, games, multimedia, UI and desktop resources
# =============================================================================
^programs/(cmm|demos|emulator|games|media|other)/.* @KolibriOS/apps
^contrib/(games|media|other)/.* @KolibriOS/apps
^skins/.* @KolibriOS/apps
# =============================================================================
# System
# Kernel, drivers, filesystems, SDK, libraries, toolchain and system utilities
# =============================================================================
^kernel/.* @KolibriOS/system
^drivers/.* @KolibriOS/system
^programs/(bcc32|develop|fs|hd_load|system|testing)/.* @KolibriOS/system
^contrib/(C_Layer|sdk|toolchain)/.* @KolibriOS/system
# Shared system/API includes in programs/
^programs/[^/]+\\.inc$ @KolibriOS/system
# =============================================================================
# Network
# Network stack, network drivers, protocols, libraries and network applications
# =============================================================================
^kernel/trunk/network/.* @KolibriOS/network
^drivers/ethernet/.* @KolibriOS/network
^drivers/(mii|netdrv)\\.inc$ @KolibriOS/network
^programs/network/.* @KolibriOS/network
^programs/network\\.inc$ @KolibriOS/network
^programs/develop/libraries/(http|network|kos_mbedtls)/.* @KolibriOS/network
^contrib/network/.* @KolibriOS/network
# =============================================================================
# DevOps
# CI/CD, repository infrastructure, build system and autobuild configuration
# =============================================================================
^\\.gitea/.* @KolibriOS/devops
^_tools/.* @KolibriOS/devops
^\\.gitmodules$ @KolibriOS/devops
^build\\.txt$ @KolibriOS/devops
^tup\\.config\\.template$ @KolibriOS/devops
-35
View File
@@ -19,38 +19,3 @@
owner: "{{ storage_user }}"
group: "{{ storage_user }}"
mode: preserve
# per-program binaries browsable at <version>/<lang>/data/, like on the old builds server
- name: Creating build tree folders
ansible.builtin.file:
path: "{{ storage_path }}/{{ version }}/{{ item | basename | regex_replace('\\.tar\\.gz$', '') }}/data"
state: directory
owner: "{{ storage_user }}"
group: "{{ storage_user }}"
mode: '0755'
with_fileglob: "{{ tree_artifact_path }}/*.tar.gz"
- name: Unpacking build trees
ansible.builtin.unarchive:
src: "{{ item }}"
dest: "{{ storage_path }}/{{ version }}/{{ item | basename | regex_replace('\\.tar\\.gz$', '') }}/data"
owner: "{{ storage_user }}"
group: "{{ storage_user }}"
with_fileglob: "{{ tree_artifact_path }}/*.tar.gz"
# stable URL for the newest build: <storage_path>/latest/<lang>/...
- name: Updating latest symlink
ansible.builtin.file:
src: "{{ version }}"
dest: "{{ storage_path }}/latest"
state: link
force: true
owner: "{{ storage_user }}"
group: "{{ storage_user }}"
# emulators hardcode <site root>/<lang>/data/data/kolibri.img; storage_path is the ci folder, one level under the site root
- name: Sending bare images to stable emulator paths
ansible.builtin.copy:
src: "{{ stable_artifact_path }}/"
dest: "{{ storage_path }}/../"
mode: preserve
+22 -83
View File
@@ -162,13 +162,12 @@ jobs:
tup init
tup variant ${{ matrix.lang }}.config
# build the image for language variant; keep the tup log for publishing
# build the image for language variant
- name: Build KolibriOS
run: |
set -o pipefail
export PATH=/home/autobuild/tools/win32/bin:$PATH
source kos32-export-env-vars ${{ gitea.workspace }}
tup build-${{ matrix.lang }} 2>&1 | tee build.log
tup build-${{ matrix.lang }}
# stamp the cache with its commit so later builds diff against it
- name: Record cache base commit
@@ -182,26 +181,15 @@ jobs:
id: vars
run: echo "descr=$(git describe --tags)" >> $GITEA_OUTPUT
# stage build outputs under their final names, plus distribution kit and checksums
- name: Prepare artifacts
# rename build outputs to their final names so artifacts are bare files
- name: Rename images
run: |
set -e
BASE="kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}"
for ext in img iso raw; do
cp "build-${{ matrix.lang }}/data/kolibri.$ext" "$BASE.$ext"
cp "build-${{ matrix.lang }}/data/kolibri.$ext" \
"kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.$ext"
done
# zip: distr targets Windows/DOS users, Explorer opens it natively
(cd "build-${{ matrix.lang }}/data" && zip -r -9 -q "${{ gitea.workspace }}/$BASE.distr.zip" distribution_kit)
# whole build tree for per-program downloads; the big images ship separately
tar -C "build-${{ matrix.lang }}" \
--exclude './data/kolibri.iso' \
--exclude './data/kolibri.raw' \
--exclude './data/distribution_kit' \
-czf "$BASE.tree.tar.gz" .
sha256sum "$BASE".img "$BASE".iso "$BASE".raw "$BASE".distr.zip > "$BASE.sha256sums.txt"
mv build.log "$BASE.build.log"
# publish the images; longer retention for the floppy image
#publish the three images; longer retention for the floppy image.
- name: Upload floppy image
uses: actions/upload-artifact@v3
with:
@@ -223,34 +211,6 @@ jobs:
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.raw
retention-days: 15
- name: Upload distribution kit
uses: actions/upload-artifact@v3
with:
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.distr.zip
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.distr.zip
retention-days: 30
- name: Upload checksums
uses: actions/upload-artifact@v3
with:
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.sha256sums.txt
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.sha256sums.txt
retention-days: 90
- name: Upload build log
uses: actions/upload-artifact@v3
with:
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.build.log
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.build.log
retention-days: 90
- name: Upload build tree
uses: actions/upload-artifact@v3
with:
name: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.tree.tar.gz
path: kolibrios-${{ steps.vars.outputs.descr }}-${{ matrix.lang }}.tree.tar.gz
retention-days: 15
deploy:
name: "Publish Images"
runs-on: ubuntu-latest
@@ -275,50 +235,31 @@ jobs:
run: |
set -eu
rm -rf ./norm-artifacts ./stable-artifacts ./tree-artifacts
mkdir -p ./norm-artifacts ./stable-artifacts ./tree-artifacts
rm -rf ./norm-artifacts
mkdir -p ./norm-artifacts
find ./artifacts -type f -name 'kolibrios-*' | while read -r file; do
fname="$(basename "$file")" # kolibrios-<descr>-<lang>.<suffix>
case "$fname" in
*.tree.tar.gz) stem="${fname%.tree.tar.gz}";;
*.distr.zip) stem="${fname%.distr.zip}";;
*.sha256sums.txt) stem="${fname%.sha256sums.txt}";;
*.build.log) stem="${fname%.build.log}";;
*.img) stem="${fname%.img}";;
*.iso) stem="${fname%.iso}";;
*.raw) stem="${fname%.raw}";;
*) continue;;
esac
lang="${stem##*-}" # <lang> has no dashes, <descr> may
find ./artifacts -type f \( \
-name 'kolibrios-*.img' -o \
-name 'kolibrios-*.iso' -o \
-name 'kolibrios-*.raw' \
\) | while read -r file; do
fname="$(basename "$file")" # kolibrios-<descr>-<lang>.<ext>
name_without_ext="${fname%.*}"
lang="${name_without_ext##*-}"
mkdir -p "./norm-artifacts/$lang"
case "$fname" in
*.tree.tar.gz)
# unpacked on the server into <version>/<lang>/data/ for per-program downloads
cp "$file" "./tree-artifacts/$lang.tar.gz";;
*.sha256sums.txt)
cp "$file" "./norm-artifacts/$lang/sha256sums.txt";;
*.build.log)
cp "$file" "./norm-artifacts/$lang/build.log";;
*.img)
cp "$file" "./norm-artifacts/$lang/$fname"
# emulators (e.g. v86) hardcode <lang>/data/data/kolibri.img at the site root
mkdir -p "./stable-artifacts/$lang/data/data"
cp "$file" "./stable-artifacts/$lang/data/data/kolibri.img";;
*)
cp "$file" "./norm-artifacts/$lang/$fname";;
esac
cp "$file" "./norm-artifacts/$lang/$fname"
done
# derive the version (git describe) from an artifact name: kolibrios-<descr>-<lang>.iso -> <descr>
sample="$(find ./norm-artifacts -type f -name 'kolibrios-*.iso' | head -n1)"
# derive the version (git describe) from an artifact name:
# kolibrios-<descr>-<lang>.<ext> -> <descr>
sample="$(find ./norm-artifacts -type f -name 'kolibrios-*' | head -n1)"
base="$(basename "${sample%.*}")" # kolibrios-<descr>-<lang>
version="${base%-*}" # kolibrios-<descr>
version="${version#kolibrios-}" # <descr>
echo "version=$version" >> $GITEA_OUTPUT
find ./norm-artifacts ./stable-artifacts ./tree-artifacts -type f -print
find ./norm-artifacts -type f -print
- name: Setup SSH
run: |
@@ -344,6 +285,4 @@ jobs:
-e "storage_path=${{ secrets.STORAGE_PATH }}" \
-e "version=${{ steps.normalize.outputs.version }}" \
-e "artifact_path=${{ gitea.workspace }}/norm-artifacts" \
-e "stable_artifact_path=${{ gitea.workspace }}/stable-artifacts" \
-e "tree_artifact_path=${{ gitea.workspace }}/tree-artifacts" \
-v
+2 -1
View File
@@ -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 }}
+1 -1
View File
@@ -4,7 +4,7 @@
branch = main
[submodule "programs/develop/oberon07"]
path = programs/develop/oberon07
url = https://git.kolibrios.org/KolibriOS/oberon-07-compiler.git
url = https://github.com/AntKrotov/oberon-07-compiler.git
branch = master
[submodule "programs/cmm"]
path = programs/cmm
+5 -12
View File
@@ -74,6 +74,7 @@ if build_type == "ru_RU" then tup.append_table(img_files, {
{"WELCOME.HTM", VAR_DATA .. "/" .. build_type .. "/welcome.htm.kpack"},
{"EXAMPLE.ASM", SRC_PROGS .. "/develop/examples/example/rus/example.asm"},
{"DEVELOP/BACKY", SRC_PROGS .. "/develop/backy/Backy_ru"},
{"GAMES/BASEKURS.KLA", build_type .. "/games/basekurs.kla"},
{"File Managers/KFAR.INI", build_type .. "/File Managers/kfar.ini"},
{"GAMES/DESCENT", build_type .. "/games/descent"},
{"SETTINGS/.shell", SRC_PROGS .. "/system/shell/bin/rus/.shell"},
@@ -191,12 +192,6 @@ extra_files = {
{"kolibrios/develop/tcc/samples/", SRC_PROGS .. "/develop/ktcc/libc.obj/samples/*.sh"},
{"kolibrios/develop/tcc/samples/clayer/", SRC_PROGS .. "/develop/ktcc/libc.obj/samples/clayer/*"},
{"kolibrios/develop/utils/SPEDump", SRC_PROGS .. "/develop/SPEDump/SPEDump.kex"},
{"kolibrios/develop/XDPascal/", SRC_PROGS .. "/develop/XDPascal/xdpk/*"},
{"kolibrios/develop/XDPascal/projects2025/", SRC_PROGS .. "/develop/XDPascal/xdpk/projects2025/*"},
{"kolibrios/develop/XDPascal/projects2025/Compiler/", SRC_PROGS .. "/develop/XDPascal/xdpk/projects2025/Compiler/*"},
{"kolibrios/develop/XDPascal/projects2026/", SRC_PROGS .. "/develop/XDPascal/xdpk/projects2026/*"},
{"kolibrios/develop/XDPascal/source/", SRC_PROGS .. "/develop/XDPascal/xdpk/source/*"},
{"kolibrios/develop/XDPascal/units/", SRC_PROGS .. "/develop/XDPascal/xdpk/units/*"},
{"kolibrios/emul/", "common/emul/*"},
{"kolibrios/emul/dosbox/", "common/emul/DosBox/*"},
{"kolibrios/emul/e80/readme.txt", SRC_PROGS .. "/emulator/e80/readme.txt"},
@@ -296,6 +291,8 @@ extra_files = {
{"kolibrios/utils/vmode", "common/vmode"},
{"kolibrios/utils/texture", "common/utils/texture"},
{"kolibrios/utils/kterm/kterm", VAR_PROGS .. "/other/kterm/kterm"},
{"kolibrios/utils/kterm/serial.sys", VAR_DRVS .. "/serial/serial.sys"},
{"kolibrios/utils/kterm/install.sh", SRC .. "/drivers/serial/install.sh"},
{"kolibrios/utils/cnc_editor/cnc_editor", VAR_PROGS .. "/other/cnc_editor/cnc_editor"},
{"kolibrios/utils/cnc_editor/kolibri.NC", SRC_PROGS .. "/other/cnc_editor/kolibri.NC"},
{"kolibrios/utils/kfm/kfm.ini", "common/File Managers/kfm.ini"},
@@ -542,7 +539,7 @@ tup.append_table(img_files, {
{"NETWORK/PING", VAR_PROGS .. "/network/ping/ping"},
{"NETWORK/NETCFG", VAR_PROGS .. "/network/netcfg/netcfg"},
{"NETWORK/NETSTAT", VAR_PROGS .. "/network/netstat/netstat"},
{"NETWORK/NETSURF", VAR_PROGS .. "/network/netsurf/netsurf"},
{"NETWORK/NSINST", VAR_PROGS .. "/network/netsurf/nsinstall"},
{"NETWORK/NSLOOKUP", VAR_PROGS .. "/network/nslookup/nslookup"},
{"NETWORK/PASTA", VAR_PROGS .. "/network/pasta/pasta"},
{"NETWORK/SYNERGYC", VAR_PROGS .. "/network/synergyc/synergyc"},
@@ -573,15 +570,12 @@ tup.append_table(img_files, {
{"DRIVERS/UHCI.SYS", VAR_DRVS .. "/usb/uhci.sys"},
{"DRIVERS/OHCI.SYS", VAR_DRVS .. "/usb/ohci.sys"},
{"DRIVERS/EHCI.SYS", VAR_DRVS .. "/usb/ehci.sys"},
{"DRIVERS/XHCI.SYS", VAR_DRVS .. "/usb/xhci/xhci.sys"},
{"DRIVERS/USBHID.SYS", VAR_DRVS .. "/usb/usbhid/usbhid.sys"},
{"DRIVERS/USBFTDI.SYS", VAR_DRVS .. "/usb/usbftdi/usbftdi.sys"},
{"DRIVERS/USBOTHER.SYS",VAR_DRVS .. "/usb/usbother/usbother.sys"},
{"DRIVERS/USBCDC.SYS", VAR_DRVS .. "/usb/usbnet/usbcdc.sys"},
{"DRIVERS/USBRNDIS.SYS", VAR_DRVS .. "/usb/usbnet/usbrndis.sys"},
{"DRIVERS/USBSTOR.SYS", VAR_DRVS .. "/usb/usbstor.sys"},
{"DRIVERS/RDC.SYS", VAR_DRVS .. "/video/rdc.sys"},
{"DRIVERS/SERIAL.SYS", VAR_DRVS .. "/serial/serial.sys"},
{"DRIVERS/COMMOUSE.SYS", VAR_DRVS .. "/mouse/commouse.sys"},
{"DRIVERS/PS2MOUSE.SYS", VAR_DRVS .. "/mouse/ps2mouse4d/ps2mouse.sys"},
{"DRIVERS/TMPDISK.SYS", VAR_DRVS .. "/disk/tmpdisk.sys"},
@@ -655,6 +649,7 @@ tup.append_table(extra_files, {
})
-- For russian build, add russian-only programs.
if build_type == "ru_RU" then tup.append_table(img_files, {
{"GAMES/KLAVISHA", VAR_PROGS .. "/games/klavisha/klavisha"},
{"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"},
@@ -663,8 +658,6 @@ if build_type == "ru_RU" then tup.append_table(img_files, {
if build_type == "ru_RU" then tup.append_table(extra_files, {
{"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"},
}) end
end -- tup.getconfig('NO_FASM') ~= 'full'
+1 -1
View File
@@ -48,7 +48,7 @@ mht=/sys/network/WebView
docx=/sys/network/WebView
url=/sys/network/WebView
fb2=/sys/fb2read
kla=/kolibrios/games/klavisha/klavisha
kla=/sys/games/klavisha
pdf=/kolibrios/media/updf
avi=/kolibrios/media/fplay_run
mpg=/kolibrios/media/fplay_run
Binary file not shown.
+1 -1
View File
@@ -179,7 +179,7 @@ stl=/sys/3d/view3ds
skn=/sys/skincfg
dtp=/sys/skincfg
lif=/kolibrios/demos/life2
kla=/kolibrios/games/klavisha/klavisha
kla=/sys/games/klavisha
pdf=/kolibrios/media/updf
smc=/kolibrios/emul/zsnes/zsnes
+1 -1
View File
@@ -39,7 +39,7 @@ Donkey=/kg/donkey
Loderunner=/kg/LRL/LRL,41
; 21days=/kg/21days,104 ;rus only
BabyPainter=/kg/BabyPainter,87
Klavisha=/kg/klavisha/klavisha,69
Klavisha=games/klavisha,69
Millioneer=/kg/WHOWTBAM/whowtbam,114
StarTrek71=/kg/sstartrek/SStarTrek
Descent=games/descent
+1 -1
View File
@@ -243,7 +243,7 @@ x=204
y=0
[22]
name=NETSURF
path=/sys/NETWORK/NETSURF
path=/sys/NETWORK/NSINST
param=
ico=125
x=204
-1
View File
@@ -116,7 +116,6 @@
33 HTTPGet |network/httpget
33 Downloader |network/dl
12 WebView Browser |network/webview
12 NetSurf |network/netsurf
#13 **** SERVERS
24 FTP |network/ftpd
#14 **** OTHER
+1 -1
View File
@@ -243,7 +243,7 @@ x=204
y=0
[22]
name=NETSURF
path=/sys/NETWORK/NETSURF
path=/sys/NETWORK/NSINST
param=
ico=125
x=204
-1
View File
@@ -121,7 +121,6 @@
16 HTTPGet |network/httpget
16 Descargas |network/dl
16 Navegador WebView |network/webview
12 NetSurf |network/netsurf
#15 **** OTROS
16 Reloj analвgico |demos/aclock
16 Reloj binario |demos/bcdclk
+1 -1
View File
@@ -39,7 +39,7 @@ docx=/sys/network/WebView
url=/sys/network/WebView
fb2=/sys/fb2read
mht=/sys/network/WebView
kla=/kolibrios/games/klavisha/klavisha
kla=/sys/games/klavisha
pdf=/kolibrios/media/updf
avi=/kolibrios/media/fplay_run
mpg=/kolibrios/media/fplay_run
+1 -1
View File
@@ -39,7 +39,7 @@ Donkey=/kg/donkey
Loderunner=/kg/LRL/LRL,41
21days=/kg/21days,104 ;rus only
BabyPainter=/kg/BabyPainter,87
Klavisha=/kg/klavisha/klavisha,69
Klavisha=games/klavisha,69
Millioneer=/kg/WHOWTBAM/whowtbam,114
StarTrek71=/kg/sstartrek/SStarTrek
Descent=games/descent
+1 -1
View File
@@ -243,7 +243,7 @@ x=204
y=0
[22]
name=NETSURF
path=/sys/NETWORK/NETSURF
path=/sys/NETWORK/NSINST
param=
ico=125
x=204
+1 -2
View File
@@ -115,7 +115,6 @@
33 HTTPGet |network/httpget
33 Загрузчик |network/dl
12 Браузер WebView |network/webview
12 Браузер NetSurf |network/netsurf
#14 **** Разное
00 Эмуляторы* > |@6
45 Создание скриншотов |scrshoot
@@ -123,7 +122,7 @@
18 FB2 Читалка |fb2read
16 Аналоговые часы |aclock
21 Таблица Менделеева |/kolibrios/utils/period
59 Тренажёр KJIABuIIIA |/kolibrios/games/klavisha/klavisha
59 Тренажёр KJ|ABuIIIA |games/klavisha
16 Бинарные часы |demos/bcdclk
53 Таймер |timer
09 Разархиватор Unz |unz
+13 -11
View File
@@ -515,18 +515,20 @@ HDA_AMP_VOLMASK equ 0x7F
; unsolicited event handler
HDA_UNSOL_QUEUE_SIZE equ 64 ; must stay a power of 2 (used as a bitmask for wrap)
HDA_UNSOL_QUEUE_SIZE equ 64
struc HDA_BUS_UNSOLICITED
{
; ring buffer
.queue rd HDA_UNSOL_QUEUE_SIZE * 2 ; 2 dword for each event (res and res_ex)
.rp dd ? ; Read pointer
.wp dd ? ; Write pointer
; ; workqueue
; .work dd ? ;struct work_struct work;
; .bus dd ? ;struct hda_bus ;bus
}
;struc HDA_BUS_UNSOLICITED
;{
; ; ring buffer
; .queue:
; times HDA_UNSOL_QUEUE_SIZE*2 dd ?
; .rp dd ?
; .wp dd ?
;
; ; workqueue
; .work dd ?;struct work_struct work;
; .bus dd ? ;struct hda_bus ;bus
;};
; Helper for automatic ping configuration
AUTO_PIN_MIC equ 0
+18 -67
View File
@@ -654,15 +654,7 @@ end if
stdcall hda_codec_setup_stream, eax, SDO_TAG, 0, 0x11 ; Left & Right channels (Back panel)
;Asper+ ]
if USE_UNSOL_EV = 0
invoke TimerHS, 1, 0, snd_hda_automute, 1
else
; Keep the unsolicited-event mode on the event-driven path. Running
; snd_hda_automute at startup can issue codec commands before the new
; unsolicited-response flow is ready, which hangs some systems.
invoke TimerHS, 1, 0, process_unsol_events, 0
end if
invoke TimerHS, 1, 0, snd_hda_automute, 0
if USE_SINGLE_MODE
mov esi, msgSingleMode
invoke SysMsgBoardStr
@@ -2643,7 +2635,7 @@ proc snd_hda_automute stdcall, data:dword
test eax, eax
jz .out
stdcall snd_hda_read_pin_sense, edx, [data]
stdcall snd_hda_read_pin_sense, edx, 1
test eax, AC_PINSENSE_PRESENCE
jnz @f
xchg ecx, esi
@@ -2672,64 +2664,24 @@ proc snd_hda_automute stdcall, data:dword
endp
; ;Asper remember to add this functions:
; proc snd_hda_queue_unsol_event stdcall, par1:dword, par2:dword
; ;if DEBUG
; ; push esi
; ; mov esi, msgUnsolEvent
; ; invoke SysMsgBoardStr
; ; pop esi
; ;end if
; if USE_UNSOL_EV = 1
; ;Test. Do not make queue, process immediately!
; ;stdcall here snd_hda_read_pin_sense stdcall, nid:dword, trigger_sense:dword
; ;and then mute/unmute pin based on the results
; invoke TimerHS, 1, 0, snd_hda_automute, 0
; end if
; ret
; endp
; ;...
align 4
proc snd_hda_queue_unsol_event stdcall, res:dword, res_ex:dword
; Single-producer (HDA IRQ) lock-free enqueue. The caller azx_update_rirb
; only carries EBX across iterations and reloads the rest, and TimerHS
; preserves EBX too - so by using scratch regs only we need no saves.
mov eax, [unsol_events.wp]
lea edx, [eax+1]
and edx, HDA_UNSOL_QUEUE_SIZE - 1 ; next write pos (size must be 2^n)
cmp edx, [unsol_events.rp]
je .full ; ring full -> drop, keep 1 slot free
mov ecx, [res]
mov [unsol_events.queue + eax*8], ecx
mov ecx, [res_ex]
mov [unsol_events.queue + eax*8 + 4], ecx
mov [unsol_events.wp], edx ; publish only after data is stored
invoke TimerHS, 1, 0, process_unsol_events, 0
.full:
ret
;Asper remember to add this functions:
proc snd_hda_queue_unsol_event stdcall, par1:dword, par2:dword
;if DEBUG
; push esi
; mov esi, msgUnsolEvent
; invoke SysMsgBoardStr
; pop esi
;end if
if USE_UNSOL_EV = 1
;Test. Do not make queue, process immediately!
;stdcall here snd_hda_read_pin_sense stdcall, nid:dword, trigger_sense:dword
;and then mute/unmute pin based on the results
invoke TimerHS, 1, 0, snd_hda_automute, 0
end if
ret
endp
;...
align 4
proc process_unsol_events stdcall, data:dword
; Runs from TimerHS (single consumer). Uses only EAX (scratch) and calls
; snd_hda_automute, which preserves every register, so nothing is saved.
.loop:
mov eax, [unsol_events.rp]
cmp eax, [unsol_events.wp]
je .done
; The event payload is at [unsol_events.queue + eax*8] (res) and +4 (res_ex).
; Per-pin tag parsing is not implemented yet, so just re-evaluate jack state.
inc eax
and eax, HDA_UNSOL_QUEUE_SIZE - 1
mov [unsol_events.rp], eax
stdcall snd_hda_automute, 0
jmp .loop
.done:
ret
endp
align 4
proc fdword2str stdcall, flags:dword ; bit 0 - skipLeadZeroes; bit 1 - newLine; other bits undefined
@@ -3105,7 +3057,6 @@ aspinlock dd SPINLOCK_FREE
codec CODEC
ctrl AC_CNTRL
unsol_events HDA_BUS_UNSOLICITED
;Asper: BDL must be aligned to 128 according to HDA specification.
pcmout_bdl rd 1
-68
View File
@@ -1,68 +0,0 @@
#ifndef _ACPI_ACPI_H
#define _ACPI_ACPI_H
/*
* Minimal ACPI-CA type surface for KolibriOS.
*
* CONFIG_ACPI is never defined here, so <linux/acpi.h> compiles only its
* "no ACPI" branch - but that branch still mentions a handful of ACPI-CA
* types in the signatures of its inline stubs. Those types are what this
* header provides; there is no ACPI interpreter behind them.
*/
#include <linux/types.h>
typedef u32 acpi_status;
typedef u32 acpi_object_type;
typedef u64 acpi_size;
typedef u64 acpi_io_address;
typedef u64 acpi_physical_address;
typedef void *acpi_handle;
typedef char *acpi_string;
#define AE_OK ((acpi_status) 0x0000)
#define AE_ERROR ((acpi_status) 0x0001)
#define AE_NOT_FOUND ((acpi_status) 0x0005)
#define AE_SUPPORT ((acpi_status) 0x001D)
#define ACPI_SUCCESS(a) ((a) == AE_OK)
#define ACPI_FAILURE(a) ((a) != AE_OK)
#define ACPI_TYPE_INTEGER 0x01
#define ACPI_TYPE_STRING 0x02
#define ACPI_TYPE_BUFFER 0x03
#define ACPI_TYPE_PACKAGE 0x04
#define ACPI_TYPE_ANY 0x00
union acpi_object {
acpi_object_type type;
struct {
acpi_object_type type;
u64 value;
} integer;
struct {
acpi_object_type type;
u32 length;
char *pointer;
} string;
struct {
acpi_object_type type;
u32 length;
u8 *pointer;
} buffer;
struct {
acpi_object_type type;
u32 count;
union acpi_object *elements;
} package;
};
struct acpi_buffer {
acpi_size length;
void *pointer;
};
struct acpi_object_list {
u32 count;
union acpi_object *pointer;
};
#endif /* _ACPI_ACPI_H */
-13
View File
@@ -1,13 +0,0 @@
#ifndef ACPI_BUTTON_H
#define ACPI_BUTTON_H
#include <linux/errno.h>
#include <linux/notifier.h>
/*
* nouveau_connector.c asks the ACPI lid device whether the panel is open
* before trusting an LVDS hotplug. No ACPI here, so report "open" - the same
* answer the upstream !CONFIG_ACPI_BUTTON stub gives.
*/
static inline int acpi_lid_open(void) { return 1; }
static inline int acpi_lid_notifier_register(struct notifier_block *nb) { return -ENODEV; }
static inline int acpi_lid_notifier_unregister(struct notifier_block *nb) { return -ENODEV; }
#endif
-40
View File
@@ -1,40 +0,0 @@
#ifndef _ACPI_PDC_INTEL_H
#define _ACPI_PDC_INTEL_H
/*
* Intel _PDC / _OSC capability bits, included unconditionally by <asm/acpi.h>.
*
* Nothing here evaluates these - KolibriOS drivers never negotiate processor
* capabilities with the firmware - but the definitions have to exist for
* <linux/acpi.h> to be includable at all. Values match the kernel's
* include/acpi/pdc_intel.h.
*/
#define ACPI_PDC_P_FFH (0x0001)
#define ACPI_PDC_C_C1_HALT (0x0002)
#define ACPI_PDC_T_FFH (0x0004)
#define ACPI_PDC_SMP_C1PT (0x0008)
#define ACPI_PDC_SMP_C2C3 (0x0010)
#define ACPI_PDC_SMP_P_SWCOORD (0x0020)
#define ACPI_PDC_SMP_C_SWCOORD (0x0040)
#define ACPI_PDC_SMP_T_SWCOORD (0x0080)
#define ACPI_PDC_C_C1_FFH (0x0100)
#define ACPI_PDC_C_C2C3_FFH (0x0200)
#define ACPI_PDC_SMP_P_HWCOORD (0x0800)
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \
ACPI_PDC_P_FFH)
#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \
ACPI_PDC_SMP_P_SWCOORD | \
ACPI_PDC_SMP_P_HWCOORD | \
ACPI_PDC_P_FFH)
#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \
ACPI_PDC_C_C1_FFH | \
ACPI_PDC_C_C2C3_FFH)
#endif /* _ACPI_PDC_INTEL_H */
-18
View File
@@ -1,18 +0,0 @@
#ifndef __ACPI_VIDEO_H
#define __ACPI_VIDEO_H
/* No ACPI video extensions; nouveau_display.c only calls the register hook. */
#include <linux/errno.h>
enum acpi_backlight_type {
acpi_backlight_undef = -1,
acpi_backlight_none = 0,
acpi_backlight_video,
acpi_backlight_vendor,
acpi_backlight_native,
};
static inline int acpi_video_register(void) { return -ENODEV; }
static inline void acpi_video_unregister(void) { }
static inline enum acpi_backlight_type acpi_video_get_backlight_type(void)
{ return acpi_backlight_vendor; }
#endif
@@ -85,9 +85,6 @@ dma_supported(struct device *dev, u64 mask);
extern int
dma_set_mask(struct device *dev, u64 mask);
extern int
dma_set_coherent_mask(struct device *dev, u64 mask);
extern int
dma_get_cache_alignment(void);
-12
View File
@@ -315,18 +315,6 @@ extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
#define IO_SPACE_LIMIT 0xffff
/*
* Write-combining range management. Upstream declares these under
* CONFIG_MTRR and provides !MTRR fallbacks from <linux/io.h>, which this tree
* does not carry - so they are declared unconditionally here and implemented
* as no-ops by each driver's kos_io.c. arch_io_*_memtype_wc() is the 4.9
* spelling that came in with the PAT rework.
*/
extern int __must_check arch_phys_wc_add(unsigned long base, unsigned long size);
extern void arch_phys_wc_del(int handle);
extern int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size);
extern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size);
#ifdef CONFIG_MTRR
extern int __must_check arch_phys_wc_index(int handle);
#define arch_phys_wc_index arch_phys_wc_index
-30
View File
@@ -359,13 +359,6 @@ struct drm_file {
int event_space;
struct mutex event_read_lock;
/*
* Upstream stores the opening process here. Nothing opens a DRM node
* on this port, so it stays NULL; nouveau_drm.c only feeds it to
* pid_nr() when it names a client.
*/
struct pid *pid;
};
/**
@@ -685,14 +678,6 @@ struct drm_device {
/*@} */
struct list_head filelist;
/*
* Backported from Linux 4.9, which moved filelist from under
* struct_mutex to its own lock. Nothing in the 4.6 core takes it, so
* it only ever serialises the driver against itself.
*/
struct mutex filelist_mutex;
/* Backported from Linux 4.9; unused without a real inode layer. */
struct inode *anon_inode;
/** \name Memory management */
/*@{ */
@@ -763,12 +748,6 @@ struct drm_device {
// struct drm_agp_head *agp; /**< AGP data */
struct pci_dev *pdev; /**< PCI device structure */
/*
* Always NULL here - no platform bus. nouveau_drm.c branches on
* pdev vs platformdev when it builds the device name, and the
* Tegra half of that branch is never taken.
*/
struct platform_device *platformdev;
#ifdef __alpha__
struct pci_controller *hose;
#endif
@@ -1002,15 +981,6 @@ static __inline__ int drm_pci_device_is_agp(struct drm_device *dev)
}
void drm_pci_agp_destroy(struct drm_device *dev);
/*
* Implemented in drm_pci.c and the entry point every port's probe calls, but
* its upstream declaration is in the "#if 0" block below - so each main.c used
* to declare it by hand. Declared here instead.
*/
extern int drm_get_pci_dev(struct pci_dev *pdev,
const struct pci_device_id *ent,
struct drm_driver *driver);
#if 0
extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
-27
View File
@@ -152,13 +152,6 @@ struct drm_display_info {
u8 edid_hdmi_dc_modes;
u8 cea_rev;
/*
* Backported from Linux 4.9: maximum TMDS clock in kHz advertised by an
* HDMI sink. drm_edid.c in this tree does not fill it in yet, so it
* stays 0 and drivers fall back to their built-in limit.
*/
int max_tmds_clock;
};
/* data corresponds to displayid vend/prod/serial */
@@ -708,17 +701,6 @@ struct drm_crtc_funcs {
const struct drm_crtc_state *state,
struct drm_property *property,
uint64_t *val);
/*
* Backported from Linux 4.9 for the amdgpu port. The 4.6 DRM core in
* this tree never calls these; they exist so that drivers written
* against the newer struct layout still compile and keep their hooks.
*/
void (*early_unregister)(struct drm_crtc *crtc);
int (*page_flip_target)(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t flags, uint32_t target);
};
/**
@@ -1062,9 +1044,6 @@ struct drm_connector_funcs {
const struct drm_connector_state *state,
struct drm_property *property,
uint64_t *val);
/* Backported from Linux 4.9 - see drm_crtc_funcs::early_unregister. */
void (*early_unregister)(struct drm_connector *connector);
};
/**
@@ -1090,9 +1069,6 @@ struct drm_encoder_funcs {
* hotplugged in DRM.
*/
void (*destroy)(struct drm_encoder *encoder);
/* Backported from Linux 4.9 - see drm_crtc_funcs::early_unregister. */
void (*early_unregister)(struct drm_encoder *encoder);
};
#define DRM_CONNECTOR_MAX_ENCODER 3
@@ -1514,9 +1490,6 @@ struct drm_plane_funcs {
const struct drm_plane_state *state,
struct drm_property *property,
uint64_t *val);
/* Backported from Linux 4.9 - see drm_crtc_funcs::early_unregister. */
void (*early_unregister)(struct drm_plane *plane);
};
enum drm_plane_type {
-9
View File
@@ -43,15 +43,6 @@
#include <drm/drm_modeset_helper_vtables.h>
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
/*
* Added after 4.6 and implemented by each port's kos_stubs.c:
* drm_crtc_force_disable_all() is 4.9's unload-time "turn everything off",
* and drm_kms_helper_is_poll_worker() is how 4.9 avoids deadlocking against
* its own hotplug worker - there is no such worker here.
*/
extern void drm_crtc_force_disable_all(struct drm_device *dev);
extern bool drm_kms_helper_is_poll_worker(void);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode,
-182
View File
@@ -1,182 +0,0 @@
/*
* Copyright (C) 2009 Francisco Jerez.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __DRM_ENCODER_SLAVE_H__
#define __DRM_ENCODER_SLAVE_H__
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
/**
* struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver
* @set_config: Initialize any encoder-specific modesetting parameters.
* The meaning of the @params parameter is implementation
* dependent. It will usually be a structure with DVO port
* data format settings or timings. It's not required for
* the new parameters to take effect until the next mode
* is set.
*
* Most of its members are analogous to the function pointers in
* &drm_encoder_helper_funcs and they can optionally be used to
* initialize the latter. Connector-like methods (e.g. @get_modes and
* @set_property) will typically be wrapped around and only be called
* if the encoder is the currently selected one for the connector.
*/
struct drm_encoder_slave_funcs {
void (*set_config)(struct drm_encoder *encoder,
void *params);
void (*destroy)(struct drm_encoder *encoder);
void (*dpms)(struct drm_encoder *encoder, int mode);
void (*save)(struct drm_encoder *encoder);
void (*restore)(struct drm_encoder *encoder);
bool (*mode_fixup)(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
int (*mode_valid)(struct drm_encoder *encoder,
struct drm_display_mode *mode);
void (*mode_set)(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
enum drm_connector_status (*detect)(struct drm_encoder *encoder,
struct drm_connector *connector);
int (*get_modes)(struct drm_encoder *encoder,
struct drm_connector *connector);
int (*create_resources)(struct drm_encoder *encoder,
struct drm_connector *connector);
int (*set_property)(struct drm_encoder *encoder,
struct drm_connector *connector,
struct drm_property *property,
uint64_t val);
};
/**
* struct drm_encoder_slave - Slave encoder struct
* @base: DRM encoder object.
* @slave_funcs: Slave encoder callbacks.
* @slave_priv: Slave encoder private data.
* @bus_priv: Bus specific data.
*
* A &drm_encoder_slave has two sets of callbacks, @slave_funcs and the
* ones in @base. The former are never actually called by the common
* CRTC code, it's just a convenience for splitting the encoder
* functions in an upper, GPU-specific layer and a (hopefully)
* GPU-agnostic lower layer: It's the GPU driver responsibility to
* call the slave methods when appropriate.
*
* drm_i2c_encoder_init() provides a way to get an implementation of
* this.
*/
struct drm_encoder_slave {
struct drm_encoder base;
const struct drm_encoder_slave_funcs *slave_funcs;
void *slave_priv;
void *bus_priv;
};
#define to_encoder_slave(x) container_of((x), struct drm_encoder_slave, base)
int drm_i2c_encoder_init(struct drm_device *dev,
struct drm_encoder_slave *encoder,
struct i2c_adapter *adap,
const struct i2c_board_info *info);
/**
* struct drm_i2c_encoder_driver
*
* Describes a device driver for an encoder connected to the GPU
* through an I2C bus. In addition to the entry points in @i2c_driver
* an @encoder_init function should be provided. It will be called to
* give the driver an opportunity to allocate any per-encoder data
* structures and to initialize the @slave_funcs and (optionally)
* @slave_priv members of @encoder.
*/
struct drm_i2c_encoder_driver {
struct i2c_driver i2c_driver;
int (*encoder_init)(struct i2c_client *client,
struct drm_device *dev,
struct drm_encoder_slave *encoder);
};
#define to_drm_i2c_encoder_driver(x) container_of((x), \
struct drm_i2c_encoder_driver, \
i2c_driver)
/**
* drm_i2c_encoder_get_client - Get the I2C client corresponding to an encoder
*/
static inline struct i2c_client *drm_i2c_encoder_get_client(struct drm_encoder *encoder)
{
return (struct i2c_client *)to_encoder_slave(encoder)->bus_priv;
}
/**
* drm_i2c_encoder_register - Register an I2C encoder driver
* @owner: Module containing the driver.
* @driver: Driver to be registered.
*/
static inline int drm_i2c_encoder_register(struct module *owner,
struct drm_i2c_encoder_driver *driver)
{
return i2c_register_driver(owner, &driver->i2c_driver);
}
/**
* drm_i2c_encoder_unregister - Unregister an I2C encoder driver
* @driver: Driver to be unregistered.
*/
static inline void drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver *driver)
{
i2c_del_driver(&driver->i2c_driver);
}
void drm_i2c_encoder_destroy(struct drm_encoder *encoder);
/*
* Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
*/
void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode);
bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void drm_i2c_encoder_prepare(struct drm_encoder *encoder);
void drm_i2c_encoder_commit(struct drm_encoder *encoder);
void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
struct drm_connector *connector);
void drm_i2c_encoder_save(struct drm_encoder *encoder);
void drm_i2c_encoder_restore(struct drm_encoder *encoder);
#endif
-8
View File
@@ -226,14 +226,6 @@ int drm_fb_helper_init(struct drm_device *dev,
struct drm_fb_helper *helper, int crtc_count,
int max_conn);
void drm_fb_helper_fini(struct drm_fb_helper *helper);
/*
* 4.9's fbdev handover. There is no other framebuffer driver to evict on
* KolibriOS; implemented in each port's kos_stubs.c.
*/
struct apertures_struct;
int drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a,
const char *name, bool primary);
int drm_fb_helper_blank(int blank, struct fb_info *info);
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
-10
View File
@@ -1,10 +0,0 @@
#ifndef _DRM_FOURCC_SHIM_H
#define _DRM_FOURCC_SHIM_H
/*
* The tree keeps the format list in uapi/ and the in-kernel helpers in
* drm_crtc.h. Upstream drivers include <drm/drm_fourcc.h>; give them that
* spelling instead of patching every call site. The guard is deliberately
* distinct from the uapi header's own.
*/
#include <uapi/drm/drm_fourcc.h>
#endif
-9
View File
@@ -1,9 +0,0 @@
#ifndef _DRM_MODE_SHIM_H
#define _DRM_MODE_SHIM_H
/*
* Same reason as drm_fourcc.h: upstream drivers spell this <drm/drm_mode.h>
* while the tree keeps it under uapi/. The guard deliberately does not match
* the uapi header's own _DRM_MODE_H, or including this first would suppress it.
*/
#include <uapi/drm/drm_mode.h>
#endif
-86
View File
@@ -1,86 +0,0 @@
/*
* Copyright (C) 2009 Francisco Jerez.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __DRM_I2C_CH7006_H__
#define __DRM_I2C_CH7006_H__
/**
* struct ch7006_encoder_params
*
* Describes how the ch7006 is wired up with the GPU. It should be
* used as the @params parameter of its @set_config method.
*
* See "http://www.chrontel.com/pdf/7006.pdf" for their precise
* meaning.
*/
struct ch7006_encoder_params {
enum {
CH7006_FORMAT_RGB16 = 0,
CH7006_FORMAT_YCrCb24m16,
CH7006_FORMAT_RGB24m16,
CH7006_FORMAT_RGB15,
CH7006_FORMAT_RGB24m12C,
CH7006_FORMAT_RGB24m12I,
CH7006_FORMAT_RGB24m8,
CH7006_FORMAT_RGB16m8,
CH7006_FORMAT_RGB15m8,
CH7006_FORMAT_YCrCb24m8,
} input_format;
enum {
CH7006_CLOCK_SLAVE = 0,
CH7006_CLOCK_MASTER,
} clock_mode;
enum {
CH7006_CLOCK_EDGE_NEG = 0,
CH7006_CLOCK_EDGE_POS,
} clock_edge;
int xcm, pcm;
enum {
CH7006_SYNC_SLAVE = 0,
CH7006_SYNC_MASTER,
} sync_direction;
enum {
CH7006_SYNC_SEPARATED = 0,
CH7006_SYNC_EMBEDDED,
} sync_encoding;
enum {
CH7006_POUT_1_8V = 0,
CH7006_POUT_3_3V,
} pout_level;
enum {
CH7006_ACTIVE_HSYNC = 0,
CH7006_ACTIVE_DSTART,
} active_detect;
};
#endif
-63
View File
@@ -1,63 +0,0 @@
/*
* Copyright (C) 2010 Francisco Jerez.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __DRM_I2C_SIL164_H__
#define __DRM_I2C_SIL164_H__
/**
* struct sil164_encoder_params
*
* Describes how the sil164 is connected to the GPU. It should be used
* as the @params parameter of its @set_config method.
*
* See "http://www.siliconimage.com/docs/SiI-DS-0021-E-164.pdf".
*/
struct sil164_encoder_params {
enum {
SIL164_INPUT_EDGE_FALLING = 0,
SIL164_INPUT_EDGE_RISING
} input_edge;
enum {
SIL164_INPUT_WIDTH_12BIT = 0,
SIL164_INPUT_WIDTH_24BIT
} input_width;
enum {
SIL164_INPUT_SINGLE_EDGE = 0,
SIL164_INPUT_DUAL_EDGE
} input_dual;
enum {
SIL164_PLL_FILTER_ON = 0,
SIL164_PLL_FILTER_OFF,
} pll_filter;
int input_skew; /** < Allowed range [-4, 3], use 0 for no de-skew. */
int duallink_skew; /** < Allowed range [-4, 3]. */
};
#endif
-9
View File
@@ -257,15 +257,6 @@ struct ttm_buffer_object {
struct reservation_object *resv;
struct reservation_object ttm_resv;
struct mutex wu_mutex;
/*
* Backported from Linux 4.9: fence of the last accelerated move, kept
* outside the reservation object so a pipelined eviction can be waited
* on without blocking other users. The 4.6 TTM in this tree still
* waits synchronously, so the core leaves this NULL; amdgpu sets and
* checks it on its own paths.
*/
struct fence *moving;
};
/**
-12
View File
@@ -434,20 +434,8 @@ struct ttm_bo_driver {
*/
int (*io_mem_reserve)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
void (*io_mem_free)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
/*
* Backported from Linux 4.9 for the amdgpu port. The 4.6 TTM in this
* tree does not consult these hooks - it always uses the default LRU
* placement - but drivers written against 4.9 still populate them.
*/
void (*lru_removal)(struct ttm_buffer_object *bo);
struct list_head *(*lru_tail)(struct ttm_buffer_object *bo);
struct list_head *(*swap_lru_tail)(struct ttm_buffer_object *bo);
};
struct list_head *ttm_bo_default_lru_tail(struct ttm_buffer_object *bo);
struct list_head *ttm_bo_default_swap_lru_tail(struct ttm_buffer_object *bo);
/**
* struct ttm_bo_global_ref - Argument to initialize a struct ttm_bo_global.
*/
-21
View File
@@ -1,21 +0,0 @@
#ifndef _LINUX_CLK_H
#define _LINUX_CLK_H
/*
* Tegra-only. nvif/os.h pulls this in unconditionally, but the only nouveau
* code that calls a clk_* helper is nvkm/engine/device/tegra.c, which this
* port does not build.
*/
#include <linux/errno.h>
#include <linux/err.h>
struct clk;
struct device;
static inline struct clk *clk_get(struct device *dev, const char *id)
{ return ERR_PTR(-ENOENT); }
static inline void clk_put(struct clk *clk) { }
static inline int clk_prepare_enable(struct clk *clk) { return -ENOSYS; }
static inline void clk_disable_unprepare(struct clk *clk) { }
static inline unsigned long clk_get_rate(struct clk *clk) { return 0; }
static inline int clk_set_rate(struct clk *clk, unsigned long rate) { return -ENOSYS; }
#endif
-14
View File
@@ -1,14 +0,0 @@
#ifndef _LINUX_CONSOLE_H
#define _LINUX_CONSOLE_H
/* KolibriOS has no VT console layer; the fbdev handover hooks are no-ops. */
#define CON_PRINTBUFFER (1)
#define CON_CONSDEV (2)
#define CON_ENABLED (4)
#define CON_BOOT (8)
#define CON_ANYTIME (16)
#define CON_BRL (32)
static inline void console_lock(void) { }
static inline void console_unlock(void) { }
static inline int console_trylock(void) { return 1; }
#endif
-7
View File
@@ -1,7 +0,0 @@
#ifndef _LINUX_DEBUGFS_H
#define _LINUX_DEBUGFS_H
/* No debugfs in KolibriOS - CONFIG_DEBUG_FS is never defined. */
#include <linux/types.h>
struct dentry;
struct file_operations;
#endif
-29
View File
@@ -31,12 +31,6 @@ enum probe_type {
struct device_driver {
const char *name;
/*
* Restored for drm_encoder_slave.c, which pins the slave encoder's
* module around a bind. Nothing is ever bound on this port, so it
* stays NULL and try_module_get()/module_put() are no-ops.
*/
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
@@ -132,28 +126,5 @@ static inline __printf(2, 3)
void dev_notice(const struct device *dev, const char *fmt, ...)
{}
/*
* sysfs attribute types. KolibriOS has no sysfs, so nothing ever walks these
* tables - but drivers still declare them at file scope, so the layout has to
* exist. Matches the upstream definitions field for field.
*/
#include <linux/sysfs.h>
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
#define __ATTR(_name, _mode, _show, _store) { \
.attr = { .name = __stringify(_name), .mode = (_mode) }, \
.show = _show, \
.store = _store, \
}
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
#endif /* _DEVICE_H_ */
-6
View File
@@ -131,12 +131,6 @@ struct dma_buf {
const char *exp_name;
struct list_head list_node;
void *priv;
/*
* Upstream keeps the exporter's reservation object here. No dma-buf
* is ever created on this port, so nouveau_prime.c's import path is
* dead code - but it dereferences the field, so it has to exist.
*/
struct reservation_object *resv;
};
/**
-7
View File
@@ -1,7 +0,0 @@
#ifndef _LINUX_EFI_H
#define _LINUX_EFI_H
/* KolibriOS boots via BIOS only; amdgpu only tests efi_enabled(). */
#define EFI_BOOT 0
#define EFI_RUNTIME_SERVICES 1
static inline bool efi_enabled(int feature) { return false; }
#endif
+1 -6
View File
@@ -470,12 +470,7 @@ struct fb_info {
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
// struct work_struct queue; /* Framebuffer event queue */
/*
* Restored for nouveau, which sets pixmap.buf_align after
* drm_fb_helper_initial_config(). Nothing on this port consumes the
* field - there is no fbcon - but the assignment has to compile.
*/
struct fb_pixmap pixmap; /* Image hardware mapper */
// struct fb_pixmap pixmap; /* Image hardware mapper */
// struct fb_pixmap sprite; /* Cursor hardware mapper */
// struct fb_cmap cmap; /* Current cmap */
struct list_head modelist; /* mode list */
-83
View File
@@ -1,83 +0,0 @@
/*
* fence-array: aggregates fence to be waited together
*
* Copyright (C) 2016 Collabora Ltd
* Copyright (C) 2016 Advanced Micro Devices, Inc.
* Authors:
* Gustavo Padovan <gustavo@padovan.org>
* Christian König <christian.koenig@amd.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __LINUX_FENCE_ARRAY_H
#define __LINUX_FENCE_ARRAY_H
#include <linux/fence.h>
/**
* struct fence_array_cb - callback helper for fence array
* @cb: fence callback structure for signaling
* @array: reference to the parent fence array object
*/
struct fence_array_cb {
struct fence_cb cb;
struct fence_array *array;
};
/**
* struct fence_array - fence to represent an array of fences
* @base: fence base class
* @lock: spinlock for fence handling
* @num_fences: number of fences in the array
* @num_pending: fences in the array still pending
* @fences: array of the fences
*/
struct fence_array {
struct fence base;
spinlock_t lock;
unsigned num_fences;
atomic_t num_pending;
struct fence **fences;
};
extern const struct fence_ops fence_array_ops;
/**
* fence_is_array - check if a fence is from the array subsclass
*
* Return true if it is a fence_array and false otherwise.
*/
static inline bool fence_is_array(struct fence *fence)
{
return fence->ops == &fence_array_ops;
}
/**
* to_fence_array - cast a fence to a fence_array
* @fence: fence to cast to a fence_array
*
* Returns NULL if the fence is not a fence_array,
* or the fence_array otherwise.
*/
static inline struct fence_array *to_fence_array(struct fence *fence)
{
if (fence->ops != &fence_array_ops)
return NULL;
return container_of(fence, struct fence_array, base);
}
struct fence_array *fence_array_create(int num_fences, struct fence **fences,
u64 context, unsigned seqno,
bool signal_on_any);
#endif /* __LINUX_FENCE_ARRAY_H */
-35
View File
@@ -1,35 +0,0 @@
#ifndef _LINUX_HRTIMER_H
#define _LINUX_HRTIMER_H
/*
* amdgpu_mode.h only embeds a struct hrtimer in the virtual-DCE crtc and never
* arms it on this port, so a structural stub is enough.
*/
#include <linux/types.h>
#include <linux/ktime.h>
enum hrtimer_restart { HRTIMER_NORESTART, HRTIMER_RESTART };
enum hrtimer_mode {
HRTIMER_MODE_ABS = 0x0,
HRTIMER_MODE_REL = 0x1,
HRTIMER_MODE_PINNED = 0x2,
};
enum hrtimer_base_type { HRTIMER_BASE_MONOTONIC, HRTIMER_MAX_CLOCK_BASES };
struct hrtimer {
ktime_t _softexpires;
enum hrtimer_restart (*function)(struct hrtimer *);
int state;
};
static inline void hrtimer_init(struct hrtimer *timer, int which, enum hrtimer_mode mode)
{ timer->function = NULL; timer->state = 0; }
static inline int hrtimer_start(struct hrtimer *t, ktime_t tim, enum hrtimer_mode m) { return 0; }
static inline int hrtimer_cancel(struct hrtimer *t) { return 0; }
static inline int hrtimer_try_to_cancel(struct hrtimer *t) { return 0; }
static inline bool hrtimer_active(const struct hrtimer *t) { return false; }
static inline void hrtimer_start_range_ns(struct hrtimer *t, ktime_t tim,
u64 range_ns, enum hrtimer_mode m) { }
/* Sleeps through the DDK's delay(); see the driver's kos_* glue. */
extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
#endif
-27
View File
@@ -1,27 +0,0 @@
#ifndef _LINUX_HWMON_SYSFS_H
#define _LINUX_HWMON_SYSFS_H
/* sysfs is absent; amdgpu_pm.c's hwmon attributes are compiled out to stubs. */
#include <linux/device.h>
struct sensor_device_attribute {
struct device_attribute dev_attr;
int index;
};
#define to_sensor_dev_attr(_dev_attr) \
container_of(_dev_attr, struct sensor_device_attribute, dev_attr)
#define SENSOR_ATTR(_name, _mode, _show, _store, _index) \
{ .dev_attr = __ATTR(_name, _mode, _show, _store), .index = _index }
#define SENSOR_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
struct sensor_device_attribute sensor_dev_attr_##_name = \
SENSOR_ATTR(_name, _mode, _show, _store, _index)
struct sensor_device_attribute_2 {
struct device_attribute dev_attr;
u8 index;
u8 nr;
};
#define to_sensor_dev_attr_2(_dev_attr) \
container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr)
#endif
+2 -22
View File
@@ -52,19 +52,6 @@ struct i2c_board_info;
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
/*
* Declared here rather than left implicit: i2c-core.c defines them, and
* nouveau reaches all three - i2c_new_device()/i2c_unregister_device() from
* nvkm/subdev/therm/ic.c, i2c_register_driver() through the i2c_add_driver()
* inline below.
*/
struct module;
extern int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
extern void i2c_del_driver(struct i2c_driver *driver);
extern struct i2c_client *i2c_new_device(struct i2c_adapter *adap,
struct i2c_board_info const *info);
extern void i2c_unregister_device(struct i2c_client *client);
/**
* struct i2c_driver - represent an I2C device driver
* @class: What kind of i2c device we instantiate (for detect)
@@ -127,18 +114,11 @@ struct i2c_driver {
*/
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
/*
* Restored for nouveau: nvkm/subdev/therm/ic.c reaches the bound
* driver through to_i2c_driver(client->dev.driver)->detect(). There
* is no driver-model binding on this port, so dev.driver is always
* NULL and the probe short-circuits - but the fields have to exist
* for to_i2c_driver() to compile.
*/
struct device_driver driver;
// struct device_driver driver;
const struct i2c_device_id *id_table;
/* Device detection callback for automatic device creation */
int (*detect)(struct i2c_client *, struct i2c_board_info *);
// int (*detect)(struct i2c_client *, struct i2c_board_info *);
const unsigned short *address_list;
struct list_head clients;
};
-12
View File
@@ -5,18 +5,6 @@
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/irqreturn.h>
/*
* Taking an interrupt outside drm_irq_install(). nouveau's nvkm_pci_init()
* does exactly that, so the driver supplies request_irq()/free_irq() over
* AttachIntHandler(); the signatures are upstream's.
*/
typedef irqreturn_t (*irq_handler_t)(int irq, void *dev_id);
extern int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev_id);
extern void free_irq(unsigned int irq, void *dev_id);
#include <linux/kref.h>
#include <linux/atomic.h>
/*
-37
View File
@@ -1,37 +0,0 @@
#ifndef _LINUX_IOMMU_H
#define _LINUX_IOMMU_H
/*
* No IOMMU on this port. nvif/os.h includes it unconditionally; the only user
* is the Tegra SMMU path in nvkm/engine/device/tegra.c, which is not built.
*/
#include <linux/errno.h>
#include <linux/types.h>
#define IOMMU_READ (1 << 0)
#define IOMMU_WRITE (1 << 1)
#define IOMMU_CACHE (1 << 2)
struct device;
struct iommu_domain;
struct iommu_group;
struct iommu_domain_geometry {
dma_addr_t aperture_start;
dma_addr_t aperture_end;
bool force_aperture;
};
static inline struct iommu_domain *iommu_domain_alloc(void *bus) { return NULL; }
static inline void iommu_domain_free(struct iommu_domain *d) { }
static inline int iommu_attach_device(struct iommu_domain *d, struct device *dev)
{ return -ENODEV; }
static inline void iommu_detach_device(struct iommu_domain *d, struct device *dev) { }
static inline struct iommu_group *iommu_group_get(struct device *dev) { return NULL; }
static inline int iommu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
{ return -ENODEV; }
static inline size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
size_t size)
{ return 0; }
static inline void iommu_group_put(struct iommu_group *g) { }
#endif
-27
View File
@@ -1,27 +0,0 @@
#ifndef _LINUX_IRQ_H
#define _LINUX_IRQ_H
/*
* KolibriOS has no irq_domain layer. amdgpu_irq.c is patched to dispatch IH
* ring entries straight to the registered amdgpu_irq_src, so only the types it
* still mentions need to exist.
*/
#include <linux/types.h>
struct irq_data {
unsigned int irq;
unsigned long hwirq;
void *chip_data;
};
struct irq_chip {
const char *name;
void (*irq_mask)(struct irq_data *data);
void (*irq_unmask)(struct irq_data *data);
};
static inline void *irq_data_get_irq_chip_data(struct irq_data *d)
{
return d ? d->chip_data : NULL;
}
static inline void handle_simple_irq(void) { }
#endif
-41
View File
@@ -1,41 +0,0 @@
#ifndef _LINUX_IRQDOMAIN_H
#define _LINUX_IRQDOMAIN_H
/*
* KolibriOS has no irq domain layer.
*
* amdgpu builds a linear domain purely so that a *different* driver (the ACP
* audio co-processor) can receive GPU interrupts by Linux irq number. ACP is
* not part of this port, so no mapping is ever created: adev->irq.virq[] stays
* zero and amdgpu_irq_dispatch() always takes its direct-call branch.
*
* These declarations therefore exist to keep the domain setup compiling and
* succeeding; the implementations in the driver's kos_stubs.c do nothing.
*/
#include <linux/types.h>
#include <linux/irq.h>
typedef unsigned long irq_hw_number_t;
struct irq_domain;
struct device_node;
struct irq_domain_ops {
int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
void (*unmap)(struct irq_domain *d, unsigned int virq);
int (*xlate)(struct irq_domain *d, struct device_node *node,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type);
};
struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
unsigned int size,
const struct irq_domain_ops *ops,
void *host_data);
void irq_domain_remove(struct irq_domain *domain);
unsigned int irq_create_mapping(struct irq_domain *domain, irq_hw_number_t hwirq);
unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq);
int generic_handle_irq(unsigned int irq);
void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *chip,
void (*handle)(void));
#endif /* _LINUX_IRQDOMAIN_H */
+1 -33
View File
@@ -684,20 +684,7 @@ typedef union
u64 raw;
}evhandle_t;
/*
* KolibriOS has no user address space that drivers can map into, so these are
* placeholders. The fields exist because the mmap/userptr entry points of the
* ported DRM drivers reference them; those paths are never reached, since no
* ioctl surface is exposed to user code.
*/
struct vm_area_struct {
unsigned long vm_start;
unsigned long vm_end;
unsigned long vm_pgoff;
unsigned long vm_flags;
struct file *vm_file;
void *vm_private_data;
};
struct vm_area_struct {};
struct address_space {};
#define in_dbg_master() (0)
@@ -744,13 +731,6 @@ int del_timer(struct timer_list *timer);
#define mmiowb() barrier()
/* String-to-integer conversions; each driver's kos_kernel.c implements them. */
extern int kstrtol(const char *s, unsigned int base, long *res);
extern int kstrtoul(const char *s, unsigned int base, unsigned long *res);
extern int kstrtoint(const char *s, unsigned int base, int *res);
extern int kstrtou32(const char *s, unsigned int base, u32 *res);
#define dev_err(dev, format, arg...) \
printk("Error %s " format, __func__ , ## arg)
@@ -760,18 +740,6 @@ extern int kstrtou32(const char *s, unsigned int base, u32 *res);
#define dev_info(dev, format, arg...) \
printk("Info %s " format , __func__, ## arg)
/*
* nouveau routes all of its logging through dev_*() (NV_PRINTK in
* nouveau_drv.h picks the level by name), so the two levels the other drivers
* never needed have to exist as well. dev_dbg() keeps its arguments checked
* but emits nothing, matching the !CONFIG_DYNAMIC_DEBUG behaviour upstream.
*/
#define dev_crit(dev, format, arg...) \
printk("Critical %s " format, __func__ , ## arg)
#define dev_dbg(dev, format, arg...) \
do { if (0) printk(format, ## arg); } while (0)
struct page
{
unsigned int addr;
-833
View File
@@ -1,833 +0,0 @@
/*
* A generic kernel FIFO implementation
*
* Copyright (C) 2013 Stefani Seibold <stefani@seibold.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _LINUX_KFIFO_H
#define _LINUX_KFIFO_H
/*
* How to porting drivers to the new generic FIFO API:
*
* - Modify the declaration of the "struct kfifo *" object into a
* in-place "struct kfifo" object
* - Init the in-place object with kfifo_alloc() or kfifo_init()
* Note: The address of the in-place "struct kfifo" object must be
* passed as the first argument to this functions
* - Replace the use of __kfifo_put into kfifo_in and __kfifo_get
* into kfifo_out
* - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get
* into kfifo_out_spinlocked
* Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc
* must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked
* as the last parameter
* - The formerly __kfifo_* functions are renamed into kfifo_*
*/
/*
* Note about locking : There is no locking required until only * one reader
* and one writer is using the fifo and no kfifo_reset() will be * called
* kfifo_reset_out() can be safely used, until it will be only called
* in the reader thread.
* For multiple writer and one reader there is only a need to lock the writer.
* And vice versa for only one writer and multiple reader there is only a need
* to lock the reader.
*/
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/scatterlist.h>
struct __kfifo {
unsigned int in;
unsigned int out;
unsigned int mask;
unsigned int esize;
void *data;
};
#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \
union { \
struct __kfifo kfifo; \
datatype *type; \
const datatype *const_type; \
char (*rectype)[recsize]; \
ptrtype *ptr; \
ptrtype const *ptr_const; \
}
#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
{ \
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
}
#define STRUCT_KFIFO(type, size) \
struct __STRUCT_KFIFO(type, size, 0, type)
#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \
{ \
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
type buf[0]; \
}
#define STRUCT_KFIFO_PTR(type) \
struct __STRUCT_KFIFO_PTR(type, 0, type)
/*
* define compatibility "struct kfifo" for dynamic allocated fifos
*/
struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void);
#define STRUCT_KFIFO_REC_1(size) \
struct __STRUCT_KFIFO(unsigned char, size, 1, void)
#define STRUCT_KFIFO_REC_2(size) \
struct __STRUCT_KFIFO(unsigned char, size, 2, void)
/*
* define kfifo_rec types
*/
struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void);
struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
/*
* helper macro to distinguish between real in place fifo where the fifo
* array is a part of the structure and the fifo type where the array is
* outside of the fifo structure.
*/
#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo))
/**
* DECLARE_KFIFO_PTR - macro to declare a fifo pointer object
* @fifo: name of the declared fifo
* @type: type of the fifo elements
*/
#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo
/**
* DECLARE_KFIFO - macro to declare a fifo object
* @fifo: name of the declared fifo
* @type: type of the fifo elements
* @size: the number of elements in the fifo, this must be a power of 2
*/
#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo
/**
* INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO
* @fifo: name of the declared fifo datatype
*/
#define INIT_KFIFO(fifo) \
(void)({ \
typeof(&(fifo)) __tmp = &(fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__kfifo->in = 0; \
__kfifo->out = 0; \
__kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\
__kfifo->esize = sizeof(*__tmp->buf); \
__kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \
})
/**
* DEFINE_KFIFO - macro to define and initialize a fifo
* @fifo: name of the declared fifo datatype
* @type: type of the fifo elements
* @size: the number of elements in the fifo, this must be a power of 2
*
* Note: the macro can be used for global and local fifo data type variables.
*/
#define DEFINE_KFIFO(fifo, type, size) \
DECLARE_KFIFO(fifo, type, size) = \
(typeof(fifo)) { \
{ \
{ \
.in = 0, \
.out = 0, \
.mask = __is_kfifo_ptr(&(fifo)) ? \
0 : \
ARRAY_SIZE((fifo).buf) - 1, \
.esize = sizeof(*(fifo).buf), \
.data = __is_kfifo_ptr(&(fifo)) ? \
NULL : \
(fifo).buf, \
} \
} \
}
static inline unsigned int __must_check
__kfifo_uint_must_check_helper(unsigned int val)
{
return val;
}
static inline int __must_check
__kfifo_int_must_check_helper(int val)
{
return val;
}
/**
* kfifo_initialized - Check if the fifo is initialized
* @fifo: address of the fifo to check
*
* Return %true if fifo is initialized, otherwise %false.
* Assumes the fifo was 0 before.
*/
#define kfifo_initialized(fifo) ((fifo)->kfifo.mask)
/**
* kfifo_esize - returns the size of the element managed by the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_esize(fifo) ((fifo)->kfifo.esize)
/**
* kfifo_recsize - returns the size of the record length field
* @fifo: address of the fifo to be used
*/
#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype))
/**
* kfifo_size - returns the size of the fifo in elements
* @fifo: address of the fifo to be used
*/
#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1)
/**
* kfifo_reset - removes the entire fifo content
* @fifo: address of the fifo to be used
*
* Note: usage of kfifo_reset() is dangerous. It should be only called when the
* fifo is exclusived locked or when it is secured that no other thread is
* accessing the fifo.
*/
#define kfifo_reset(fifo) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
__tmp->kfifo.in = __tmp->kfifo.out = 0; \
})
/**
* kfifo_reset_out - skip fifo content
* @fifo: address of the fifo to be used
*
* Note: The usage of kfifo_reset_out() is safe until it will be only called
* from the reader thread and there is only one concurrent reader. Otherwise
* it is dangerous and must be handled in the same way as kfifo_reset().
*/
#define kfifo_reset_out(fifo) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
__tmp->kfifo.out = __tmp->kfifo.in; \
})
/**
* kfifo_len - returns the number of used elements in the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_len(fifo) \
({ \
typeof((fifo) + 1) __tmpl = (fifo); \
__tmpl->kfifo.in - __tmpl->kfifo.out; \
})
/**
* kfifo_is_empty - returns true if the fifo is empty
* @fifo: address of the fifo to be used
*/
#define kfifo_is_empty(fifo) \
({ \
typeof((fifo) + 1) __tmpq = (fifo); \
__tmpq->kfifo.in == __tmpq->kfifo.out; \
})
/**
* kfifo_is_full - returns true if the fifo is full
* @fifo: address of the fifo to be used
*/
#define kfifo_is_full(fifo) \
({ \
typeof((fifo) + 1) __tmpq = (fifo); \
kfifo_len(__tmpq) > __tmpq->kfifo.mask; \
})
/**
* kfifo_avail - returns the number of unused elements in the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_avail(fifo) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmpq = (fifo); \
const size_t __recsize = sizeof(*__tmpq->rectype); \
unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \
(__recsize) ? ((__avail <= __recsize) ? 0 : \
__kfifo_max_r(__avail - __recsize, __recsize)) : \
__avail; \
}) \
)
/**
* kfifo_skip - skip output data
* @fifo: address of the fifo to be used
*/
#define kfifo_skip(fifo) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__kfifo_skip_r(__kfifo, __recsize); \
else \
__kfifo->out++; \
})
/**
* kfifo_peek_len - gets the size of the next fifo record
* @fifo: address of the fifo to be used
*
* This function returns the size of the next fifo record in number of bytes.
*/
#define kfifo_peek_len(fifo) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \
__kfifo_len_r(__kfifo, __recsize); \
}) \
)
/**
* kfifo_alloc - dynamically allocates a new fifo buffer
* @fifo: pointer to the fifo
* @size: the number of elements in the fifo, this must be a power of 2
* @gfp_mask: get_free_pages mask, passed to kmalloc()
*
* This macro dynamically allocates a new fifo buffer.
*
* The numer of elements will be rounded-up to a power of 2.
* The fifo will be release with kfifo_free().
* Return 0 if no error, otherwise an error code.
*/
#define kfifo_alloc(fifo, size, gfp_mask) \
__kfifo_int_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__is_kfifo_ptr(__tmp) ? \
__kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \
-EINVAL; \
}) \
)
/**
* kfifo_free - frees the fifo
* @fifo: the fifo to be freed
*/
#define kfifo_free(fifo) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__is_kfifo_ptr(__tmp)) \
__kfifo_free(__kfifo); \
})
/**
* kfifo_init - initialize a fifo using a preallocated buffer
* @fifo: the fifo to assign the buffer
* @buffer: the preallocated buffer to be used
* @size: the size of the internal buffer, this have to be a power of 2
*
* This macro initialize a fifo using a preallocated buffer.
*
* The numer of elements will be rounded-up to a power of 2.
* Return 0 if no error, otherwise an error code.
*/
#define kfifo_init(fifo, buffer, size) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__is_kfifo_ptr(__tmp) ? \
__kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \
-EINVAL; \
})
/**
* kfifo_put - put data into the fifo
* @fifo: address of the fifo to be used
* @val: the data to be added
*
* This macro copies the given value into the fifo.
* It returns 0 if the fifo was full. Otherwise it returns the number
* processed elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_put(fifo, val) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof(*__tmp->const_type) __val = (val); \
unsigned int __ret; \
size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \
__recsize); \
else { \
__ret = !kfifo_is_full(__tmp); \
if (__ret) { \
(__is_kfifo_ptr(__tmp) ? \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->in & __tmp->kfifo.mask] = \
*(typeof(__tmp->type))&__val; \
smp_wmb(); \
__kfifo->in++; \
} \
} \
__ret; \
})
/**
* kfifo_get - get data from the fifo
* @fifo: address of the fifo to be used
* @val: address where to store the data
*
* This macro reads the data from the fifo.
* It returns 0 if the fifo was empty. Otherwise it returns the number
* processed elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_get(fifo, val) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof(__tmp->ptr) __val = (val); \
unsigned int __ret; \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
else { \
__ret = !kfifo_is_empty(__tmp); \
if (__ret) { \
*(typeof(__tmp->type))__val = \
(__is_kfifo_ptr(__tmp) ? \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->out & __tmp->kfifo.mask]; \
smp_wmb(); \
__kfifo->out++; \
} \
} \
__ret; \
}) \
)
/**
* kfifo_peek - get data from the fifo without removing
* @fifo: address of the fifo to be used
* @val: address where to store the data
*
* This reads the data from the fifo without removing it from the fifo.
* It returns 0 if the fifo was empty. Otherwise it returns the number
* processed elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_peek(fifo, val) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof(__tmp->ptr) __val = (val); \
unsigned int __ret; \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
__recsize); \
else { \
__ret = !kfifo_is_empty(__tmp); \
if (__ret) { \
*(typeof(__tmp->type))__val = \
(__is_kfifo_ptr(__tmp) ? \
((typeof(__tmp->type))__kfifo->data) : \
(__tmp->buf) \
)[__kfifo->out & __tmp->kfifo.mask]; \
smp_wmb(); \
} \
} \
__ret; \
}) \
)
/**
* kfifo_in - put data into the fifo
* @fifo: address of the fifo to be used
* @buf: the data to be added
* @n: number of elements to be added
*
* This macro copies the given buffer into the fifo and returns the
* number of copied elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_in(fifo, buf, n) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof(__tmp->ptr_const) __buf = (buf); \
unsigned long __n = (n); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ?\
__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_in(__kfifo, __buf, __n); \
})
/**
* kfifo_in_spinlocked - put data into the fifo using a spinlock for locking
* @fifo: address of the fifo to be used
* @buf: the data to be added
* @n: number of elements to be added
* @lock: pointer to the spinlock to use for locking
*
* This macro copies the given values buffer into the fifo and returns the
* number of copied elements.
*/
#define kfifo_in_spinlocked(fifo, buf, n, lock) \
({ \
unsigned long __flags; \
unsigned int __ret; \
spin_lock_irqsave(lock, __flags); \
__ret = kfifo_in(fifo, buf, n); \
spin_unlock_irqrestore(lock, __flags); \
__ret; \
})
/* alias for kfifo_in_spinlocked, will be removed in a future release */
#define kfifo_in_locked(fifo, buf, n, lock) \
kfifo_in_spinlocked(fifo, buf, n, lock)
/**
* kfifo_out - get data from the fifo
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
*
* This macro get some data from the fifo and return the numbers of elements
* copied.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_out(fifo, buf, n) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof(__tmp->ptr) __buf = (buf); \
unsigned long __n = (n); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ?\
__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_out(__kfifo, __buf, __n); \
}) \
)
/**
* kfifo_out_spinlocked - get data from the fifo using a spinlock for locking
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
* @lock: pointer to the spinlock to use for locking
*
* This macro get the data from the fifo and return the numbers of elements
* copied.
*/
#define kfifo_out_spinlocked(fifo, buf, n, lock) \
__kfifo_uint_must_check_helper( \
({ \
unsigned long __flags; \
unsigned int __ret; \
spin_lock_irqsave(lock, __flags); \
__ret = kfifo_out(fifo, buf, n); \
spin_unlock_irqrestore(lock, __flags); \
__ret; \
}) \
)
/* alias for kfifo_out_spinlocked, will be removed in a future release */
#define kfifo_out_locked(fifo, buf, n, lock) \
kfifo_out_spinlocked(fifo, buf, n, lock)
/**
* kfifo_from_user - puts some data from user space into the fifo
* @fifo: address of the fifo to be used
* @from: pointer to the data to be added
* @len: the length of the data to be added
* @copied: pointer to output variable to store the number of copied bytes
*
* This macro copies at most @len bytes from the @from into the
* fifo, depending of the available space and returns -EFAULT/0.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_from_user(fifo, from, len, copied) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
const void __user *__from = (from); \
unsigned int __len = (len); \
unsigned int *__copied = (copied); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \
__kfifo_from_user(__kfifo, __from, __len, __copied); \
}) \
)
/**
* kfifo_to_user - copies data from the fifo into user space
* @fifo: address of the fifo to be used
* @to: where the data must be copied
* @len: the size of the destination buffer
* @copied: pointer to output variable to store the number of copied bytes
*
* This macro copies at most @len bytes from the fifo into the
* @to buffer and returns -EFAULT/0.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_to_user(fifo, to, len, copied) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
void __user *__to = (to); \
unsigned int __len = (len); \
unsigned int *__copied = (copied); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \
__kfifo_to_user(__kfifo, __to, __len, __copied); \
}) \
)
/**
* kfifo_dma_in_prepare - setup a scatterlist for DMA input
* @fifo: address of the fifo to be used
* @sgl: pointer to the scatterlist array
* @nents: number of entries in the scatterlist array
* @len: number of elements to transfer
*
* This macro fills a scatterlist for DMA input.
* It returns the number entries in the scatterlist array.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macros.
*/
#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct scatterlist *__sgl = (sgl); \
int __nents = (nents); \
unsigned int __len = (len); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
__kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \
})
/**
* kfifo_dma_in_finish - finish a DMA IN operation
* @fifo: address of the fifo to be used
* @len: number of bytes to received
*
* This macro finish a DMA IN operation. The in counter will be updated by
* the len parameter. No error checking will be done.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macros.
*/
#define kfifo_dma_in_finish(fifo, len) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
unsigned int __len = (len); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \
else \
__kfifo->in += __len / sizeof(*__tmp->type); \
})
/**
* kfifo_dma_out_prepare - setup a scatterlist for DMA output
* @fifo: address of the fifo to be used
* @sgl: pointer to the scatterlist array
* @nents: number of entries in the scatterlist array
* @len: number of elements to transfer
*
* This macro fills a scatterlist for DMA output which at most @len bytes
* to transfer.
* It returns the number entries in the scatterlist array.
* A zero means there is no space available and the scatterlist is not filled.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macros.
*/
#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct scatterlist *__sgl = (sgl); \
int __nents = (nents); \
unsigned int __len = (len); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
__kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \
})
/**
* kfifo_dma_out_finish - finish a DMA OUT operation
* @fifo: address of the fifo to be used
* @len: number of bytes transferred
*
* This macro finish a DMA OUT operation. The out counter will be updated by
* the len parameter. No error checking will be done.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macros.
*/
#define kfifo_dma_out_finish(fifo, len) \
(void)({ \
typeof((fifo) + 1) __tmp = (fifo); \
unsigned int __len = (len); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
if (__recsize) \
__kfifo_dma_out_finish_r(__kfifo, __recsize); \
else \
__kfifo->out += __len / sizeof(*__tmp->type); \
})
/**
* kfifo_out_peek - gets some data from the fifo
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
*
* This macro get the data from the fifo and return the numbers of elements
* copied. The data is not removed from the fifo.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define kfifo_out_peek(fifo, buf, n) \
__kfifo_uint_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
typeof(__tmp->ptr) __buf = (buf); \
unsigned long __n = (n); \
const size_t __recsize = sizeof(*__tmp->rectype); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
(__recsize) ? \
__kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
__kfifo_out_peek(__kfifo, __buf, __n); \
}) \
)
extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
size_t esize, gfp_t gfp_mask);
extern void __kfifo_free(struct __kfifo *fifo);
extern int __kfifo_init(struct __kfifo *fifo, void *buffer,
unsigned int size, size_t esize);
extern unsigned int __kfifo_in(struct __kfifo *fifo,
const void *buf, unsigned int len);
extern unsigned int __kfifo_out(struct __kfifo *fifo,
void *buf, unsigned int len);
extern int __kfifo_from_user(struct __kfifo *fifo,
const void __user *from, unsigned long len, unsigned int *copied);
extern int __kfifo_to_user(struct __kfifo *fifo,
void __user *to, unsigned long len, unsigned int *copied);
extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
struct scatterlist *sgl, int nents, unsigned int len);
extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
struct scatterlist *sgl, int nents, unsigned int len);
extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
void *buf, unsigned int len);
extern unsigned int __kfifo_in_r(struct __kfifo *fifo,
const void *buf, unsigned int len, size_t recsize);
extern unsigned int __kfifo_out_r(struct __kfifo *fifo,
void *buf, unsigned int len, size_t recsize);
extern int __kfifo_from_user_r(struct __kfifo *fifo,
const void __user *from, unsigned long len, unsigned int *copied,
size_t recsize);
extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to,
unsigned long len, unsigned int *copied, size_t recsize);
extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo,
unsigned int len, size_t recsize);
extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize);
extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
void *buf, unsigned int len, size_t recsize);
extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize);
#endif
-57
View File
@@ -1,57 +0,0 @@
#ifndef _LINUX_KTHREAD_H
#define _LINUX_KTHREAD_H
/*
* Minimal kthread emulation for KolibriOS.
*
* The GPU scheduler (drivers/video/drm/amdgpu/scheduler) is the only user in
* the DRM tree. KolibriOS kernel threads are created with CreateKernelThread(),
* which takes no argument, so kthread_run() stashes the payload in a small
* pid-indexed table and the trampoline picks it up. Park/stop are cooperative
* flags polled by the thread body, matching how the scheduler uses them.
*/
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/err.h>
#include <linux/rwsem.h>
/*
* Placeholder address space. Drivers reach it as current->mm on their userptr
* paths only, which KolibriOS never enters (no ioctl surface for user code).
*/
struct mm_struct {
struct rw_semaphore mmap_sem;
};
struct task_struct {
int (*threadfn)(void *data);
void *data;
int pid;
volatile int should_stop;
volatile int should_park;
volatile int parked;
char comm[16];
struct mm_struct *mm;
};
struct task_struct *kthread_create_kos(int (*threadfn)(void *data),
void *data, const char *name);
int kthread_stop(struct task_struct *k);
bool kthread_should_stop(void);
bool kthread_should_park(void);
void kthread_parkme(void);
int kthread_park(struct task_struct *k);
void kthread_unpark(struct task_struct *k);
struct task_struct *kthread_current(void);
#define kthread_run(threadfn, data, namefmt, ...) \
kthread_create_kos((threadfn), (data), (namefmt))
#define kthread_create(threadfn, data, namefmt, ...) \
kthread_create_kos((threadfn), (data), (namefmt))
static inline void wake_up_process(struct task_struct *k) { }
static inline void get_task_struct(struct task_struct *k) { }
static inline void put_task_struct(struct task_struct *k) { }
#endif /* _LINUX_KTHREAD_H */
-24
View File
@@ -1,24 +0,0 @@
#ifndef _LINUX_MFD_CORE_H
#define _LINUX_MFD_CORE_H
/*
* No multi-function-device bus on KolibriOS. amdgpu_acp.h embeds an
* mfd_cell pointer in struct amdgpu_acp; the ACP block itself is not built.
*/
#include <linux/types.h>
struct device;
struct resource;
struct mfd_cell {
const char *name;
int id;
void *platform_data;
size_t pdata_size;
int num_resources;
const struct resource *resources;
};
static inline int mfd_add_hotplug_devices(struct device *parent,
const struct mfd_cell *cells, int n)
{ return -ENODEV; }
static inline void mfd_remove_devices(struct device *parent) { }
#endif
-6
View File
@@ -8,12 +8,6 @@
#define nth_page(page,n) ((void*)(((page_to_phys(page)>>12)+(n))<<12))
#define __page_to_pfn(page) (page_to_phys(page)>>12)
/*
* A struct page * here is just the physical address (see page_to_phys() in
* <linux/kernel.h>), so the reverse direction is the same shift back.
*/
#define __pfn_to_page(pfn) ((struct page *)((dma_addr_t)(pfn) << 12))
#define pfn_to_page(pfn) __pfn_to_page(pfn)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
-10
View File
@@ -26,14 +26,4 @@
struct module {};
/*
* Nothing is a module here - everything is linked into the one image - so the
* reference count can never drop and a request for another module can never be
* satisfied. Implemented in the driver's kos_* glue.
*/
extern int request_module(const char *name, ...);
extern int try_module_get(struct module *module);
extern void module_put(struct module *module);
#endif /* _LINUX_MODULE_H */
-9
View File
@@ -77,15 +77,6 @@ void __attribute__ ((fastcall)) __attribute__ ((dllimport))
void __attribute__ ((fastcall)) __attribute__ ((dllimport))
mutex_unlock(struct mutex*)__asm__("MutexUnlock");
/*
* mutex_init() is the DDK's MutexInit(); these two are the spellings upstream
* code reaches for when it wants a lockdep class, which this port does not
* have. Both end up in the same place.
*/
extern void __mutex_init(struct mutex *lock, const char *name,
struct lock_class_key *key);
extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
static inline int mutex_lock_interruptible(struct mutex *lock)
{
mutex_lock(lock);
-10
View File
@@ -1,10 +0,0 @@
#ifndef _LINUX_OF_DEVICE_H
#define _LINUX_OF_DEVICE_H
/* No device tree on x86; pulled in unconditionally by nvif/os.h. */
struct device;
struct of_device_id;
static inline const struct of_device_id *
of_match_device(const struct of_device_id *m, const struct device *dev)
{ return NULL; }
#endif
-8
View File
@@ -1,8 +0,0 @@
#ifndef _LINUX_PAGEMAP_H
#define _LINUX_PAGEMAP_H
/* Only the shift/size helpers are used by the TTM/GEM paths on this port. */
#include <linux/mm.h>
#define PAGE_CACHE_SHIFT PAGE_SHIFT
#define PAGE_CACHE_SIZE PAGE_SIZE
#define PAGE_CACHE_MASK PAGE_MASK
#endif
-7
View File
@@ -275,13 +275,6 @@ struct pci_dev {
struct pci_bus *bus; /* bus this device is on */
struct pci_bus *subordinate; /* bus this device bridges to */
/*
* Always NULL on this port: there is no driver model to bind through.
* nouveau_drm.c reads it to decide whether the HDMI audio function is
* claimed before powering the GPU down, and takes the safe branch.
*/
struct pci_driver *driver;
void *sysdata; /* hook for sys-specific extension */
// struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */
struct pci_slot *slot; /* Physical slot this device is in */
-7
View File
@@ -1,7 +0,0 @@
#ifndef _LINUX_PLATFORM_DEVICE_H
#define _LINUX_PLATFORM_DEVICE_H
/* No platform bus; amdgpu_drv.h only needs the type to exist. */
#include <linux/device.h>
struct platform_device { struct device dev; const char *name; int id; };
struct platform_driver;
#endif
-12
View File
@@ -1,12 +0,0 @@
#ifndef _LINUX_POWER_SUPPLY_H
#define _LINUX_POWER_SUPPLY_H
/*
* No battery subsystem on KolibriOS. power_supply_is_system_supplied() is
* already provided by <syscall.h>; only the enum labels are missing.
*/
enum {
POWER_SUPPLY_TYPE_UNKNOWN = 0,
POWER_SUPPLY_TYPE_BATTERY,
POWER_SUPPLY_TYPE_MAINS,
};
#endif
-22
View File
@@ -1,22 +0,0 @@
#ifndef _LINUX_REBOOT_H
#define _LINUX_REBOOT_H
/*
* No reboot notifier chain on this port. nvif/os.h includes this header for
* every nvkm translation unit; nothing in the built set registers a notifier.
*/
#include <linux/notifier.h>
#define SYS_RESTART 0x0001
#define SYS_HALT 0x0002
#define SYS_POWER_OFF 0x0003
static inline int register_reboot_notifier(struct notifier_block *nb) { return 0; }
static inline int unregister_reboot_notifier(struct notifier_block *nb) { return 0; }
/*
* nvkm/subdev/therm/temp.c asks for this when the GPU passes its shutdown
* threshold. There is no orderly shutdown to request on KolibriOS; the
* driver's implementation logs and returns.
*/
extern int orderly_poweroff(bool force);
#endif
@@ -1,18 +0,0 @@
#ifndef _LINUX_REGULATOR_CONSUMER_H
#define _LINUX_REGULATOR_CONSUMER_H
/* Tegra-only; see linux/clk.h for why this exists at all. */
#include <linux/errno.h>
#include <linux/err.h>
struct regulator;
struct device;
static inline struct regulator *regulator_get(struct device *dev, const char *id)
{ return ERR_PTR(-ENOENT); }
static inline void regulator_put(struct regulator *r) { }
static inline int regulator_enable(struct regulator *r) { return -ENOSYS; }
static inline int regulator_disable(struct regulator *r) { return -ENOSYS; }
static inline int regulator_get_voltage(struct regulator *r) { return -ENODEV; }
static inline int regulator_set_voltage(struct regulator *r, int min_uV, int max_uV)
{ return -ENODEV; }
#endif
-15
View File
@@ -1,15 +0,0 @@
#ifndef _LINUX_RESET_H
#define _LINUX_RESET_H
/* Tegra-only; see linux/clk.h for why this exists at all. */
#include <linux/errno.h>
#include <linux/err.h>
struct reset_control;
struct device;
static inline struct reset_control *reset_control_get(struct device *dev, const char *id)
{ return ERR_PTR(-ENOENT); }
static inline void reset_control_put(struct reset_control *rstc) { }
static inline int reset_control_assert(struct reset_control *rstc) { return -ENOSYS; }
static inline int reset_control_deassert(struct reset_control *rstc) { return -ENOSYS; }
#endif
-10
View File
@@ -49,14 +49,4 @@
#define schedule_timeout(x) delay(x)
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
/*
* No processes and no signals behind a driver thread: signal_pending() is
* always false, so interruptible waits only ever end on their timeout, and
* every task carries the singleton name set in kos_stubs.c.
*/
struct task_struct;
extern int signal_pending(struct task_struct *p);
extern void __set_current_state(int state);
extern char *get_task_comm(char *buf, struct task_struct *tsk);
#endif
-19
View File
@@ -1,19 +0,0 @@
#ifndef _LINUX_SCREEN_INFO_H
#define _LINUX_SCREEN_INFO_H
/*
* nouveau_fbcon.c only uses this to decide whether it owns the boot console.
* KolibriOS has no boot console to hand over, so the record stays empty.
*/
#include <linux/types.h>
struct screen_info {
__u8 orig_video_isVGA;
__u16 lfb_width;
__u16 lfb_height;
__u16 lfb_depth;
__u32 lfb_base;
__u32 lfb_size;
};
extern struct screen_info screen_info;
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef _LINUX_SWIOTLB_H
#define _LINUX_SWIOTLB_H
/* No bounce buffers on this port; amdgpu_ttm.c only queries swiotlb_nr_tbl(). */
static inline unsigned long swiotlb_nr_tbl(void) { return 0; }
#endif
-35
View File
@@ -1,35 +0,0 @@
#ifndef _LINUX_TRACEPOINT_H
#define _LINUX_TRACEPOINT_H
/* Tracepoints compile away: amdgpu_trace.h expands to empty trace_*() calls. */
/*
* Each event still has to yield a callable trace_<name>(), because the driver
* code calls it unconditionally - upstream generates one per event. Here they
* expand to empty inlines, so the calls disappear at -O2 but the argument
* expressions are still type-checked.
*/
#define TP_PROTO(args...) args
#define TP_ARGS(args...) args
#define TP_STRUCT__entry(args...)
#define TP_fast_assign(args...)
#define TP_printk(fmt, args...)
#define TP_CONDITION(args...)
#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
#define DEFINE_EVENT(tmpl, name, proto, args) \
static inline void trace_##name(proto) { } \
static inline bool trace_##name##_enabled(void) { return false; }
#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
static inline void trace_##name(proto) { } \
static inline bool trace_##name##_enabled(void) { return false; }
#define TRACE_EVENT_CONDITION(name, proto, args, cond, tstruct, assign, print) \
static inline void trace_##name(proto) { } \
static inline bool trace_##name##_enabled(void) { return false; }
#define DECLARE_TRACE(name, proto, args) \
static inline void trace_##name(proto) { }
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
#define EXPORT_TRACEPOINT_SYMBOL(name)
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef _LINUX_TTY_H
#define _LINUX_TTY_H
/* No tty layer; nouveau_fbcon.c includes it for console_lock() neighbours. */
#include <linux/console.h>
#endif
-1
View File
@@ -188,7 +188,6 @@ static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(v
static inline int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { return -ENODEV; }
static inline int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) { return -ENODEV; }
static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
static inline bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) { return false; }
static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {}
-6
View File
@@ -30,12 +30,6 @@ extern void *vmalloc(unsigned long size);
extern void *vzalloc(unsigned long size);
extern void vfree(const void *addr);
/*
* kmalloc() and vmalloc() come from the same allocator on this port, so one
* free serves both - which is what kvfree() means upstream too.
*/
extern void kvfree(const void *addr);
extern void *vmap(struct page **pages, unsigned int count,
unsigned long flags, pgprot_t prot);
extern void vunmap(const void *addr);
-24
View File
@@ -326,30 +326,6 @@ int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
/*
* The "_locked" variants are entered with wq.lock already held and must give
* it up while waiting. That rules out the event-based path above, which takes
* the lock itself, so these poll instead - the same trade the rest of this
* header already makes.
*
* Because nothing ever blocks on an event here, wake_up_all_locked() has
* nothing to signal: the waiter re-tests the condition on its next tick.
*/
#define wait_event_interruptible_locked(wq, condition) \
({ \
while (!(condition)) { \
spin_unlock(&(wq).lock); \
delay(1); \
spin_lock(&(wq).lock); \
} \
0; \
})
#define wait_event_locked(wq, condition) \
wait_event_interruptible_locked(wq, condition)
#define wake_up_locked(q) do { } while (0)
#define wake_up_all_locked(q) do { } while (0)
#endif
-3
View File
@@ -268,9 +268,6 @@ static inline bool mod_delayed_work(struct workqueue_struct *wq,
(_work)->work.func = _func; \
} while (0)
/* Defined in each driver's kos_kernel.c. */
extern bool flush_work(struct work_struct *work);
static inline bool schedule_work(struct work_struct *work)
{
return queue_work(system_wq, work);
-5
View File
@@ -1,5 +0,0 @@
#ifndef __SOC_TEGRA_FUSE_H
#define __SOC_TEGRA_FUSE_H
/* Tegra-only; nvif/os.h includes it unconditionally. */
static inline int tegra_sku_info_dummy(void) { return 0; }
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef __SOC_TEGRA_PMC_H
#define __SOC_TEGRA_PMC_H
/* Tegra-only; nvif/os.h includes it unconditionally. */
static inline int tegra_pmc_dummy(void) { return 0; }
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef _TRACE_DEFINE_TRACE_H
#define _TRACE_DEFINE_TRACE_H
/* Tracepoints are compiled out - see linux/tracepoint.h. */
#undef TRACE_HEADER_MULTI_READ
#endif
-6
View File
@@ -1,6 +0,0 @@
#ifndef _TRACE_EVENTS_FENCE_H
#define _TRACE_EVENTS_FENCE_H
/* Tracepoints are compiled out; nouveau_fence.c is the only includer. */
struct fence;
static inline void trace_fence_emit(struct fence *fence) { }
#endif
+1 -8
View File
@@ -68,14 +68,7 @@
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#ifdef __KERNEL__
/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
#else
#ifndef __KERNEL__
#define _IOC_TYPECHECK(t) (sizeof(t))
#endif
-662
View File
@@ -1,662 +0,0 @@
/* amdgpu_drm.h -- Public header for the amdgpu driver -*- linux-c -*-
*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
* Copyright 2014 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef __AMDGPU_DRM_H__
#define __AMDGPU_DRM_H__
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_AMDGPU_GEM_CREATE 0x00
#define DRM_AMDGPU_GEM_MMAP 0x01
#define DRM_AMDGPU_CTX 0x02
#define DRM_AMDGPU_BO_LIST 0x03
#define DRM_AMDGPU_CS 0x04
#define DRM_AMDGPU_INFO 0x05
#define DRM_AMDGPU_GEM_METADATA 0x06
#define DRM_AMDGPU_GEM_WAIT_IDLE 0x07
#define DRM_AMDGPU_GEM_VA 0x08
#define DRM_AMDGPU_WAIT_CS 0x09
#define DRM_AMDGPU_GEM_OP 0x10
#define DRM_AMDGPU_GEM_USERPTR 0x11
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
#define DRM_IOCTL_AMDGPU_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CTX, union drm_amdgpu_ctx)
#define DRM_IOCTL_AMDGPU_BO_LIST DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_BO_LIST, union drm_amdgpu_bo_list)
#define DRM_IOCTL_AMDGPU_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CS, union drm_amdgpu_cs)
#define DRM_IOCTL_AMDGPU_INFO DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_INFO, struct drm_amdgpu_info)
#define DRM_IOCTL_AMDGPU_GEM_METADATA DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, struct drm_amdgpu_gem_metadata)
#define DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_WAIT_IDLE, union drm_amdgpu_gem_wait_idle)
#define DRM_IOCTL_AMDGPU_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_VA, struct drm_amdgpu_gem_va)
#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
#define AMDGPU_GEM_DOMAIN_VRAM 0x4
#define AMDGPU_GEM_DOMAIN_GDS 0x8
#define AMDGPU_GEM_DOMAIN_GWS 0x10
#define AMDGPU_GEM_DOMAIN_OA 0x20
/* Flag that CPU access will be required for the case of VRAM domain */
#define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0)
/* Flag that CPU access will not work, this VRAM domain is invisible */
#define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1)
/* Flag that USWC attributes should be used for GTT */
#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
/* Flag that the memory should be in VRAM and cleared */
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
/* Flag that create shadow bo(GTT) while allocating vram bo */
#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
struct drm_amdgpu_gem_create_in {
/** the requested memory size */
__u64 bo_size;
/** physical start_addr alignment in bytes for some HW requirements */
__u64 alignment;
/** the requested memory domains */
__u64 domains;
/** allocation flags */
__u64 domain_flags;
};
struct drm_amdgpu_gem_create_out {
/** returned GEM object handle */
__u32 handle;
__u32 _pad;
};
union drm_amdgpu_gem_create {
struct drm_amdgpu_gem_create_in in;
struct drm_amdgpu_gem_create_out out;
};
/** Opcode to create new residency list. */
#define AMDGPU_BO_LIST_OP_CREATE 0
/** Opcode to destroy previously created residency list */
#define AMDGPU_BO_LIST_OP_DESTROY 1
/** Opcode to update resource information in the list */
#define AMDGPU_BO_LIST_OP_UPDATE 2
struct drm_amdgpu_bo_list_in {
/** Type of operation */
__u32 operation;
/** Handle of list or 0 if we want to create one */
__u32 list_handle;
/** Number of BOs in list */
__u32 bo_number;
/** Size of each element describing BO */
__u32 bo_info_size;
/** Pointer to array describing BOs */
__u64 bo_info_ptr;
};
struct drm_amdgpu_bo_list_entry {
/** Handle of BO */
__u32 bo_handle;
/** New (if specified) BO priority to be used during migration */
__u32 bo_priority;
};
struct drm_amdgpu_bo_list_out {
/** Handle of resource list */
__u32 list_handle;
__u32 _pad;
};
union drm_amdgpu_bo_list {
struct drm_amdgpu_bo_list_in in;
struct drm_amdgpu_bo_list_out out;
};
/* context related */
#define AMDGPU_CTX_OP_ALLOC_CTX 1
#define AMDGPU_CTX_OP_FREE_CTX 2
#define AMDGPU_CTX_OP_QUERY_STATE 3
/* GPU reset status */
#define AMDGPU_CTX_NO_RESET 0
/* this the context caused it */
#define AMDGPU_CTX_GUILTY_RESET 1
/* some other context caused it */
#define AMDGPU_CTX_INNOCENT_RESET 2
/* unknown cause */
#define AMDGPU_CTX_UNKNOWN_RESET 3
struct drm_amdgpu_ctx_in {
/** AMDGPU_CTX_OP_* */
__u32 op;
/** For future use, no flags defined so far */
__u32 flags;
__u32 ctx_id;
__u32 _pad;
};
union drm_amdgpu_ctx_out {
struct {
__u32 ctx_id;
__u32 _pad;
} alloc;
struct {
/** For future use, no flags defined so far */
__u64 flags;
/** Number of resets caused by this context so far. */
__u32 hangs;
/** Reset status since the last call of the ioctl. */
__u32 reset_status;
} state;
};
union drm_amdgpu_ctx {
struct drm_amdgpu_ctx_in in;
union drm_amdgpu_ctx_out out;
};
/*
* This is not a reliable API and you should expect it to fail for any
* number of reasons and have fallback path that do not use userptr to
* perform any operation.
*/
#define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
#define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
#define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
#define AMDGPU_GEM_USERPTR_REGISTER (1 << 3)
struct drm_amdgpu_gem_userptr {
__u64 addr;
__u64 size;
/* AMDGPU_GEM_USERPTR_* */
__u32 flags;
/* Resulting GEM handle */
__u32 handle;
};
/* same meaning as the GB_TILE_MODE and GL_MACRO_TILE_MODE fields */
#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0
#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf
#define AMDGPU_TILING_PIPE_CONFIG_SHIFT 4
#define AMDGPU_TILING_PIPE_CONFIG_MASK 0x1f
#define AMDGPU_TILING_TILE_SPLIT_SHIFT 9
#define AMDGPU_TILING_TILE_SPLIT_MASK 0x7
#define AMDGPU_TILING_MICRO_TILE_MODE_SHIFT 12
#define AMDGPU_TILING_MICRO_TILE_MODE_MASK 0x7
#define AMDGPU_TILING_BANK_WIDTH_SHIFT 15
#define AMDGPU_TILING_BANK_WIDTH_MASK 0x3
#define AMDGPU_TILING_BANK_HEIGHT_SHIFT 17
#define AMDGPU_TILING_BANK_HEIGHT_MASK 0x3
#define AMDGPU_TILING_MACRO_TILE_ASPECT_SHIFT 19
#define AMDGPU_TILING_MACRO_TILE_ASPECT_MASK 0x3
#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
#define AMDGPU_TILING_SET(field, value) \
(((value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT)
#define AMDGPU_TILING_GET(value, field) \
(((value) >> AMDGPU_TILING_##field##_SHIFT) & AMDGPU_TILING_##field##_MASK)
#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
/** The same structure is shared for input/output */
struct drm_amdgpu_gem_metadata {
/** GEM Object handle */
__u32 handle;
/** Do we want get or set metadata */
__u32 op;
struct {
/** For future use, no flags defined so far */
__u64 flags;
/** family specific tiling info */
__u64 tiling_info;
__u32 data_size_bytes;
__u32 data[64];
} data;
};
struct drm_amdgpu_gem_mmap_in {
/** the GEM object handle */
__u32 handle;
__u32 _pad;
};
struct drm_amdgpu_gem_mmap_out {
/** mmap offset from the vma offset manager */
__u64 addr_ptr;
};
union drm_amdgpu_gem_mmap {
struct drm_amdgpu_gem_mmap_in in;
struct drm_amdgpu_gem_mmap_out out;
};
struct drm_amdgpu_gem_wait_idle_in {
/** GEM object handle */
__u32 handle;
/** For future use, no flags defined so far */
__u32 flags;
/** Absolute timeout to wait */
__u64 timeout;
};
struct drm_amdgpu_gem_wait_idle_out {
/** BO status: 0 - BO is idle, 1 - BO is busy */
__u32 status;
/** Returned current memory domain */
__u32 domain;
};
union drm_amdgpu_gem_wait_idle {
struct drm_amdgpu_gem_wait_idle_in in;
struct drm_amdgpu_gem_wait_idle_out out;
};
struct drm_amdgpu_wait_cs_in {
/** Command submission handle */
__u64 handle;
/** Absolute timeout to wait */
__u64 timeout;
__u32 ip_type;
__u32 ip_instance;
__u32 ring;
__u32 ctx_id;
};
struct drm_amdgpu_wait_cs_out {
/** CS status: 0 - CS completed, 1 - CS still busy */
__u64 status;
};
union drm_amdgpu_wait_cs {
struct drm_amdgpu_wait_cs_in in;
struct drm_amdgpu_wait_cs_out out;
};
#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
#define AMDGPU_GEM_OP_SET_PLACEMENT 1
/* Sets or returns a value associated with a buffer. */
struct drm_amdgpu_gem_op {
/** GEM object handle */
__u32 handle;
/** AMDGPU_GEM_OP_* */
__u32 op;
/** Input or return value */
__u64 value;
};
#define AMDGPU_VA_OP_MAP 1
#define AMDGPU_VA_OP_UNMAP 2
/* Delay the page table update till the next CS */
#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
/* Mapping flags */
/* readable mapping */
#define AMDGPU_VM_PAGE_READABLE (1 << 1)
/* writable mapping */
#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
/* executable mapping, new for VI */
#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
struct drm_amdgpu_gem_va {
/** GEM object handle */
__u32 handle;
__u32 _pad;
/** AMDGPU_VA_OP_* */
__u32 operation;
/** AMDGPU_VM_PAGE_* */
__u32 flags;
/** va address to assign . Must be correctly aligned.*/
__u64 va_address;
/** Specify offset inside of BO to assign. Must be correctly aligned.*/
__u64 offset_in_bo;
/** Specify mapping size. Must be correctly aligned. */
__u64 map_size;
};
#define AMDGPU_HW_IP_GFX 0
#define AMDGPU_HW_IP_COMPUTE 1
#define AMDGPU_HW_IP_DMA 2
#define AMDGPU_HW_IP_UVD 3
#define AMDGPU_HW_IP_VCE 4
#define AMDGPU_HW_IP_NUM 5
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
#define AMDGPU_CHUNK_ID_IB 0x01
#define AMDGPU_CHUNK_ID_FENCE 0x02
#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
struct drm_amdgpu_cs_chunk {
__u32 chunk_id;
__u32 length_dw;
__u64 chunk_data;
};
struct drm_amdgpu_cs_in {
/** Rendering context id */
__u32 ctx_id;
/** Handle of resource list associated with CS */
__u32 bo_list_handle;
__u32 num_chunks;
__u32 _pad;
/** this points to __u64 * which point to cs chunks */
__u64 chunks;
};
struct drm_amdgpu_cs_out {
__u64 handle;
};
union drm_amdgpu_cs {
struct drm_amdgpu_cs_in in;
struct drm_amdgpu_cs_out out;
};
/* Specify flags to be used for IB */
/* This IB should be submitted to CE */
#define AMDGPU_IB_FLAG_CE (1<<0)
/* CE Preamble */
#define AMDGPU_IB_FLAG_PREAMBLE (1<<1)
struct drm_amdgpu_cs_chunk_ib {
__u32 _pad;
/** AMDGPU_IB_FLAG_* */
__u32 flags;
/** Virtual address to begin IB execution */
__u64 va_start;
/** Size of submission */
__u32 ib_bytes;
/** HW IP to submit to */
__u32 ip_type;
/** HW IP index of the same type to submit to */
__u32 ip_instance;
/** Ring index to submit to */
__u32 ring;
};
struct drm_amdgpu_cs_chunk_dep {
__u32 ip_type;
__u32 ip_instance;
__u32 ring;
__u32 ctx_id;
__u64 handle;
};
struct drm_amdgpu_cs_chunk_fence {
__u32 handle;
__u32 offset;
};
struct drm_amdgpu_cs_chunk_data {
union {
struct drm_amdgpu_cs_chunk_ib ib_data;
struct drm_amdgpu_cs_chunk_fence fence_data;
};
};
/**
* Query h/w info: Flag that this is integrated (a.h.a. fusion) GPU
*
*/
#define AMDGPU_IDS_FLAGS_FUSION 0x1
/* indicate if acceleration can be working */
#define AMDGPU_INFO_ACCEL_WORKING 0x00
/* get the crtc_id from the mode object id? */
#define AMDGPU_INFO_CRTC_FROM_ID 0x01
/* query hw IP info */
#define AMDGPU_INFO_HW_IP_INFO 0x02
/* query hw IP instance count for the specified type */
#define AMDGPU_INFO_HW_IP_COUNT 0x03
/* timestamp for GL_ARB_timer_query */
#define AMDGPU_INFO_TIMESTAMP 0x05
/* Query the firmware version */
#define AMDGPU_INFO_FW_VERSION 0x0e
/* Subquery id: Query VCE firmware version */
#define AMDGPU_INFO_FW_VCE 0x1
/* Subquery id: Query UVD firmware version */
#define AMDGPU_INFO_FW_UVD 0x2
/* Subquery id: Query GMC firmware version */
#define AMDGPU_INFO_FW_GMC 0x03
/* Subquery id: Query GFX ME firmware version */
#define AMDGPU_INFO_FW_GFX_ME 0x04
/* Subquery id: Query GFX PFP firmware version */
#define AMDGPU_INFO_FW_GFX_PFP 0x05
/* Subquery id: Query GFX CE firmware version */
#define AMDGPU_INFO_FW_GFX_CE 0x06
/* Subquery id: Query GFX RLC firmware version */
#define AMDGPU_INFO_FW_GFX_RLC 0x07
/* Subquery id: Query GFX MEC firmware version */
#define AMDGPU_INFO_FW_GFX_MEC 0x08
/* Subquery id: Query SMC firmware version */
#define AMDGPU_INFO_FW_SMC 0x0a
/* Subquery id: Query SDMA firmware version */
#define AMDGPU_INFO_FW_SDMA 0x0b
/* number of bytes moved for TTM migration */
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
/* the used VRAM size */
#define AMDGPU_INFO_VRAM_USAGE 0x10
/* the used GTT size */
#define AMDGPU_INFO_GTT_USAGE 0x11
/* Information about GDS, etc. resource configuration */
#define AMDGPU_INFO_GDS_CONFIG 0x13
/* Query information about VRAM and GTT domains */
#define AMDGPU_INFO_VRAM_GTT 0x14
/* Query information about register in MMR address space*/
#define AMDGPU_INFO_READ_MMR_REG 0x15
/* Query information about device: rev id, family, etc. */
#define AMDGPU_INFO_DEV_INFO 0x16
/* visible vram usage */
#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
/* number of TTM buffer evictions */
#define AMDGPU_INFO_NUM_EVICTIONS 0x18
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
#define AMDGPU_INFO_MMR_SH_INDEX_MASK 0xff
struct drm_amdgpu_query_fw {
/** AMDGPU_INFO_FW_* */
__u32 fw_type;
/**
* Index of the IP if there are more IPs of
* the same type.
*/
__u32 ip_instance;
/**
* Index of the engine. Whether this is used depends
* on the firmware type. (e.g. MEC, SDMA)
*/
__u32 index;
__u32 _pad;
};
/* Input structure for the INFO ioctl */
struct drm_amdgpu_info {
/* Where the return value will be stored */
__u64 return_pointer;
/* The size of the return value. Just like "size" in "snprintf",
* it limits how many bytes the kernel can write. */
__u32 return_size;
/* The query request id. */
__u32 query;
union {
struct {
__u32 id;
__u32 _pad;
} mode_crtc;
struct {
/** AMDGPU_HW_IP_* */
__u32 type;
/**
* Index of the IP if there are more IPs of the same
* type. Ignored by AMDGPU_INFO_HW_IP_COUNT.
*/
__u32 ip_instance;
} query_hw_ip;
struct {
__u32 dword_offset;
/** number of registers to read */
__u32 count;
__u32 instance;
/** For future use, no flags defined so far */
__u32 flags;
} read_mmr_reg;
struct drm_amdgpu_query_fw query_fw;
};
};
struct drm_amdgpu_info_gds {
/** GDS GFX partition size */
__u32 gds_gfx_partition_size;
/** GDS compute partition size */
__u32 compute_partition_size;
/** total GDS memory size */
__u32 gds_total_size;
/** GWS size per GFX partition */
__u32 gws_per_gfx_partition;
/** GSW size per compute partition */
__u32 gws_per_compute_partition;
/** OA size per GFX partition */
__u32 oa_per_gfx_partition;
/** OA size per compute partition */
__u32 oa_per_compute_partition;
__u32 _pad;
};
struct drm_amdgpu_info_vram_gtt {
__u64 vram_size;
__u64 vram_cpu_accessible_size;
__u64 gtt_size;
};
struct drm_amdgpu_info_firmware {
__u32 ver;
__u32 feature;
};
#define AMDGPU_VRAM_TYPE_UNKNOWN 0
#define AMDGPU_VRAM_TYPE_GDDR1 1
#define AMDGPU_VRAM_TYPE_DDR2 2
#define AMDGPU_VRAM_TYPE_GDDR3 3
#define AMDGPU_VRAM_TYPE_GDDR4 4
#define AMDGPU_VRAM_TYPE_GDDR5 5
#define AMDGPU_VRAM_TYPE_HBM 6
#define AMDGPU_VRAM_TYPE_DDR3 7
struct drm_amdgpu_info_device {
/** PCI Device ID */
__u32 device_id;
/** Internal chip revision: A0, A1, etc.) */
__u32 chip_rev;
__u32 external_rev;
/** Revision id in PCI Config space */
__u32 pci_rev;
__u32 family;
__u32 num_shader_engines;
__u32 num_shader_arrays_per_engine;
/* in KHz */
__u32 gpu_counter_freq;
__u64 max_engine_clock;
__u64 max_memory_clock;
/* cu information */
__u32 cu_active_number;
__u32 cu_ao_mask;
__u32 cu_bitmap[4][4];
/** Render backend pipe mask. One render backend is CB+DB. */
__u32 enabled_rb_pipes_mask;
__u32 num_rb_pipes;
__u32 num_hw_gfx_contexts;
__u32 _pad;
__u64 ids_flags;
/** Starting virtual address for UMDs. */
__u64 virtual_address_offset;
/** The maximum virtual address */
__u64 virtual_address_max;
/** Required alignment of virtual addresses. */
__u32 virtual_address_alignment;
/** Page table entry - fragment size */
__u32 pte_fragment_size;
__u32 gart_page_size;
/** constant engine ram size*/
__u32 ce_ram_size;
/** video memory type info*/
__u32 vram_type;
/** video memory bit width*/
__u32 vram_bit_width;
/* vce harvesting instance */
__u32 vce_harvest_config;
};
struct drm_amdgpu_info_hw_ip {
/** Version of h/w IP */
__u32 hw_ip_version_major;
__u32 hw_ip_version_minor;
/** Capabilities */
__u64 capabilities_flags;
/** command buffer address start alignment*/
__u32 ib_start_alignment;
/** command buffer size alignment*/
__u32 ib_size_alignment;
/** Bitmask of available rings. Bit 0 means ring 0, etc. */
__u32 available_rings;
__u32 _pad;
};
/*
* Supported GPU families
*/
#define AMDGPU_FAMILY_UNKNOWN 0
#define AMDGPU_FAMILY_SI 110 /* Hainan, Oland, Verde, Pitcairn, Tahiti */
#define AMDGPU_FAMILY_CI 120 /* Bonaire, Hawaii */
#define AMDGPU_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */
#define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */
#define AMDGPU_FAMILY_CZ 135 /* Carrizo, Stoney */
#if defined(__cplusplus)
}
#endif
#endif
-152
View File
@@ -1,152 +0,0 @@
/*
* Copyright 2005 Stephane Marchesin.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__
#define DRM_NOUVEAU_EVENT_NVIF 0x80000000
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3)
#define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4)
#define NOUVEAU_GEM_TILE_COMP 0x00030000 /* nv50-only */
#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00
#define NOUVEAU_GEM_TILE_16BPP 0x00000001
#define NOUVEAU_GEM_TILE_32BPP 0x00000002
#define NOUVEAU_GEM_TILE_ZETA 0x00000004
#define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008
struct drm_nouveau_gem_info {
__u32 handle;
__u32 domain;
__u64 size;
__u64 offset;
__u64 map_handle;
__u32 tile_mode;
__u32 tile_flags;
};
struct drm_nouveau_gem_new {
struct drm_nouveau_gem_info info;
__u32 channel_hint;
__u32 align;
};
#define NOUVEAU_GEM_MAX_BUFFERS 1024
struct drm_nouveau_gem_pushbuf_bo_presumed {
__u32 valid;
__u32 domain;
__u64 offset;
};
struct drm_nouveau_gem_pushbuf_bo {
__u64 user_priv;
__u32 handle;
__u32 read_domains;
__u32 write_domains;
__u32 valid_domains;
struct drm_nouveau_gem_pushbuf_bo_presumed presumed;
};
#define NOUVEAU_GEM_RELOC_LOW (1 << 0)
#define NOUVEAU_GEM_RELOC_HIGH (1 << 1)
#define NOUVEAU_GEM_RELOC_OR (1 << 2)
#define NOUVEAU_GEM_MAX_RELOCS 1024
struct drm_nouveau_gem_pushbuf_reloc {
__u32 reloc_bo_index;
__u32 reloc_bo_offset;
__u32 bo_index;
__u32 flags;
__u32 data;
__u32 vor;
__u32 tor;
};
#define NOUVEAU_GEM_MAX_PUSH 512
struct drm_nouveau_gem_pushbuf_push {
__u32 bo_index;
__u32 pad;
__u64 offset;
__u64 length;
};
struct drm_nouveau_gem_pushbuf {
__u32 channel;
__u32 nr_buffers;
__u64 buffers;
__u32 nr_relocs;
__u32 nr_push;
__u64 relocs;
__u64 push;
__u32 suffix0;
__u32 suffix1;
__u64 vram_available;
__u64 gart_available;
};
#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001
#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
struct drm_nouveau_gem_cpu_prep {
__u32 handle;
__u32 flags;
};
struct drm_nouveau_gem_cpu_fini {
__u32 handle;
};
#define DRM_NOUVEAU_GETPARAM 0x00 /* deprecated */
#define DRM_NOUVEAU_SETPARAM 0x01 /* deprecated */
#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02 /* deprecated */
#define DRM_NOUVEAU_CHANNEL_FREE 0x03 /* deprecated */
#define DRM_NOUVEAU_GROBJ_ALLOC 0x04 /* deprecated */
#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05 /* deprecated */
#define DRM_NOUVEAU_GPUOBJ_FREE 0x06 /* deprecated */
#define DRM_NOUVEAU_NVIF 0x07
#define DRM_NOUVEAU_GEM_NEW 0x40
#define DRM_NOUVEAU_GEM_PUSHBUF 0x41
#define DRM_NOUVEAU_GEM_CPU_PREP 0x42
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
#define DRM_NOUVEAU_GEM_INFO 0x44
#define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
#define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
#define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
#define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini)
#define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info)
#if defined(__cplusplus)
}
#endif
#endif /* __NOUVEAU_DRM_H__ */
+5 -59
View File
@@ -1,4 +1,4 @@
SERIAL_COMPATIBLE_API_VER = 1 ; increments in case of breaking changes
SERIAL_COMPATIBLE_API_VER = 0 ; increments in case of breaking changes
SERIAL_API_GET_VERSION = 0
SERIAL_API_SRV_ADD_PORT = 1
@@ -9,7 +9,6 @@ SERIAL_API_CLOSE_PORT = 5
SERIAL_API_SETUP_PORT = 6
SERIAL_API_READ = 7
SERIAL_API_WRITE = 8
SERIAL_API_ENUM_PORTS = 9
SERIAL_API_ERR_PORT_INVALID = 1
SERIAL_API_ERR_PORT_BUSY = 2
@@ -30,9 +29,6 @@ SERIAL_CONF_STOP_BITS_2 = 2
SERIAL_CONF_FLOW_CTRL_NONE = 0
SERIAL_INFO_DRIVER_LEN = 16
SERIAL_INFO_DESCR_LEN = 64
struct SP_DRIVER
size dd ? ; size of this struct
startup dd ? ; int __stdcall (*startup)(void *drv_data, const struct serial_conf *conf);
@@ -50,20 +46,7 @@ struct SP_CONF
flow_ctrl db ?
ends
struct SP_PORT_INFO
size dd ? ; size of this struct
driver dd ? ; ASCIIZ driver name, e.g. "uart16550", "usb-cdc"
descr dd ? ; ASCIIZ description, may be NULL
ends
struct SP_PORT_ENUM_ENTRY
id dd ? ; unique port number (SERIAL_PORT.id)
busy dd ? ; 0 = free, non-zero = port is opened
driver rb SERIAL_INFO_DRIVER_LEN
descr rb SERIAL_INFO_DESCR_LEN
ends
proc serial_add_port stdcall, drv:dword, drv_data:dword, info:dword
proc serial_add_port stdcall, drv:dword, drv_data:dword
locals
handler dd ?
io_code dd ?
@@ -77,7 +60,7 @@ endl
mov [io_code], SERIAL_API_SRV_ADD_PORT
lea eax, [drv]
mov [input], eax
mov [inp_size], 12
mov [inp_size], 8
xor eax, eax
mov [output], eax
mov [out_size], eax
@@ -146,7 +129,7 @@ proc serial_port_init
ret
endp
proc serial_port_get_version stdcall uses ebx, version:dword
proc serial_port_get_version stdcall, version:dword
locals
.handler dd ?
.io_code dd ?
@@ -166,7 +149,7 @@ endl
lea ecx, [.handler]
mcall SF_SYS_MISC, SSF_CONTROL_DRIVER
ret
endp
@@ -314,43 +297,6 @@ endl
ret
endp
proc serial_port_enum stdcall uses ebx, buf:dword, buf_size:dword, \
total:dword, filled:dword
locals
.handler dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
endl
push [buf_size]
push [buf]
mov eax, [serial_drv_handle]
mov [.handler], eax
mov dword [.io_code], SERIAL_API_ENUM_PORTS
mov [.input], esp
mov dword [.inp_size], 8
sub esp, 8
mov [.output], esp
mov dword [.out_size], 8
lea ecx, [.handler]
mcall SF_SYS_MISC, SSF_CONTROL_DRIVER
pop ebx edx
cmp eax, -1
je .err
mov ecx, [total]
mov [ecx], ebx
mov ecx, [filled]
mov [ecx], edx
.err:
add esp, 8
ret
endp
align 4
serial_drv_name db "SERIAL", 0
serial_drv_handle dd ?
+5
View File
@@ -0,0 +1,5 @@
#SHS
echo Installing serial driver for kterm...
cp /kolibrios/utils/kterm/serial.sys /sys/drivers/
/sys/loaddrv serial
echo Serial driver successfully installed!
+7 -148
View File
@@ -44,8 +44,6 @@ struct SERIAL_PORT
rx_buf RING_BUF
tx_buf RING_BUF
conf SP_CONF
driver rb SERIAL_INFO_DRIVER_LEN ; ASCIIZ, copied from SP_PORT_INFO.driver in add_port
descr rb SERIAL_INFO_DESCR_LEN ; ASCIIZ, copied from SP_PORT_INFO.descr in add_port (may be empty)
ends
proc START c, reason:dword, cmdline:dword
@@ -59,7 +57,7 @@ proc START c, reason:dword, cmdline:dword
stdcall uart_probe, 0x2f8, 3
stdcall uart_probe, 0x3e8, 4
stdcall uart_probe, 0x2e8, 3
invoke RegService, serial_drv_name, service_proc
invoke RegService, drv_name, service_proc
ret
.fail:
@@ -77,7 +75,7 @@ srv_calls:
dd service_proc.setup
dd service_proc.read
dd service_proc.write
dd service_proc.enum_ports
; TODO enumeration
srv_calls_end:
proc service_proc stdcall uses ebx esi edi, ioctl:dword
@@ -99,13 +97,11 @@ proc service_proc stdcall uses ebx esi edi, ioctl:dword
; in:
; +0: driver
; +4: driver data
; +8: port info (SP_PORT_INFO*)
cmp [edx + IOCTL.inp_size], 12
cmp [edx + IOCTL.inp_size], 8
jb .err
mov ebx, [edx + IOCTL.input]
mov ecx, [ebx]
mov edx, [ebx + 4]
mov ebx, [ebx + 8]
call add_port
ret
@@ -141,7 +137,6 @@ proc service_proc stdcall uses ebx esi edi, ioctl:dword
; +4 addr to SERIAL_CONF
; out:
; +0 port handle if success
; eax = 0 if success, otherwise an error code SERIAL_API_ERR_*
cmp [edx + IOCTL.inp_size], 8
jb .err
cmp [edx + IOCTL.out_size], 4
@@ -225,60 +220,25 @@ proc service_proc stdcall uses ebx esi edi, ioctl:dword
mov [ebx], ecx
ret
.enum_ports:
; in:
; +0 output buffer (array of SP_PORT_ENUM_ENTRY), may be NULL
; +4 output buffer size in bytes
; out:
; +0 total number of ports in the system
; +4 number of entries actually filled into the buffer
; eax = 0 if success, -1 otherwise
cmp [edx + IOCTL.inp_size], 8
jb .err
cmp [edx + IOCTL.out_size], 8
jb .err
mov ebx, [edx + IOCTL.input]
push edx
mov eax, [ebx]
mov edx, [ebx + 4]
call sp_enum
pop edx
mov ebx, [edx + IOCTL.output]
mov [ebx], eax
mov [ebx + 4], ecx
xor eax, eax
ret
.err:
or eax, -1
ret
endp
; struct SERIAL_PORT __fastcall *add_port(const struct SP_DRIVER *drv, const void *drv_data);
align 4
; @param ecx pointer to SP_DRIVER
; @param edx driver-specific argument
; @param ebx pointer to SP_PORT_INFO
; @return SERIAL_PORT descriptor
proc add_port uses edi
DEBUGF L_DBG, "serial.sys: add port drv=%x drv_data=%x info=%x\n", ecx, edx, ebx
DEBUGF L_DBG, "serial.sys: add port drv=%x drv_data=%x\n", ecx, edx
mov eax, [ecx + SP_DRIVER.size]
cmp eax, sizeof.SP_DRIVER
jne .fail
test ebx, ebx
jz .fail
mov eax, [ebx + SP_PORT_INFO.size]
cmp eax, sizeof.SP_PORT_INFO
jne .fail
; alloc memory for serial port descriptor
push ecx
push edx
push ebx
movi eax, sizeof.SERIAL_PORT
invoke Kmalloc
pop ebx
pop edx
pop ecx
test eax, eax
@@ -292,17 +252,6 @@ proc add_port uses edi
invoke MutexInit
and [edi + SERIAL_PORT.con], 0
; copy port info strings
mov eax, [ebx + SP_PORT_INFO.driver]
lea edx, [edi + SERIAL_PORT.driver]
mov ecx, SERIAL_INFO_DRIVER_LEN
call copy_bounded_str
mov eax, [ebx + SP_PORT_INFO.descr]
lea edx, [edi + SERIAL_PORT.descr]
mov ecx, SERIAL_INFO_DESCR_LEN
call copy_bounded_str
mov ecx, port_list_mutex
invoke MutexLock
@@ -333,35 +282,7 @@ proc add_port uses edi
endp
align 4
; copies an ASCIIZ string into a fixed-size buffer: copies up to (size - 1)
; bytes or until the NUL, then zero-pads the rest of the buffer
; @param eax source ASCIIZ ptr, may be NULL
; @param edx dest buffer ptr
; @param ecx dest buffer size in bytes, must be >= 1
proc copy_bounded_str uses esi edi
mov esi, eax
mov edi, edx
dec ecx ; reserve the last byte for the NUL terminator
.copy:
test ecx, ecx
jz .pad
test esi, esi
jz .pad
lodsb
test al, al
jz .pad
stosb
dec ecx
jmp .copy
.pad:
inc ecx ; account for the reserved NUL byte
xor al, al
rep stosb
ret
endp
align 4
; @param ecx serial port descriptor
; u32 __fastcall *remove_port(struct SERIAL_PORT *port);
proc remove_port uses esi
mov esi, ecx
mov ecx, port_list_mutex
@@ -736,69 +657,7 @@ proc sp_write
ret
endp
align 4
; @param eax buf
; @param edx buf_size (bytes)
; @return eax total port count in the system
; ecx entries filled into buf
proc sp_enum uses ebx esi edi
mov ecx, eax
mov eax, edx
xor edx, edx
mov ebx, sizeof.SP_PORT_ENUM_ENTRY
div ebx
; eax max entries count
mov edi, ecx
imul eax, sizeof.SP_PORT_ENUM_ENTRY
add eax, ecx
mov edx, eax ; end-of-buffer boundary
xor ebx, ebx ; total port count
xor ecx, ecx ; filled count
push ecx edx
mov ecx, port_list_mutex
invoke MutexLock
pop edx ecx
mov esi, port_list
.next:
mov esi, [esi + SERIAL_PORT.fd]
cmp esi, port_list
jz .done
inc ebx
cmp edi, edx
jae .next
mov eax, [esi + SERIAL_PORT.id]
mov [edi + SP_PORT_ENUM_ENTRY.id], eax
xor eax, eax
cmp dword [esi + SERIAL_PORT.con], 0
setnz al
mov [edi + SP_PORT_ENUM_ENTRY.busy], eax
push ecx esi edi
lea esi, [esi + SERIAL_PORT.driver]
lea edi, [edi + SP_PORT_ENUM_ENTRY.driver]
mov ecx, (SERIAL_INFO_DRIVER_LEN + SERIAL_INFO_DESCR_LEN) / 4
rep movsd
pop edi esi ecx
add edi, sizeof.SP_PORT_ENUM_ENTRY
inc ecx
jmp .next
.done:
push ecx
mov ecx, port_list_mutex
invoke MutexUnlock
pop ecx
mov eax, ebx
ret
endp
drv_name db 'SERIAL', 0
include_debug_strings
align 4
-9
View File
@@ -169,7 +169,6 @@ proc uart_probe stdcall uses ebx esi edi, io_addr:dword, irqn:dword
; register port
lea ecx, [uart_drv]
mov edx, edi
lea ebx, [uart_port_info]
call add_port
test eax, eax
jz .free_desc ; TODO detach_int_handler?
@@ -407,11 +406,3 @@ uart_drv:
dd uart_reconf
dd uart_tx
uart_drv_end:
align 4
uart_port_info:
dd uart_port_end - uart_port_info
dd uart_port_name
dd 0
uart_port_end:
uart_port_name db 'uart16550', 0
+310 -203
View File
@@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2026. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; FTDI chips driver for KolibriOS ;;
@@ -15,11 +15,10 @@
format PE DLL native 0.05
entry START
L_DBG = 1
L_ERR = 2
DEBUG = 1
__DEBUG__ = 1
__DEBUG_LEVEL__ = L_ERR
__DEBUG_LEVEL__ = 1
node equ ftdi_context
node.next equ ftdi_context.next_context
@@ -123,10 +122,9 @@ TYPE_232H=6
TYPE_230X=7
;strings
my_driver db 'usbftdi',0
my_driver db 'usbother',0
serial_driver db 'SERIAL',0
nomemory_msg db 'ftdi: no memory',13,10,0
ftdi_port_name db 'ftdi',0
nomemory_msg db 'K : no memory',13,10,0
; Structures
struct ftdi_context
@@ -202,13 +200,10 @@ endp
proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
locals
.pinfo rb sizeof.SP_PORT_INFO
endl
invoke USBGetParam, [.config_pipe], 0
mov edx, eax
DEBUGF L_DBG, 'ftdi: Detected device vendor: 0x%x\n', [eax+usb_descr.idVendor]
DEBUGF 2,'K : Detected device vendor: 0x%x\n', [eax+usb_descr.idVendor]
cmp word[eax+usb_descr.idVendor], 0x0403
jnz .notftdi
mov eax, sizeof.ftdi_context
@@ -219,7 +214,7 @@ endl
invoke SysMsgBoardStr
jmp .nothing
@@:
DEBUGF L_DBG, 'ftdi: Adding struct to list 0x%x\n', eax
DEBUGF 2,'K : Adding struct to list 0x%x\n', eax
call linkedlist_add
mov ebx, [.config_pipe]
@@ -238,7 +233,7 @@ endl
jmp .slow
mov cx, [edx+usb_descr.bcdDevice]
DEBUGF L_DBG, 'ftdi: Chip type 0x%x\n', ecx
DEBUGF 2, 'K : Chip type 0x%x\n', ecx
cmp cx, 0x400
jnz @f
mov [eax + ftdi_context.chipType], TYPE_BM
@@ -292,13 +287,8 @@ endl
mov eax, [serial_drv_entry]
test eax, eax
jz @f
mov dword [.pinfo + SP_PORT_INFO.size], sizeof.SP_PORT_INFO
mov dword [.pinfo + SP_PORT_INFO.driver], ftdi_port_name
; TODO obtain iManufacturer, iProduct and iSerial strings
mov dword [.pinfo + SP_PORT_INFO.descr], 0
lea ecx, [.pinfo]
stdcall serial_add_port, uart_drv, ebx, ecx
DEBUGF L_DBG, 'ftdi: add serial port with result %x\n', eax
stdcall serial_add_port, uart_drv, ebx
DEBUGF 1, "usbftdi: add serial port with result %x\n", eax
@@:
mov [ebx + ftdi_context.port_handle], eax
@@ -306,7 +296,7 @@ endl
ret
.notftdi:
DEBUGF L_DBG, 'ftdi: Skipping not FTDI device\n'
DEBUGF 1,'K : Skipping not FTDI device\n'
.nothing:
xor eax, eax
ret
@@ -327,7 +317,7 @@ EventData rd 3
endl
mov edi, [ioctl]
mov eax, [edi+io_code]
DEBUGF L_DBG, 'ftdi: FTDI got the request: %d\n', eax
DEBUGF 1,'K : FTDI got the request: %d\n', eax
test eax, eax ;0
jz .version
dec eax ;1
@@ -426,7 +416,7 @@ endl
.version:
jmp .endswitch
.error:
DEBUGF L_ERR, 'ftdi: error occured! %d\n', eax
DEBUGF 1, 'K : FTDI error occured! %d\n', eax
;mov esi, [edi+output]
;mov [esi], dword 'ERR0'
;or [esi], eax
@@ -459,7 +449,7 @@ endl
mov word[ConfPacket+6], cx
.own_index:
mov ebx, [edi+4]
DEBUGF L_DBG, 'ftdi: ConfPacket 0x%x 0x%x\n', [ConfPacket], [ConfPacket+4]
DEBUGF 2,'K : ConfPacket 0x%x 0x%x\n', [ConfPacket], [ConfPacket+4]
lea esi, [ConfPacket]
lea edi, [EventData]
invoke USBControlTransferAsync, [ebx + ftdi_context.nullP], esi, 0,\
@@ -475,7 +465,7 @@ endl
jmp .error
.ftdi_setrtshigh:
DEBUGF L_DBG, 'ftdi: Setting RTS pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2,'K : FTDI Setting RTS pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
@@ -483,7 +473,7 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_setrtslow:
DEBUGF L_DBG, 'ftdi: Setting RTS pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2,'K : FTDI Setting RTS pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
@@ -491,7 +481,7 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_setdtrhigh:
DEBUGF L_DBG, 'ftdi: Setting DTR pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2,'K : FTDI Setting DTR pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
@@ -499,7 +489,7 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_setdtrlow:
DEBUGF L_DBG, 'ftdi: Setting DTR pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2,'K : FTDI Setting DTR pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
@@ -507,7 +497,7 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_usb_reset:
DEBUGF L_DBG, 'ftdi: Reseting PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2,'K : FTDI Reseting PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_RESET_REQUEST shl 8) \
@@ -515,7 +505,7 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_purge_rx_buf:
DEBUGF L_DBG, 'ftdi: Purge TX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Purge TX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_RESET_REQUEST shl 8) \
@@ -523,7 +513,7 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_purge_tx_buf:
DEBUGF L_DBG, 'ftdi: Purge RX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Purge RX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_RESET_REQUEST shl 8) \
@@ -531,42 +521,42 @@ endl
jmp .ftdi_out_control_transfer_noinp
.ftdi_set_bitmode:
DEBUGF L_DBG, 'ftdi: Set bitmode 0x%x, bitmask 0x%x %d PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set bitmode 0x%x, bitmask 0x%x %d PID: %d Dev handler 0x0x%x\n', \
[edi+8]:2,[edi+10]:2,[edi],[edi+4]
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_BITMODE_REQUEST shl 8)
jmp .ftdi_out_control_transfer_withinp
.ftdi_set_line_property:
DEBUGF L_DBG, 'ftdi: Set line property 0x%x PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set line property 0x%x PID: %d Dev handler 0x0x%x\n', \
[edi+8]:4,[edi],[edi+4]
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_DATA_REQUEST shl 8)
jmp .ftdi_out_control_transfer_withinp
.ftdi_set_latency_timer:
DEBUGF L_DBG, 'ftdi: Set latency %d PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set latency %d PID: %d Dev handler 0x0x%x\n', \
[edi+8],[edi],[edi+4]
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_LATENCY_TIMER_REQUEST shl 8)
jmp .ftdi_out_control_transfer_withinp
.ftdi_set_event_char:
DEBUGF L_DBG, 'ftdi: Set event char %c PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set event char %c PID: %d Dev handler 0x0x%x\n', \
[edi+8],[edi],[edi+4]
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_EVENT_CHAR_REQUEST shl 8)
jmp .ftdi_out_control_transfer_withinp
.ftdi_set_error_char:
DEBUGF L_DBG, 'ftdi: Set error char %c PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set error char %c PID: %d Dev handler 0x0x%x\n', \
[edi+8],[edi],[edi+4]
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_ERROR_CHAR_REQUEST shl 8)
jmp .ftdi_out_control_transfer_withinp
.ftdi_setflowctrl:
DEBUGF L_DBG, 'ftdi: Set flow control PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Set flow control PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_FLOW_CTRL_REQUEST shl 8) + (0 shl 16)
@@ -579,7 +569,7 @@ endl
jmp .own_index
.ftdi_read_pins:
DEBUGF L_DBG, 'ftdi: Read pins PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Read pins PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov ebx, [edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_IN_REQTYPE) \
@@ -608,7 +598,7 @@ endl
jmp .error
.ftdi_set_wchunksize:
DEBUGF L_DBG, 'ftdi: Set write chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set write chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
[edi+8], [edi], [edi+4]
mov ebx, [edi+4]
mov ecx, [edi+8]
@@ -618,7 +608,7 @@ endl
jmp .endswitch
.ftdi_get_wchunksize:
DEBUGF L_DBG, 'ftdi: Get write chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Get write chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov esi, [edi+output]
mov edi, [edi+input]
@@ -628,7 +618,7 @@ endl
jmp .endswitch
.ftdi_set_rchunksize:
DEBUGF L_DBG, 'ftdi: Set read chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
DEBUGF 2, 'K : FTDI Set read chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
[edi+8], [edi], [edi+4]
mov ebx, [edi+4]
mov ecx, [edi+8]
@@ -638,7 +628,7 @@ endl
jmp .endswitch
.ftdi_get_rchunksize:
DEBUGF L_DBG, 'ftdi: Get read chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Get read chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov esi, [edi+output]
mov edi, [edi+input]
@@ -648,7 +638,7 @@ endl
jmp .endswitch
.ftdi_write_data:
DEBUGF L_DBG, 'ftdi: Write %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
DEBUGF 2, 'K : FTDI Write %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
[edi], [edi+4]
mov esi, edi
add esi, 12
@@ -695,7 +685,7 @@ endl
jmp .write_loop
.ftdi_read_data:
DEBUGF L_DBG, 'ftdi: Read %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
DEBUGF 2, 'K : FTDI Read %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
[edi], [edi+4]
mov edi, [ioctl]
mov esi, [edi+input]
@@ -753,7 +743,7 @@ endl
;---Dirty hack end
.ftdi_poll_modem_status:
DEBUGF L_DBG, 'ftdi: Poll modem status PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Poll modem status PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov ebx, [edi+4]
mov dword[ConfPacket], (FTDI_DEVICE_IN_REQTYPE) \
@@ -777,7 +767,7 @@ endl
jmp .endswitch
.ftdi_get_latency_timer:
DEBUGF L_DBG, 'ftdi: Get latency timer PID: %d Dev handler 0x0x%x\n', [edi],\
DEBUGF 2, 'K : FTDI Get latency timer PID: %d Dev handler 0x0x%x\n', [edi],\
[edi+4]
mov ebx, [edi+4]
mov dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE \
@@ -797,7 +787,7 @@ endl
jmp .endswitch
.ftdi_get_list:
DEBUGF L_DBG, 'ftdi: devices list request\n'
DEBUGF 2, 'K : FTDI devices list request\n'
mov edi, [edi+output]
xor ecx, ecx
call linkedlist_gethead
@@ -827,7 +817,7 @@ endl
jmp .endswitch
.ftdi_lock:
DEBUGF L_DBG, 'ftdi: Lock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
DEBUGF 2, 'K : FTDI Lock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
mov esi, [edi+input]
mov ebx, [esi+4]
mov eax, [ebx + ftdi_context.lockPID]
@@ -841,7 +831,7 @@ endl
jmp .endswitch
.ftdi_unlock:
DEBUGF L_DBG, 'ftdi: Unlock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
DEBUGF 2, 'K : FTDI Unlock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
mov esi, [edi+input]
mov edi, [edi+output]
mov ebx, [esi+4]
@@ -855,19 +845,145 @@ endl
mov [edi], eax
jmp .endswitch
H_CLK = 120000000
C_CLK = 48000000
.ftdi_set_baudrate:
DEBUGF L_DBG, 'ftdi: Set baudrate to %d PID: %d Dev handle: 0x%x\n',\
DEBUGF 2, 'K : FTDI Set baudrate to %d PID: %d Dev handle: 0x%x\n',\
[edi+8], [edi], [edi+4]
mov ebx, [edi+4]
mov esi, [edi+8]
call ftdi_calc_baud_divisor
cmp [ebx + ftdi_context.chipType], TYPE_2232H
jl .c_clk
imul eax, [edi+8], 10
cmp eax, H_CLK / 0x3FFF
jle .c_clk
.h_clk:
cmp dword[edi+8], H_CLK/10
jl .h_nextbaud1
xor edx, edx
mov ecx, H_CLK/10
jmp .calcend
.c_clk:
cmp dword[edi+8], C_CLK/16
jl .c_nextbaud1
xor edx, edx
mov ecx, C_CLK/16
jmp .calcend
.h_nextbaud1:
cmp dword[edi+8], H_CLK/(10 + 10/2)
jl .h_nextbaud2
mov edx, 1
mov ecx, H_CLK/(10 + 10/2)
jmp .calcend
.c_nextbaud1:
cmp dword[edi+8], C_CLK/(16 + 16/2)
jl .c_nextbaud2
mov edx, 1
mov ecx, C_CLK/(16 + 16/2)
jmp .calcend
.h_nextbaud2:
cmp dword[edi+8], H_CLK/(2*10)
jl .h_nextbaud3
mov edx, 2
mov ecx, H_CLK/(2*10)
jmp .calcend
.c_nextbaud2:
cmp dword[edi+8], C_CLK/(2*16)
jl .c_nextbaud3
mov edx, 2
mov ecx, C_CLK/(2*16)
jmp .calcend
.h_nextbaud3:
mov eax, H_CLK*16/10 ; eax - best_divisor
xor edx, edx
div dword[edi+8] ; [edi+8] - baudrate
push eax
and eax, 1
pop eax
shr eax, 1
jz .h_rounddowndiv ; jump by result of and eax, 1
inc eax
.h_rounddowndiv:
cmp eax, 0x20000
jle .h_best_divok
mov eax, 0x1FFFF
.h_best_divok:
mov ecx, eax
mov eax, H_CLK*16/10
xor edx, edx
div ecx
xchg ecx, eax ; ecx - best_baud
push ecx
and ecx, 1
pop ecx
shr ecx, 1
jz .rounddownbaud
inc ecx
jmp .rounddownbaud
.c_nextbaud3:
mov eax, C_CLK ; eax - best_divisor
xor edx, edx
div dword[edi+8] ; [edi+8] - baudrate
push eax
and eax, 1
pop eax
shr eax, 1
jnz .c_rounddowndiv ; jump by result of and eax, 1
inc eax
.c_rounddowndiv:
cmp eax, 0x20000
jle .c_best_divok
mov eax, 0x1FFFF
.c_best_divok:
mov ecx, eax
mov eax, C_CLK
xor edx, edx
div ecx
xchg ecx, eax ; ecx - best_baud
push ecx
and ecx, 1
pop ecx
shr ecx, 1
jnz .rounddownbaud
inc ecx
.rounddownbaud:
mov edx, eax ; edx - encoded_divisor
shr edx, 3
and eax, 0x7
push 7 6 5 1 4 2 3 0
mov eax, [esp+eax*4]
shl eax, 14
or edx, eax
add esp, 32
.calcend:
mov eax, edx ; eax - *value
mov ecx, edx ; ecx - *index
and eax, 0xFFFF
cmp [ebx + ftdi_context.chipType], TYPE_2232H
jge .foxyindex
shr ecx, 16
jmp .preparepacket
.foxyindex:
shr ecx, 8
and ecx, 0xFF00
or ecx, [ebx + ftdi_context.index]
.preparepacket:
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_BAUDRATE_REQUEST shl 8)
mov word[ConfPacket+2], ax
mov word[ConfPacket+4], cx
mov word[ConfPacket+6], 0
jmp .own_index
jmp .own_index
endp
restore handle
restore io_code
@@ -877,143 +993,10 @@ restore output
restore out_size
proc ftdi_calc_baud_divisor
; in: ebx = ftdi_context pointer
; esi = baud rate
; out: ax = encoded value
; cx = encoded index
; destroys: eax, ecx, edx, esi
cmp [ebx + ftdi_context.chipType], TYPE_2232H
jl .c_clk
imul eax, esi, 10
cmp eax, H_CLK / 0x3FFF
jle .c_clk
.h_clk:
cmp esi, H_CLK / 10
jl .h_nextbaud1
xor edx, edx
mov ecx, H_CLK / 10
jmp .calcend
.c_clk:
cmp esi, C_CLK / 16
jl .c_nextbaud1
xor edx, edx
mov ecx, C_CLK / 16
jmp .calcend
.h_nextbaud1:
cmp esi, H_CLK / (10 + 10 / 2)
jl .h_nextbaud2
mov edx, 1
mov ecx, H_CLK / (10 + 10 / 2)
jmp .calcend
.c_nextbaud1:
cmp esi, C_CLK / (16 + 16 / 2)
jl .c_nextbaud2
mov edx, 1
mov ecx, C_CLK/(16 + 16 / 2)
jmp .calcend
.h_nextbaud2:
cmp esi, H_CLK / (2 * 10)
jl .h_nextbaud3
mov edx, 2
mov ecx, H_CLK / (2 * 10)
jmp .calcend
.c_nextbaud2:
cmp esi, C_CLK / (2 * 16)
jl .c_nextbaud3
mov edx, 2
mov ecx, C_CLK / (2 * 16)
jmp .calcend
.h_nextbaud3:
mov eax, H_CLK * 16 / 10 ; eax - best_divisor
xor edx, edx
div esi
push eax
and eax, 1
pop eax
shr eax, 1
jz .h_rounddowndiv ; jump by result of and eax, 1
inc eax
.h_rounddowndiv:
cmp eax, 0x20000
jle .h_best_divok
mov eax, 0x1FFFF
.h_best_divok:
mov ecx, eax
mov eax, H_CLK * 16 / 10
xor edx, edx
div ecx
xchg ecx, eax ; ecx - best_baud
push ecx
and ecx, 1
pop ecx
shr ecx, 1
jz .rounddownbaud
inc ecx
jmp .rounddownbaud
.c_nextbaud3:
mov eax, C_CLK ; eax - best_divisor
xor edx, edx
div esi
push eax
and eax, 1
pop eax
shr eax, 1
jnz .c_rounddowndiv ; jump by result of and eax, 1
inc eax
.c_rounddowndiv:
cmp eax, 0x20000
jle .c_best_divok
mov eax, 0x1FFFF
.c_best_divok:
mov ecx, eax
mov eax, C_CLK
xor edx, edx
div ecx
xchg ecx, eax ; ecx - best_baud
push ecx
and ecx, 1
pop ecx
shr ecx, 1
jnz .rounddownbaud
inc ecx
.rounddownbaud:
mov edx, eax ; edx - encoded_divisor
shr edx, 3
and eax, 0x7
push 7 6 5 1 4 2 3 0
mov eax, [esp + eax * 4]
shl eax, 14
or edx, eax
add esp, 32
.calcend:
mov eax, edx ; eax - *value
mov ecx, edx ; ecx - *index
and eax, 0xFFFF
cmp [ebx + ftdi_context.chipType], TYPE_2232H
jge .foxyindex
shr ecx, 16
ret
.foxyindex:
shr ecx, 8
and ecx, 0xFF00
or ecx, [ebx + ftdi_context.index]
ret
endp
proc control_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
.buffer:DWORD, .length:DWORD, .calldata:DWORD
DEBUGF L_DBG, 'ftdi: status is %d\n', [.status]
DEBUGF 1, 'K : status is %d\n', [.status]
mov ecx, [.calldata]
mov eax, [ecx]
mov ebx, [ecx+4]
@@ -1028,7 +1011,7 @@ endp
proc bulk_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
.buffer:DWORD, .length:DWORD, .calldata:DWORD
DEBUGF L_DBG, 'ftdi: status is %d\n', [.status]
DEBUGF 1, 'K : status is %d\n', [.status]
mov ecx, [.calldata]
mov eax, [ecx]
mov ebx, [ecx+4]
@@ -1051,7 +1034,7 @@ endp
proc DeviceDisconnected stdcall uses ebx esi edi, .device_data:DWORD
DEBUGF L_DBG, 'ftdi: deleting device data 0x%x\n', [.device_data]
DEBUGF 1, 'K : FTDI deleting device data 0x%x\n', [.device_data]
mov esi, [.device_data]
mov eax, [esi + ftdi_context.readBufPtr]
test eax, eax
@@ -1079,7 +1062,7 @@ proc bulk_in_complete stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
mov eax, [.status]
test eax, eax
jz @f
DEBUGF L_ERR, 'ftdi: bulk in error %x\n', eax
DEBUGF 2, 'ftdi: bulk in error %x\n', eax
@@:
mov ebx, [.calldata]
btr dword [ebx + ftdi_context.writeBufLock], 0
@@ -1092,7 +1075,7 @@ proc bulk_out_complete stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
mov eax, [.status]
test eax, eax
jz @f
DEBUGF L_ERR, 'ftdi: bulk out error %x\n', eax
DEBUGF 2, 'ftdi: bulk out error %x\n', eax
@@:
mov ebx, [.calldata]
mov ecx, [.length]
@@ -1109,18 +1092,18 @@ proc bulk_out_complete stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
endp
proc uart_startup stdcall uses ebx, data:dword, conf:dword
DEBUGF L_DBG, "ftdi: startup %x %x\n", [data], [conf]
DEBUGF 1, "ftdi: startup %x %x\n", [data], [conf]
stdcall uart_reconf, [data], [conf]
test eax, eax
jz @f
DEBUGF L_ERR, "ftdi: uart reconf error %x\n", eax
DEBUGF 2, "ftdi: uart reconf error %x\n", eax
jmp .exit
@@:
mov ebx, [data]
invoke TimerHS, 2, 2, uart_rx, ebx
test eax, eax
jnz @f
DEBUGF L_ERR, "ftdi: timer creation error\n"
DEBUGF 2, "ftdi: timer creation error\n"
or eax, -1
jmp .exit
@@:
@@ -1131,7 +1114,7 @@ proc uart_startup stdcall uses ebx, data:dword, conf:dword
endp
proc uart_shutdown stdcall uses ebx, data:dword
DEBUGF L_DBG, "ftdi: shutdown %x\n", [data]
DEBUGF 1, "ftdi: shutdown %x\n", [data]
mov ebx, [data]
cmp [ebx + ftdi_context.rx_timer], 0
jz @f
@@ -1263,14 +1246,137 @@ proc uart_rx stdcall uses ebx esi, data:dword
ret
endp
proc ftdi_set_baudrate stdcall uses ebx esi, dev:dword, baud:dword
proc ftdi_set_baudrate stdcall uses ebx, dev:dword, baud:dword
locals
ConfPacket rb 8
endl
mov ebx, [dev]
mov esi, [baud]
call ftdi_calc_baud_divisor
cmp [ebx + ftdi_context.chipType], TYPE_2232H
jl .c_clk
imul eax, [baud], 10
cmp eax, H_CLK / 0x3FFF
jle .c_clk
.h_clk:
cmp dword [baud], H_CLK / 10
jl .h_nextbaud1
xor edx, edx
mov ecx, H_CLK / 10
jmp .calcend
.c_clk:
cmp dword [baud], C_CLK / 16
jl .c_nextbaud1
xor edx, edx
mov ecx, C_CLK / 16
jmp .calcend
.h_nextbaud1:
cmp dword [baud], H_CLK / (10 + 10 / 2)
jl .h_nextbaud2
mov edx, 1
mov ecx, H_CLK / (10 + 10 / 2)
jmp .calcend
.c_nextbaud1:
cmp dword [baud], C_CLK / (16 + 16 / 2)
jl .c_nextbaud2
mov edx, 1
mov ecx, C_CLK/(16 + 16 / 2)
jmp .calcend
.h_nextbaud2:
cmp dword [baud], H_CLK / (2 * 10)
jl .h_nextbaud3
mov edx, 2
mov ecx, H_CLK / (2 * 10)
jmp .calcend
.c_nextbaud2:
cmp dword [baud], C_CLK / (2 * 16)
jl .c_nextbaud3
mov edx, 2
mov ecx, C_CLK / (2 * 16)
jmp .calcend
.h_nextbaud3:
mov eax, H_CLK * 16 / 10 ; eax - best_divisor
xor edx, edx
div dword [baud]
push eax
and eax, 1
pop eax
shr eax, 1
jz .h_rounddowndiv ; jump by result of and eax, 1
inc eax
.h_rounddowndiv:
cmp eax, 0x20000
jle .h_best_divok
mov eax, 0x1FFFF
.h_best_divok:
mov ecx, eax
mov eax, H_CLK * 16 / 10
xor edx, edx
div ecx
xchg ecx, eax ; ecx - best_baud
push ecx
and ecx, 1
pop ecx
shr ecx, 1
jz .rounddownbaud
inc ecx
jmp .rounddownbaud
.c_nextbaud3:
mov eax, C_CLK ; eax - best_divisor
xor edx, edx
div dword [baud]
push eax
and eax, 1
pop eax
shr eax, 1
jnz .c_rounddowndiv ; jump by result of and eax, 1
inc eax
.c_rounddowndiv:
cmp eax, 0x20000
jle .c_best_divok
mov eax, 0x1FFFF
.c_best_divok:
mov ecx, eax
mov eax, C_CLK
xor edx, edx
div ecx
xchg ecx, eax ; ecx - best_baud
push ecx
and ecx, 1
pop ecx
shr ecx, 1
jnz .rounddownbaud
inc ecx
.rounddownbaud:
mov edx, eax ; edx - encoded_divisor
shr edx, 3
and eax, 0x7
push 7 6 5 1 4 2 3 0
mov eax, [esp + eax * 4]
shl eax, 14
or edx, eax
add esp, 32
.calcend:
mov eax, edx ; eax - *value
mov ecx, edx ; ecx - *index
and eax, 0xFFFF
cmp [ebx + ftdi_context.chipType], TYPE_2232H
jge .foxyindex
shr ecx, 16
jmp .preparepacket
.foxyindex:
shr ecx, 8
and ecx, 0xFF00
or ecx, [ebx + ftdi_context.index]
.preparepacket:
mov word [ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
+ (SIO_SET_BAUDRATE_REQUEST shl 8)
mov word [ConfPacket + 2], ax
@@ -1345,9 +1451,10 @@ uart_drv:
dd uart_tx
uart_drv_end:
include_debug_strings
serial_drv_entry dd 0
data fixups
end data
serial_drv_entry dd ?
;for DEBUGF macro
include_debug_strings
+1 -10
View File
@@ -2204,9 +2204,6 @@ proc acm_arm_rx
endp
proc acm_add_device stdcall uses ebx esi edi, .pipe0:dword, .config:dword, .interface:dword
locals
.pinfo rb sizeof.SP_PORT_INFO
endl
; 1. Parse the descriptors (the ACM data interface is alt setting 0).
xor eax, eax
@@ -2267,12 +2264,7 @@ endl
cmp [serial_drv_entry], 0
je .no_serial
mov dword [.pinfo+SP_PORT_INFO.size], sizeof.SP_PORT_INFO
mov dword [.pinfo+SP_PORT_INFO.driver], acm_port_name
; TODO obtain iManufacturer, iProduct and iSerial strings
mov dword [.pinfo+SP_PORT_INFO.descr], 0
lea ecx, [.pinfo]
stdcall serial_add_port, acm_sp_driver, ebx, ecx
stdcall serial_add_port, acm_sp_driver, ebx
mov [ebx+acm_dev.PortHandle], eax
test eax, eax
jz .no_serial
@@ -2660,7 +2652,6 @@ endp
; strings and static data
my_service db 'usbcdc', 0
acm_port_name db 'cdc-acm', 0
netdev_name db 'USB CDC-NCM', 0
ecm_netdev_name db 'USB CDC-ECM', 0
ecm_zlp_dummy db 0 ; address for zero-length transfers
+2 -8
View File
@@ -1754,14 +1754,8 @@ proc disk_read_write stdcall uses ebx esi edi, \
mov eax, [numsectors]
mov eax, [eax]
; 2. The transfer length for SCSI_{READ,WRITE}10 commands can not be greater
; than 0xFFFF sectors, but that is not the practical limit: the field size is
; the only thing the standard bounds, while real sticks hang their firmware on
; multi-megabyte single commands. The kernel disk cache asks for as much as
; CACHE_MAX_ALLOC_SIZE (4 MB) in one call, i.e. 8192 sectors, and that is
; exactly where such sticks stop answering and re-enumerate. Linux caps
; usb-storage at 240 sectors (120 KB) for the same reason; do the same and
; split larger requests into slices.
max_sectors_at_time = 240
; than 0xFFFF, so split the request to slices with <= 0xFFFF sectors.
max_sectors_at_time = 0xFFFF
.split:
push eax ; .length_rest
cmp eax, max_sectors_at_time
-3
View File
@@ -1,3 +0,0 @@
if tup.getconfig("NO_FASM") ~= "" then return end
ROOT = "../../.."
tup.rule("xhci.asm", "fasm %f %o " .. tup.getconfig("PESTRIP_CMD") .. tup.getconfig("KPACK_CMD"), "%B.sys")
File diff suppressed because it is too large. Load diff
-993
View File
@@ -1,993 +0,0 @@
; Device slots, contexts and pipes for the xHCI driver.
; This file is included from xhci.asm.
; =============================================================================
; ============================ Context helpers ================================
; =============================================================================
; Returns the address of one context inside a context structure.
; in: eax = base of the structure, ecx = index of the context,
; esi -> usb_controller.
; out: eax = address of the context.
proc xhci_context
push ecx edx
mov edx, [esi+xhci_controller.ContextSize-XCD]
imul edx, ecx
add eax, edx
pop edx ecx
ret
endp
; Zeroes the Input Context. The caller must hold CmdLock.
; in: esi -> usb_controller.
proc xhci_clear_input_ctx
push eax ecx edi
mov edi, [esi+xhci_controller.InputCtx-XCD]
xor eax, eax
mov ecx, 33*64/4
rep stosd
pop edi ecx eax
ret
endp
; Returns the pipe of the default control endpoint of the same device, which
; represents the device as a whole.
; in: ebx -> xhci_pipe. out: eax -> xhci_pipe or 0.
proc xhci_ctrl_pipe
mov eax, [ebx+xhci_pipe.DevPage]
test eax, eax
jz .nothing
mov eax, [eax+XHCI_PIPES_OFS+1*4]
test eax, eax
jz .nothing
sub eax, sizeof.xhci_pipe
.nothing:
ret
endp
; Fills the Slot Context of the Input Context from the device description kept
; in a pipe. The caller must hold CmdLock.
; in: esi -> usb_controller, ebx -> xhci_pipe describing the device,
; ecx = value for the Context Entries field.
proc xhci_fill_slot_ctx
push eax ecx edx edi
mov eax, [esi+xhci_controller.InputCtx-XCD]
push ecx
movi ecx, 1
call xhci_context
pop ecx
mov edi, eax
; dword 0: Route String, Speed and Context Entries.
mov eax, [ebx+xhci_pipe.Route]
and eax, 0FFFFFh
if XHCI_SUPERSPEED
; A SuperSpeed root-port device carries the raw PORTSC speed identifier;
; its kernel-visible Speed pretends high-speed and must not get here.
mov edx, [ebx+xhci_pipe.PSIV]
test edx, edx
jnz .havespeed
end if
mov edx, [ebx+xhci_pipe.Speed]
cmp edx, USB_SPEED_FS
jz .fs
cmp edx, USB_SPEED_LS
jz .ls
movi edx, XHCI_PSI_HS
jmp .havespeed
.fs:
movi edx, XHCI_PSI_FS
jmp .havespeed
.ls:
movi edx, XHCI_PSI_LS
.havespeed:
shl edx, 20
or eax, edx
shl ecx, 27
or eax, ecx
mov [edi], eax
; dword 1: Root Hub Port Number.
mov eax, [ebx+xhci_pipe.RootPort]
shl eax, 16
mov [edi+4], eax
; dword 2: the Transaction Translator, if the device is served by one.
mov eax, [ebx+xhci_pipe.TTSlot]
test eax, eax
jz @f
mov edx, [ebx+xhci_pipe.TTPort]
shl edx, 8
or eax, edx
@@:
mov [edi+8], eax
and dword [edi+12], 0
pop edi edx ecx eax
ret
endp
; Fills the Endpoint Context of the Input Context for the given pipe.
; The caller must hold CmdLock.
; in: esi -> usb_controller, ebx -> xhci_pipe.
proc xhci_fill_ep_ctx
push eax ecx edx edi
mov eax, [esi+xhci_controller.InputCtx-XCD]
mov ecx, [ebx+xhci_pipe.DCI]
inc ecx
call xhci_context
mov edi, eax
; dword 0: Interval.
mov eax, [ebx+xhci_pipe.Interval]
shl eax, 16
mov [edi], eax
; dword 1: Error Count, Endpoint Type, Max Burst Size and Max Packet Size.
mov eax, [ebx+xhci_pipe.EpType]
shl eax, 3
or eax, 3 shl 1 ; three retries before giving up
mov edx, [ebx+xhci_pipe.MaxPacket]
mov ecx, edx
shr ecx, 11
and ecx, 3 ; extra transactions per microframe
shl ecx, 8
or eax, ecx
if XHCI_SUPERSPEED
; A SuperSpeed bulk endpoint may allow bursts of several packets; the field
; shares its bits with the extra-transactions ones, which are zero then.
mov ecx, [ebx+xhci_pipe.MaxBurst]
shl ecx, 8
or eax, ecx
end if
and edx, 7FFh
shl edx, 16
or eax, edx
mov [edi+4], eax
; dwords 2 and 3: the TR Dequeue Pointer with the Dequeue Cycle State.
mov eax, [ebx+xhci_pipe.Enqueue]
shl eax, 4
add eax, [ebx+xhci_pipe.RingPhys]
or eax, [ebx+xhci_pipe.Cycle]
mov [edi+8], eax
and dword [edi+12], 0
; dword 4: Average TRB Length, only a hint for the bandwidth scheduler.
mov eax, [ebx+xhci_pipe.MaxPacket]
and eax, 7FFh
cmp [ebx+xhci_pipe.EpType], XHCI_EP_CONTROL
jnz @f
movi eax, 8
@@:
mov [edi+16], eax
and dword [edi+20], 0
pop edi edx ecx eax
ret
endp
; =============================================================================
; ============================== Slot commands ================================
; =============================================================================
; Issues the Address Device command for a newly created default control pipe.
; in: esi -> usb_controller, ebx -> xhci_pipe. out: eax = 0 on failure.
proc xhci_address_device
push ebx ecx edx edi
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexLock
call xhci_clear_input_ctx
mov edx, [esi+xhci_controller.InputCtx-XCD]
mov dword [edx+4], 3 ; add the Slot Context and endpoint zero
movi ecx, 1
call xhci_fill_slot_ctx
call xhci_fill_ep_ctx
mov [ebx+xhci_pipe.MaxDCI], 1
; Point the DCBAA entry of the slot at the Device Context.
mov eax, [esi+xhci_controller.CommonPage-XCD]
mov ecx, [ebx+xhci_pipe.SlotId]
mov edx, [ebx+xhci_pipe.DevPagePhys]
mov [eax+ecx*8], edx
and dword [eax+ecx*8+4], 0
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, XHCI_TRB_ADDRESS_DEV shl 10
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
push ebx
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_submit
pop ebx
push eax
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexUnlock
pop eax
cmp eax, XHCI_CC_SUCCESS
jz .ok
DEBUGF 1,'K : XHCI: Address Device failed, code %d\n',eax
xor eax, eax
jmp .nothing
.ok:
movi eax, 1
.nothing:
pop edi edx ecx ebx
ret
endp
; Issues a Configure Endpoint command that adds the given endpoint.
; in: esi -> usb_controller, ebx -> xhci_pipe of the endpoint,
; edi -> xhci_pipe of the default control endpoint of the same device.
; out: eax = completion code.
proc xhci_configure_endpoint
push ebx ecx edx esi edi
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexLock
call xhci_clear_input_ctx
; Drop the endpoint and add it again, so that reopening an endpoint that has
; been closed before also works.
mov ecx, [ebx+xhci_pipe.DCI]
movi eax, 1
shl eax, cl
mov edx, [esi+xhci_controller.InputCtx-XCD]
mov [edx], eax
or eax, 1 ; the Slot Context is always added
mov [edx+4], eax
call xhci_fill_ep_ctx
; The Context Entries field must cover every endpoint in use by the device.
mov ecx, [ebx+xhci_pipe.DCI]
cmp ecx, [edi+xhci_pipe.MaxDCI]
jae @f
mov ecx, [edi+xhci_pipe.MaxDCI]
@@:
mov [edi+xhci_pipe.MaxDCI], ecx
push ebx
mov ebx, edi
call xhci_fill_slot_ctx
pop ebx
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, XHCI_TRB_CONFIG_EP shl 10
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
push ebx
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_submit
pop ebx
push eax
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexUnlock
pop eax
pop edi esi edx ecx ebx
ret
endp
; Tells the controller where the endpoint has to continue from.
; in: esi -> usb_controller, ebx -> xhci_pipe.
proc xhci_set_dequeue
pushad
cmp [ebx+xhci_pipe.SlotId], 0
jz .nothing
mov eax, [ebx+xhci_pipe.Dequeue]
shl eax, 4
add eax, [ebx+xhci_pipe.RingPhys]
or eax, [ebx+xhci_pipe.Cycle]
mov ecx, [ebx+xhci_pipe.DCI]
shl ecx, 16
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, ecx
or edx, XHCI_TRB_SET_DEQ shl 10
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_sync
cmp eax, XHCI_CC_SUCCESS
jz .nothing
DEBUGF 1,'K : XHCI: Set TR Dequeue Pointer failed, code %d\n',eax
.nothing:
popad
ret
endp
; =============================================================================
; =============================== New device ==================================
; =============================================================================
; Called from xhci_port_init and from the hub support code when a new device
; has been connected and reset. Enables a device slot for it and hands it over
; to the protocol layer.
; in: esi -> usb_controller, eax = speed. out: eax = 0 on failure.
proc xhci_new_device
push ebx ecx edx edi
mov [esi+usb_controller.ResettingSpeed], al
; 1. Reserve room for the pseudo-pipe that describes the new device. Only the
; fields read by xhci_init_pipe are filled in; the layout matches a real pipe,
; so the result can be passed to usb_new_device as a usb_pipe pointer.
sub esp, sizeof.xhci_pipe + 4
mov ebx, esp
push ebx
mov edi, ebx
xor eax, eax
mov ecx, (sizeof.xhci_pipe + 4)/4
rep stosd
pop ebx
mov [ebx+sizeof.xhci_pipe], esi ; usb_pipe.Controller
movzx eax, [esi+usb_controller.ResettingSpeed]
mov [ebx+xhci_pipe.Speed], eax
; 2. Compute the root hub port, the route string and the tier of the device.
movzx edx, [esi+usb_controller.ResettingPort]
mov edi, [esi+usb_controller.ResettingHub]
test edi, edi
jnz .behind_hub
mov eax, [esi+xhci_controller.PortMap-XCD+edx*4]
mov [ebx+xhci_pipe.RootPort], eax
if XHCI_SUPERSPEED
mov eax, [esi+xhci_controller.ResettingPSIV-XCD]
mov [ebx+xhci_pipe.PSIV], eax
end if
jmp .have_topology
.behind_hub:
; The parent hub is a device too, and its own pipe carries the topology data.
mov eax, [edi+USB_HUB_CONFIGPIPE]
sub eax, sizeof.xhci_pipe
mov ecx, [eax+xhci_pipe.RootPort]
mov [ebx+xhci_pipe.RootPort], ecx
mov ecx, [eax+xhci_pipe.Depth]
mov eax, [eax+xhci_pipe.Route]
; The route string holds one nibble per tier, at most five of them.
cmp ecx, 5
jae .have_route
push ecx edx
shl ecx, 2
inc edx ; the route uses 1-based port numbers
cmp edx, 15
jbe @f
movi edx, 15
@@:
shl edx, cl
or eax, edx
pop edx ecx
.have_route:
inc ecx
mov [ebx+xhci_pipe.Depth], ecx
mov [ebx+xhci_pipe.Route], eax
; 3. Low- and full-speed devices behind a high-speed hub need the address of
; the Transaction Translator that serves them.
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
jz .have_topology
push ebx
mov ecx, edx
mov edx, edi
invoke usbhc_api.usb_get_tt
pop ebx
test edx, edx
jz .have_topology
sub edx, sizeof.xhci_pipe
mov eax, [edx+xhci_pipe.SlotId]
mov [ebx+xhci_pipe.TTSlot], eax
inc ecx
mov [ebx+xhci_pipe.TTPort], ecx
.have_topology:
; 4. Ask the controller for a device slot.
xor eax, eax
push ebx
xor ebx, ebx
xor ecx, ecx
mov edx, XHCI_TRB_ENABLE_SLOT shl 10
call xhci_cmd_sync
pop ebx
cmp eax, XHCI_CC_SUCCESS
jnz .fail
test edx, edx
jz .fail
mov [ebx+xhci_pipe.SlotId], edx
DEBUGF 1,'K : XHCI new device: slot %d, root port %d, route %x, speed %d\n',edx,[ebx+xhci_pipe.RootPort],[ebx+xhci_pipe.Route],[ebx+xhci_pipe.Speed]
; 5. Hand the device over to the protocol layer. It opens the pipe of the
; default control endpoint, and that is where the slot is really addressed.
lea ecx, [ebx+sizeof.xhci_pipe]
invoke usbhc_api.usb_new_device
test eax, eax
jnz .done
; 6. The protocol layer has failed; release the slot again.
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, XHCI_TRB_DISABLE_SLOT shl 10
xor eax, eax
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_sync
xor eax, eax
jmp .done
.fail:
dbgstr 'XHCI: Enable Slot failed'
xor eax, eax
.done:
add esp, sizeof.xhci_pipe + 4
pop edi edx ecx ebx
ret
endp
; =============================================================================
; ================================= Pipes =====================================
; =============================================================================
proc xhci_alloc_pipe
push ebx ecx edi
mov ebx, xhci_ep_mutex
invoke usbhc_api.usb_allocate_common, sizeof.xhci_pipe + sizeof.usb_pipe
test eax, eax
jz @f
; Zero the whole block: the kernel may call FreePipe for a pipe whose InitPipe
; has never run, and that path must not act on garbage.
mov edi, eax
push eax
xor eax, eax
movi ecx, (sizeof.xhci_pipe + sizeof.usb_pipe + 3)/4
rep stosd
pop eax
add eax, sizeof.xhci_pipe
@@:
pop edi ecx ebx
ret
endp
proc xhci_free_pipe stdcall, ptr:dword
push ebx esi edi
mov ebx, [ptr]
sub ebx, sizeof.xhci_pipe
mov esi, [ebx+sizeof.xhci_pipe+usb_pipe.Controller]
test esi, esi
jz .free
cmp [ebx+xhci_pipe.SlotId], 0
jz .drop_pipe
cmp [ebx+xhci_pipe.DCI], 1
jnz .drop_pipe
; This is the default control endpoint, that is, the handle of the whole
; device: release the slot together with the per-device page.
mov ecx, [ebx+xhci_pipe.SlotId]
mov edx, ecx
shl edx, 24
or edx, XHCI_TRB_DISABLE_SLOT shl 10
xor eax, eax
push ebx
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_sync
pop ebx
; The controller may access the Device Context until the command above
; completes, so only now may the DCBAA entry and the slot table forget it.
mov ecx, [ebx+xhci_pipe.SlotId]
mov edi, [esi+xhci_controller.CommonPage-XCD]
and dword [edi+ecx*8], 0
and dword [edi+ecx*8+4], 0
and [esi+xhci_controller.SlotPages-XCD+ecx*4], 0
mov eax, [ebx+xhci_pipe.DevPage]
test eax, eax
jz .drop_ring
invoke KernelFree, eax
and [ebx+xhci_pipe.DevPage], 0
jmp .drop_ring
.drop_pipe:
; Remove the pipe from the per-device table, if it is still listed there.
; On disconnect the kernel releases the pipes of a device in arbitrary order,
; and the pipe of the default control endpoint - the owner of the per-device
; page - may well be freed before this one, taking the page with it. The
; authoritative pointer is the one in SlotPages: it is cleared when the slot
; is released, so it can never point to freed memory.
mov ecx, [ebx+xhci_pipe.SlotId]
test ecx, ecx
jz .drop_ring
mov eax, [esi+xhci_controller.SlotPages-XCD+ecx*4]
test eax, eax
jz .drop_ring
mov ecx, [ebx+xhci_pipe.DCI]
cmp ecx, 32
jae .drop_ring
and dword [eax+XHCI_PIPES_OFS+ecx*4], 0
.drop_ring:
mov eax, [ebx+xhci_pipe.Ring]
test eax, eax
jz @f
invoke KernelFree, eax
and [ebx+xhci_pipe.Ring], 0
@@:
mov eax, [ebx+xhci_pipe.RingMap]
test eax, eax
jz .free
invoke KernelFree, eax
and [ebx+xhci_pipe.RingMap], 0
.free:
pop edi esi ebx
mov eax, [ptr]
sub eax, sizeof.xhci_pipe
invoke usbhc_api.usb_free_common, eax
ret
endp
; Allocates the transfer ring of a pipe.
; in: ebx -> xhci_pipe. out: eax = 0 on failure.
proc xhci_alloc_ring
push ecx edx
call xhci_alloc_page
test eax, eax
jz .nothing
mov [ebx+xhci_pipe.RingMap], eax
call xhci_alloc_page
test eax, eax
jnz @f
invoke KernelFree, [ebx+xhci_pipe.RingMap]
and [ebx+xhci_pipe.RingMap], 0
xor eax, eax
jmp .nothing
@@:
mov [ebx+xhci_pipe.Ring], eax
mov [ebx+xhci_pipe.RingPhys], edx
; The last entry returns to the beginning of the ring and toggles the cycle.
lea ecx, [eax+(XHCI_RING_TRBS-1)*16]
mov [ecx], edx
mov dword [ecx+12], (XHCI_TRB_LINK shl 10) + XHCI_TRB_TC
and [ebx+xhci_pipe.Enqueue], 0
and [ebx+xhci_pipe.Dequeue], 0
and [ebx+xhci_pipe.Reserved], 0
and [ebx+xhci_pipe.FirstFix], 0
mov [ebx+xhci_pipe.Cycle], XHCI_TRB_C
movi eax, 1
.nothing:
pop edx ecx
ret
endp
; Stores the pipe in the per-device table used by the event ring handler.
; in: ebx -> xhci_pipe.
proc xhci_register_pipe
push eax ecx edx
mov eax, [ebx+xhci_pipe.DevPage]
test eax, eax
jz @f
mov ecx, [ebx+xhci_pipe.DCI]
cmp ecx, 32
jae @f
lea edx, [ebx+sizeof.xhci_pipe]
mov [eax+XHCI_PIPES_OFS+ecx*4], edx
@@:
pop edx ecx eax
ret
endp
; Computes the Interval field of the Endpoint Context of an interrupt endpoint.
; The kernel passes bInterval from the endpoint descriptor: for high-speed
; devices it is an exponent of 125 us periods, for low- and full-speed devices
; it is a number of frames.
; in: ebx -> xhci_pipe, eax = bInterval.
proc xhci_calc_interval
push eax ecx
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
jnz .low_speed
test eax, eax
jz @f
dec eax
@@:
jmp .clamp
.low_speed:
; One frame equals eight periods of 125 us, hence the offset of three.
test eax, eax
jnz @f
movi eax, 1
@@:
bsr ecx, eax
lea eax, [ecx+3]
.clamp:
cmp eax, 15
jbe @f
movi eax, 15
@@:
mov [ebx+xhci_pipe.Interval], eax
pop ecx eax
ret
endp
; Called from usb_open_pipe.
; in: edi -> usb_pipe for the target, ecx -> usb_pipe of the config pipe,
; esi -> usb_controller, eax -> usb_gtd of the first descriptor,
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type,
; [ebp+24] = interval.
; out: eax = 0 on failure.
proc xhci_init_pipe
virtual at ebp+8
.config_pipe dd ?
.endpoint dd ?
.maxpacket dd ?
.type dd ?
.interval dd ?
end virtual
push ebx
sub edi, sizeof.xhci_pipe
sub ecx, sizeof.xhci_pipe
mov ebx, edi ; ebx -> xhci_pipe being initialized
; 1. Copy the description of the device from the config pipe.
mov eax, [ecx+xhci_pipe.SlotId]
mov [ebx+xhci_pipe.SlotId], eax
mov eax, [ecx+xhci_pipe.DevPage]
mov [ebx+xhci_pipe.DevPage], eax
mov eax, [ecx+xhci_pipe.DevPagePhys]
mov [ebx+xhci_pipe.DevPagePhys], eax
mov eax, [ecx+xhci_pipe.Speed]
mov [ebx+xhci_pipe.Speed], eax
mov eax, [ecx+xhci_pipe.RootPort]
mov [ebx+xhci_pipe.RootPort], eax
mov eax, [ecx+xhci_pipe.Route]
mov [ebx+xhci_pipe.Route], eax
mov eax, [ecx+xhci_pipe.Depth]
mov [ebx+xhci_pipe.Depth], eax
mov eax, [ecx+xhci_pipe.TTSlot]
mov [ebx+xhci_pipe.TTSlot], eax
mov eax, [ecx+xhci_pipe.TTPort]
mov [ebx+xhci_pipe.TTPort], eax
if XHCI_SUPERSPEED
mov eax, [ecx+xhci_pipe.PSIV]
mov [ebx+xhci_pipe.PSIV], eax
end if
; 2. Work out the Device Context Index and the endpoint type.
mov eax, [.endpoint]
test eax, eax
jz .control_ep
mov ecx, eax
and ecx, 15
add ecx, ecx
test al, 80h
jz @f
inc ecx
or [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
@@:
mov [ebx+xhci_pipe.DCI], ecx
mov eax, [.type]
cmp eax, BULK_PIPE
jz .bulk
cmp eax, INTERRUPT_PIPE
jz .interrupt
; A control endpoint other than endpoint zero is unusual but legal.
mov [ebx+xhci_pipe.EpType], XHCI_EP_CONTROL
jmp .have_type
.bulk:
movi eax, XHCI_EP_BULK_OUT
test [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
jz @f
movi eax, XHCI_EP_BULK_IN
@@:
mov [ebx+xhci_pipe.EpType], eax
jmp .have_type
.interrupt:
movi eax, XHCI_EP_INT_OUT
test [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
jz @f
movi eax, XHCI_EP_INT_IN
@@:
mov [ebx+xhci_pipe.EpType], eax
mov eax, [.interval]
call xhci_calc_interval
.have_type:
mov eax, [.maxpacket]
mov [ebx+xhci_pipe.MaxPacket], eax
if XHCI_SUPERSPEED
call xhci_ss_get_burst
end if
jmp .alloc_ring
.control_ep:
; The default control endpoint always has index one. Until the real packet size
; is known from the device descriptor, use the value the specification requires
; for the speed of the device: the kernel asks for 64 regardless of the speed,
; which is wrong for low- and full-speed devices.
mov [ebx+xhci_pipe.DCI], 1
mov [ebx+xhci_pipe.EpType], XHCI_EP_CONTROL
movi eax, 64
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
jz @f
movi eax, 8
@@:
if XHCI_SUPERSPEED
; A SuperSpeed device always uses 512 bytes on the default control endpoint.
cmp [ebx+xhci_pipe.PSIV], XHCI_PSI_SS
jb @f
mov eax, 512
@@:
end if
mov [ebx+xhci_pipe.MaxPacket], eax
.alloc_ring:
; 3. Allocate the transfer ring.
call xhci_alloc_ring
test eax, eax
jz .fail
; 4. Choose the software list the pipe belongs to and insert it there. The
; hardware knows nothing about these lists; they exist only so that the kernel
; can walk all pipes and reinsert an aborted one.
lea edx, [esi+xhci_controller.ControlED-XCD]
cmp [.type], BULK_PIPE
jb @f
lea edx, [esi+xhci_controller.BulkED-XCD]
jz @f
lea edx, [esi+xhci_controller.IntED-XCD]
@@:
lea edi, [ebx+sizeof.xhci_pipe]
mov [edi+usb_pipe.BaseList], edx
mov ecx, [edx+usb_pipe.NextVirt]
mov [edi+usb_pipe.NextVirt], ecx
mov [edi+usb_pipe.PrevVirt], edx
mov [ecx+usb_pipe.PrevVirt], edi
mov [edx+usb_pipe.NextVirt], edi
; 5. Now do the hardware part.
cmp [.endpoint], 0
jz .address_device
call xhci_register_pipe
mov edi, [.config_pipe]
sub edi, sizeof.xhci_pipe
call xhci_configure_endpoint
xhci_trace 'K : XHCI open pipe: slot %d dci %d\n', [ebx+xhci_pipe.SlotId], [ebx+xhci_pipe.DCI]
cmp eax, XHCI_CC_SUCCESS
jz .success
DEBUGF 1,'K : XHCI: Configure Endpoint failed, code %d\n',eax
jmp .unlink_fail
.address_device:
; 6. This is a new device: allocate its Device Context, publish the slot and
; let the controller give the device a bus address.
call xhci_alloc_page
test eax, eax
jz .unlink_fail
mov [ebx+xhci_pipe.DevPage], eax
mov [ebx+xhci_pipe.DevPagePhys], edx
mov ecx, [ebx+xhci_pipe.SlotId]
mov [esi+xhci_controller.SlotPages-XCD+ecx*4], eax
call xhci_register_pipe
call xhci_address_device
test eax, eax
jz .free_devpage
.success:
; usb_open_pipe keeps the pointer to the new pipe in edi across this call, so
; it has to be handed back untouched; the branch above has overwritten it with
; the pipe of the default control endpoint.
lea edi, [ebx+sizeof.xhci_pipe]
pop ebx
movi eax, 1
ret
.free_devpage:
mov ecx, [ebx+xhci_pipe.SlotId]
and [esi+xhci_controller.SlotPages-XCD+ecx*4], 0
mov eax, [ebx+xhci_pipe.DevPage]
invoke KernelFree, eax
and [ebx+xhci_pipe.DevPage], 0
.unlink_fail:
; Undo the insertion into the software list before failing.
lea edi, [ebx+sizeof.xhci_pipe]
mov eax, [edi+usb_pipe.NextVirt]
mov edx, [edi+usb_pipe.PrevVirt]
mov [eax+usb_pipe.PrevVirt], edx
mov [edx+usb_pipe.NextVirt], eax
.fail:
lea edi, [ebx+sizeof.xhci_pipe]
pop ebx
xor eax, eax
ret
endp
; Removes the pipe from the hardware configuration of the device.
; in: esi -> usb_controller, ebx -> usb_pipe.
proc xhci_unlink_pipe
pushad
sub ebx, sizeof.xhci_pipe
cmp [ebx+xhci_pipe.SlotId], 0
jz .nothing
cmp [ebx+xhci_pipe.DCI], 1
jz .nothing ; the slot itself is released by FreePipe
call xhci_ctrl_pipe
test eax, eax
jz .nothing
mov edi, eax ; edi -> pipe of endpoint zero
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexLock
call xhci_clear_input_ctx
mov ecx, [ebx+xhci_pipe.DCI]
movi eax, 1
shl eax, cl
mov edx, [esi+xhci_controller.InputCtx-XCD]
mov [edx], eax ; drop this endpoint
mov dword [edx+4], 1 ; keep the Slot Context
mov ecx, [edi+xhci_pipe.MaxDCI]
test ecx, ecx
jnz @f
movi ecx, 1
@@:
push ebx
mov ebx, edi
call xhci_fill_slot_ctx
pop ebx
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, XHCI_TRB_CONFIG_EP shl 10
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_submit
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexUnlock
.nothing:
popad
ret
endp
; Temporarily removes the pipe from the hardware schedule.
; in: esi -> usb_controller, ebx -> usb_pipe.
proc xhci_disable_pipe
pushad
sub ebx, sizeof.xhci_pipe
cmp [ebx+xhci_pipe.SlotId], 0
jz .nothing
mov ecx, [ebx+xhci_pipe.DCI]
shl ecx, 16
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, ecx
or edx, XHCI_TRB_STOP_EP shl 10
xor eax, eax
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_sync
.nothing:
popad
ret
endp
; Reinserts the pipe into the hardware schedule after xhci_disable_pipe, with
; an empty transfer queue.
; in: esi -> usb_controller, ebx -> usb_pipe,
; edx -> current descriptor, eax -> new last descriptor.
proc xhci_enable_pipe
pushad
sub ebx, sizeof.xhci_pipe
mov eax, [ebx+xhci_pipe.Ring]
test eax, eax
jz .nothing
; The queue is empty now, so the ring can be restarted from its beginning.
mov edi, eax
xor eax, eax
mov ecx, 0x1000/4
rep stosd
mov edi, [ebx+xhci_pipe.RingMap]
mov ecx, 0x1000/4
rep stosd
mov edi, [ebx+xhci_pipe.Ring]
add edi, (XHCI_RING_TRBS-1)*16
mov eax, [ebx+xhci_pipe.RingPhys]
mov [edi], eax
mov dword [edi+12], (XHCI_TRB_LINK shl 10) + XHCI_TRB_TC
and [ebx+xhci_pipe.Enqueue], 0
and [ebx+xhci_pipe.Dequeue], 0
and [ebx+xhci_pipe.Reserved], 0
and [ebx+xhci_pipe.FirstFix], 0
mov [ebx+xhci_pipe.Cycle], XHCI_TRB_C
call xhci_set_dequeue
.nothing:
popad
ret
endp
; =============================================================================
; ========================== Address and packet size ==========================
; =============================================================================
; Called from usb_set_address_callback. The bus address is chosen by the
; controller itself while executing the Address Device command, so the only
; thing left to do is to remember the number the kernel has reserved: it asks
; for it back on disconnect in order to mark it free again.
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address.
proc xhci_set_device_address
movzx eax, cl
mov [ebx+xhci_pipe.Address-sizeof.xhci_pipe], eax
jmp [usbhc_api.usb_subscribe_control]
endp
; in: esi -> usb_controller, ebx -> usb_pipe. out: eax = address.
proc xhci_get_device_address
mov eax, [ebx+xhci_pipe.Address-sizeof.xhci_pipe]
ret
endp
; Called from usb_get_descr8_callback once the real packet size of the default
; control endpoint is known. On xHCI that value lives in the Endpoint Context,
; so an Evaluate Context command is needed to update it.
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size.
proc xhci_set_endpoint_packet_size
push ebx ecx edx edi
sub ebx, sizeof.xhci_pipe
if XHCI_SUPERSPEED
; For a SuperSpeed device bMaxPacketSize0 is an exponent, and the only value
; the specification allows is 9: use 512 directly instead of the raw byte.
cmp [ebx+xhci_pipe.PSIV], XHCI_PSI_SS
jb @f
mov ecx, 512
@@:
end if
mov [ebx+xhci_pipe.MaxPacket], ecx
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexLock
call xhci_clear_input_ctx
mov edx, [esi+xhci_controller.InputCtx-XCD]
mov dword [edx+4], 2 ; evaluate the default control endpoint
call xhci_fill_ep_ctx
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, XHCI_TRB_EVAL_CTX shl 10
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
push ebx
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_submit
pop ebx
cmp eax, XHCI_CC_SUCCESS
jz @f
DEBUGF 1,'K : XHCI: Evaluate Context failed, code %d\n',eax
@@:
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexUnlock
pop edi edx ecx ebx
jmp [usbhc_api.usb_subscribe_control]
endp
; If the descriptor that has just completed is the answer to a request for the
; hub descriptor, tell the controller that the device is a hub: it has to know
; that in order to serve the devices behind it.
; in: ebx -> usb_gtd.
proc xhci_check_hub_descriptor
pushad
cmp [ebx+usb_gtd.Callback], 0
jz .nothing
mov eax, [ebx+usb_gtd.Pipe]
mov esi, [eax+usb_pipe.Controller]
sub eax, sizeof.xhci_pipe
test [eax+xhci_pipe.Flags], XHCI_PIPE_HUBPEND
jz .nothing
and [eax+xhci_pipe.Flags], not XHCI_PIPE_HUBPEND
cmp [ebx+xhci_gtd.Status-sizeof.xhci_gtd], XHCI_CC_SUCCESS
jnz .nothing
mov edx, [eax+xhci_pipe.HubBuf]
test edx, edx
jz .nothing
cmp byte [edx+1], 29h ; bDescriptorType
jnz .nothing
or [eax+xhci_pipe.Flags], XHCI_PIPE_ISHUB
mov ebx, eax ; ebx -> xhci_pipe of the hub
movzx edi, byte [edx+2] ; bNbrPorts
movzx ebp, byte [edx+3] ; low byte of wHubCharacteristics
shr ebp, 5
and ebp, 3 ; Transaction Translator Think Time
DEBUGF 1,'K : XHCI: device on slot %d is a hub with %d ports\n',[ebx+xhci_pipe.SlotId],edi
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexLock
call xhci_clear_input_ctx
mov eax, [esi+xhci_controller.InputCtx-XCD]
mov dword [eax+4], 1 ; only the Slot Context is evaluated
mov ecx, [ebx+xhci_pipe.MaxDCI]
test ecx, ecx
jnz @f
movi ecx, 1
@@:
call xhci_fill_slot_ctx
; Patch the Slot Context with the fields that describe a hub. Only Configure
; Endpoint takes them into account, Evaluate Context would ignore them.
mov eax, [esi+xhci_controller.InputCtx-XCD]
movi ecx, 1
call xhci_context
or dword [eax], 1 shl 26 ; this device is a hub
cmp [ebx+xhci_pipe.Speed], USB_SPEED_HS
jnz @f
shl ebp, 16
or [eax+8], ebp
@@:
shl edi, 24
or [eax+4], edi ; Number of Ports
mov edx, [ebx+xhci_pipe.SlotId]
shl edx, 24
or edx, XHCI_TRB_CONFIG_EP shl 10
mov eax, [esi+xhci_controller.InputCtxPhys-XCD]
xor ebx, ebx
xor ecx, ecx
call xhci_cmd_submit
cmp eax, XHCI_CC_SUCCESS
jz @f
DEBUGF 1,'K : XHCI: cannot mark the device as a hub, code %d\n',eax
@@:
lea ecx, [esi+xhci_controller.CmdLock-XCD]
invoke MutexUnlock
.nothing:
popad
ret
endp
-135
View File
@@ -1,135 +0,0 @@
; SuperSpeed support for the xHCI driver, included from xhci.asm when
; XHCI_SUPERSPEED is enabled. The pieces too small to live here - the port
; map, the Slot Context speed, the 512-byte default control endpoint, the
; Max Burst field of the Endpoint Context - sit in the other files under
; "if XHCI_SUPERSPEED" guards; this file keeps the self-contained procedures.
;
; The kernel USB stack knows nothing about SuperSpeed, so it never learns
; about it: a SuperSpeed device is announced as a high-speed one, which also
; keeps the Transaction Translator logic away from it. The raw PORTSC speed
; identifier travels in xhci_pipe.PSIV instead and reaches everything that
; really needs it. SuperSpeed hubs are not supported: the kernel only speaks
; the USB2 hub protocol, so a device behind a USB3 hub is served by the USB2
; half of that hub at high speed.
; =============================================================================
; ============================ SuperSpeed ports ===============================
; =============================================================================
; Called from xhci_new_port for a SuperSpeed root port instead of the USB2
; reset entry point: a SuperSpeed link trains itself and the port enables
; itself on connect, reporting the speed with no reset at all. When the link
; is already up, skip straight to the reset recovery stage, after which
; xhci_port_init picks the device up; otherwise try a warm reset.
; in: esi -> usb_controller, ecx = port index.
proc xhci_ss_start_port
push eax edx
and [esi+usb_controller.ResettingHub], 0
mov [esi+usb_controller.ResettingPort], cl
push ecx
invoke GetTimerTicks
pop ecx
mov [esi+usb_controller.ResetTime], eax
mov [esi+xhci_controller.ResetStart-XCD], eax
call xhci_port_reg
mov eax, [edx]
test al, XHCI_PORT_PED
jz .warm_reset
mov [esi+usb_controller.ResettingStatus], 2
DEBUGF 1,'K : XHCI %x: SS port %d link is up, PORTSC=%x\n',esi,ecx,eax
jmp .nothing
.warm_reset:
; Connected, but the link has not come up. The Port Reset bit is set while a
; warm reset is running, so the ordinary reset-wait machinery in
; xhci_port_reset_done serves this case unchanged; the extra WRC change bit is
; acknowledged there together with the usual ones.
mov dword [edx], XHCI_PORT_PP + XHCI_PORT_WPR
mov [esi+usb_controller.ResettingStatus], 1
DEBUGF 1,'K : XHCI %x: warm-resetting port %d, PORTSC=%x\n',esi,ecx,eax
.nothing:
pop edx eax
ret
endp
; The kernel restarts pending root ports through the NewPortReset entry of
; usb_hardware_func directly, bypassing xhci_new_port; SuperSpeed ports must
; not get the USB2 reset on that path either, so the entry points here.
; in: esi -> usb_controller, ecx = port index.
proc xhci_ss_port_reset
bt [esi+xhci_controller.SSPortMask-XCD], ecx
jnc xhci_new_port.reset
call xhci_ss_start_port
ret
endp
; =============================================================================
; ===================== Endpoint Companion descriptors ========================
; =============================================================================
; Reads the SuperSpeed Endpoint Companion descriptor of a bulk endpoint and
; keeps its bMaxBurst for the Endpoint Context, allowing bursts of up to
; bMaxBurst+1 packets per transaction. Zero (no bursts) is always legal, so
; any failure just leaves the field alone. Only bulk endpoints are considered:
; a nonzero burst on a periodic endpoint would also require the Max ESIT
; Payload fields, and real interrupt endpoints do not burst anyway.
; Relies on the stack frame of usb_open_pipe exactly like xhci_init_pipe does:
; [ebp+8] is the config pipe of the device.
; in: ebx -> xhci_pipe of a non-control endpoint being opened.
proc xhci_ss_get_burst
push eax ecx edx edi
; 1. Only SuperSpeed bulk endpoints are of interest.
cmp [ebx+xhci_pipe.PSIV], XHCI_PSI_SS
jb .nothing
mov eax, [ebx+xhci_pipe.EpType]
and al, 3
cmp al, 2 ; bulk endpoint types are 2 and 6
jnz .nothing
; 2. Find the configuration data kept by the kernel behind the device
; descriptor; it holds the endpoint descriptors with their companions.
mov eax, [ebp+8]
mov eax, [eax+usb_pipe.DeviceData]
test eax, eax
jz .nothing
movzx edx, [eax+usb_device_data.DeviceDescrSize]
mov edi, [eax+usb_device_data.ConfigDataSize]
lea ecx, [eax+edx+usb_device_data.DeviceDescriptor]
add edi, ecx ; edi -> end of the configuration data
; 3. Reconstruct bEndpointAddress from the Device Context Index.
mov edx, [ebx+xhci_pipe.DCI]
shr edx, 1
test [ebx+xhci_pipe.Flags], XHCI_PIPE_IN
jz @f
or dl, 80h
@@:
; 4. Walk the descriptors to the one of this endpoint.
.walk:
lea eax, [ecx+2]
cmp eax, edi
ja .nothing
movzx eax, byte [ecx] ; bLength
test eax, eax
jz .nothing ; malformed data, stop
cmp byte [ecx+1], 5 ; an endpoint descriptor?
jnz .advance
cmp [ecx+2], dl ; bEndpointAddress
jnz .advance
; 5. The companion descriptor (type 30h) immediately follows its endpoint.
add ecx, eax
lea eax, [ecx+3]
cmp eax, edi
ja .nothing
cmp byte [ecx+1], 30h ; SuperSpeed Endpoint Companion
jnz .nothing
movzx eax, byte [ecx+2] ; bMaxBurst
cmp eax, 15
ja .nothing
mov [ebx+xhci_pipe.MaxBurst], eax
DEBUGF 1,'K : XHCI: slot %d dci %d bursts %d+1 packets\n',[ebx+xhci_pipe.SlotId],[ebx+xhci_pipe.DCI],eax
jmp .nothing
.advance:
add ecx, eax
jmp .walk
.nothing:
pop edi edx ecx eax
ret
endp
File diff suppressed because it is too large. Load diff
-188
View File
@@ -1,188 +0,0 @@
/*
* Copyright (C) 2009 Francisco Jerez.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <linux/module.h>
#include <drm/drm_encoder_slave.h>
/**
* drm_i2c_encoder_init - Initialize an I2C slave encoder
* @dev: DRM device.
* @encoder: Encoder to be attached to the I2C device. You aren't
* required to have called drm_encoder_init() before.
* @adap: I2C adapter that will be used to communicate with
* the device.
* @info: Information that will be used to create the I2C device.
* Required fields are @addr and @type.
*
* Create an I2C device on the specified bus (the module containing its
* driver is transparently loaded) and attach it to the specified
* &drm_encoder_slave. The @slave_funcs field will be initialized with
* the hooks provided by the slave driver.
*
* If @info->platform_data is non-NULL it will be used as the initial
* slave config.
*
* Returns 0 on success or a negative errno on failure, in particular,
* -ENODEV is returned when no matching driver is found.
*/
int drm_i2c_encoder_init(struct drm_device *dev,
struct drm_encoder_slave *encoder,
struct i2c_adapter *adap,
const struct i2c_board_info *info)
{
struct module *module = NULL;
struct i2c_client *client;
struct drm_i2c_encoder_driver *encoder_drv;
int err = 0;
request_module("%s%s", I2C_MODULE_PREFIX, info->type);
client = i2c_new_device(adap, info);
if (!client) {
err = -ENOMEM;
goto fail;
}
if (!client->dev.driver) {
err = -ENODEV;
goto fail_unregister;
}
module = client->dev.driver->owner;
if (!try_module_get(module)) {
err = -ENODEV;
goto fail_unregister;
}
encoder->bus_priv = client;
encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.driver));
err = encoder_drv->encoder_init(client, dev, encoder);
if (err)
goto fail_module_put;
if (info->platform_data)
encoder->slave_funcs->set_config(&encoder->base,
info->platform_data);
return 0;
fail_module_put:
module_put(module);
fail_unregister:
i2c_unregister_device(client);
fail:
return err;
}
EXPORT_SYMBOL(drm_i2c_encoder_init);
/**
* drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder
* @drm_encoder: Encoder to be unregistered.
*
* This should be called from the @destroy method of an I2C slave
* encoder driver once I2C access is no longer needed.
*/
void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
{
struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
struct module *module = client->dev.driver->owner;
i2c_unregister_device(client);
encoder->bus_priv = NULL;
module_put(module);
}
EXPORT_SYMBOL(drm_i2c_encoder_destroy);
/*
* Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
*/
static inline const struct drm_encoder_slave_funcs *
get_slave_funcs(struct drm_encoder *enc)
{
return to_encoder_slave(enc)->slave_funcs;
}
void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode)
{
get_slave_funcs(encoder)->dpms(encoder, mode);
}
EXPORT_SYMBOL(drm_i2c_encoder_dpms);
bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
if (!get_slave_funcs(encoder)->mode_fixup)
return true;
return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode);
}
EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup);
void drm_i2c_encoder_prepare(struct drm_encoder *encoder)
{
drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
}
EXPORT_SYMBOL(drm_i2c_encoder_prepare);
void drm_i2c_encoder_commit(struct drm_encoder *encoder)
{
drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
}
EXPORT_SYMBOL(drm_i2c_encoder_commit);
void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode);
}
EXPORT_SYMBOL(drm_i2c_encoder_mode_set);
enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
struct drm_connector *connector)
{
return get_slave_funcs(encoder)->detect(encoder, connector);
}
EXPORT_SYMBOL(drm_i2c_encoder_detect);
void drm_i2c_encoder_save(struct drm_encoder *encoder)
{
get_slave_funcs(encoder)->save(encoder);
}
EXPORT_SYMBOL(drm_i2c_encoder_save);
void drm_i2c_encoder_restore(struct drm_encoder *encoder)
{
get_slave_funcs(encoder)->restore(encoder);
}
EXPORT_SYMBOL(drm_i2c_encoder_restore);
+1 -4
View File
@@ -1721,8 +1721,7 @@ endp
; out: eax = 1 if the interrupt came from this controller, 0 otherwise
align 4
ahci_irq_handler:
push ebx esi edi
mov esi, [esp + 12 + 4]
mov esi, [esp + 4]
test esi, esi
jz .not_our
mov edx, [esi + AHCI_CTR.abar]
@@ -1787,11 +1786,9 @@ ahci_irq_handler:
@@:
pop eax
mov eax, 1
pop edi esi ebx
ret
.not_our:
xor eax, eax
pop edi esi ebx
ret
+3 -15
View File
@@ -1489,31 +1489,19 @@ dyndisk_handler:
; 12. The fs operation has specified some partition.
push edx ecx
xor eax, eax
mov ecx, eax
lodsb
@@:
lea ecx, [ecx*4 + ecx]
shl ecx, 1
sub eax, '0'
jb .dyndisk_cleanup
jz .dyndisk_cleanup
cmp eax, 10
jnc .dyndisk_cleanup
add ecx, eax
cmp ecx, MAX_NUM_PARTITIONS
ja .dyndisk_cleanup
mov ecx, eax
lodsb
cmp eax, '/'
jz @f
test eax, eax
jnz @b
jnz .dyndisk_cleanup
dec esi
@@:
test ecx, ecx
jz .dyndisk_cleanup
cmp byte [esi], 0
jnz @f
; partition info
+16 -76
View File
@@ -2507,7 +2507,7 @@ dword-значение цвета 0x00RRGGBB
* иначе eax = TID - идентификатор потока
---------------------- Константы для регистров: ----------------------
eax - SF_THREAD_CONTROL (51) /
eax - SF_CREATE_THREAD (51) /
ebx - SSF_CREATE_THREAD (1), SSF_GET_CURR_THREAD_SLOT (2),
SSF_GET_THREAD_PRIORITY (3), SSF_SET_THREAD_PRIORITY (4)
@@ -4098,9 +4098,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* подфункция 7 - запуск программы
* подфункция 8 - удаление файла/папки
* подфункция 9 - создание папки
* подфункция 10 - переименование/перемещение
* подфункция 11 - создание симлинка
* подфункция 12 - чтение симлинка
Для CD-приводов в связи с аппаратными ограничениями доступны
только подфункции 0,1,5 и 7, вызов других подфункций завершится
ошибкой с кодом 2.
@@ -4115,8 +4112,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
[ebx] - SSF_READ_FILE (0), SSF_READ_FOLDER (1), SSF_CREATE_FILE (2),
SSF_WRITE_FILE (3), SSF_SET_END (4), SSF_GET_INFO (5),
SSF_SET_INFO (6), SSF_START_APP (7), SSF_DELETE (8),
SSF_CREATE_FOLDER (9), SSF_RENAME (10), SSF_CREATE_SYMLINK (11),
SSF_READ_SYMLINK (12)
SSF_CREATE_FOLDER (9)
======================================================================
= Функция 70, подфункция 0 - чтение файла с поддержкой длинных имён. =
======================================================================
@@ -4468,62 +4464,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* Формирование нового пути отличается от общих правил:
относительный путь относится к папке целевого файла (или папки),
абсолютный путь считается от корня раздела.
---------------------- Константы для регистров: ----------------------
eax - SF_FILE (70)
[ebx] - SSF_RENAME (10)
======================================================================
=========== Функция 70, подфункция 11 - создание симлинка. ===========
======================================================================
Параметры:
* eax = 70 - номер функции
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 11 = номер подфункции
* +4: dword: 0 (зарезервировано)
* +8: dword: 0 (зарезервировано)
* +12 = +0xC: dword: 0 (зарезервировано)
* +16 = +0x10: dword: указатель на строку с целевым путём
* +20 = +0x14: путь, правила формирования имён указаны в общем
описании (путь ссылки)
Возвращаемое значение:
* eax = 0 - успешно, иначе код ошибки файловой системы
* ebx разрушается
Замечания:
* Родительская папка должна существовать.
* Для CD функция не поддерживается (возвращает код ошибки 2).
---------------------- Константы для регистров: ----------------------
eax - SF_FILE (70)
[ebx] - SSF_CREATE_SYMLINK (11)
======================================================================
============ Функция 70, подфункция 12 - чтение симлинка. ============
======================================================================
Параметры:
* eax = 70 - номер функции
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 12 = номер подфункции
* +4: dword: 0 (зарезервировано)
* +8: dword: 0 (зарезервировано)
* +12 = +0xC: dword: размер буфера в байтах
* +16 = +0x10: dword: указатель на буфер для целевого пути
* +20 = +0x14: путь, правила формирования имён указаны в общем
описании (путь ссылки)
Возвращаемое значение:
* eax = 0 - успешно, иначе код ошибки файловой системы
* ebx = число байт, записанных в буфер
Замечания:
* Функция не следует по симлинку; она читает целевой путь,
на который указывает симлинк.
* Целевой путь всегда завершается нулём, в том числе при обрезании;
записывается не более (размер буфера - 1) байт пути.
* Значение в ebx включает завершающий 0, как в подфункции 2
функции 30.
---------------------- Константы для регистров: ----------------------
eax - SF_FILE (70)
[ebx] - SSF_READ_SYMLINK (12)
======================================================================
========== Функция 71 - установить заголовок окна программы ==========
======================================================================
@@ -5119,8 +5059,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* eax = дескриптор фьютекса, 0 при ошибке
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_CREATE (0)
eax - SF_FUTEX (77)
ebx - SSF_CREATE (0)
======================================================================
============= Функция 77, подфункция 1, Удалить фьютекс. =============
======================================================================
@@ -5134,8 +5074,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* Ядро автоматически удаляет фьютексы при завершении процесса.
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_DESTROY (1)
eax - SF_FUTEX (77)
ebx - SSF_DESTROY (1)
======================================================================
================= Функция 77, подфункция 2, Ожидать. =================
======================================================================
@@ -5151,8 +5091,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
-2 - контрольное значение фьютекса не соответствует
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_WAIT (2)
eax - SF_FUTEX (77)
ebx - SSF_WAIT (2)
======================================================================
================ Функция 77, подфункция 3, Разбудить. ================
======================================================================
@@ -5165,8 +5105,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* eax = количество разбуженых
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_WAKE (3)
eax - SF_FUTEX (77)
ebx - SSF_WAKE (3)
======================================================================
Замечания:
* Подфункции 4-7 зарезервированы и сейчас возвращают -1.
@@ -5188,8 +5128,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* Поддерживаются только pipe-дескрипторы.
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FD_READ (10)
eax - SF_FUTEX (77)
ebx - SSF_FILE_READ (10)
======================================================================
======== Функция 77, подфункция 11, Записать из буфера в файл. =======
@@ -5208,8 +5148,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
* Поддерживаются только pipe-дескрипторы.
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FD_WRITE (11)
eax - SF_FUTEX (77)
ebx - SSF_FILE_WRITE (11)
======================================================================
=========== Функция 77, подфункция 13, Создать новый pipe. ===========
@@ -5233,8 +5173,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
- дескриптором записи.
---------------------- Константы для регистров: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FD_PIPE2 (13)
eax - SF_FUTEX (77)
ebx - SSF_PIPE_CREATE (13)
======================================================================
========== Функция -1 - завершить выполнение потока/процесса =========
+16 -74
View File
@@ -2492,7 +2492,7 @@ Returned value:
* otherwise eax = TID - thread identifier
---------------------- Constants for registers: ----------------------
eax - SF_THREAD_CONTROL (51)
eax - SF_CREATE_THREAD (51)
ebx - SSF_CREATE_THREAD (1), SSF_GET_CURR_THREAD_SLOT (2),
SSF_GET_THREAD_PRIORITY (3), SSF_SET_THREAD_PRIORITY (4)
======================================================================
@@ -4060,9 +4060,6 @@ Available subfunctions:
* subfunction 7 - start application
* subfunction 8 - delete file/folder
* subfunction 9 - create folder
* subfunction 10 - rename/move
* subfunction 11 - create symlink
* subfunction 12 - read symlink
For CD-drives due to hardware limitations only subfunctions
0,1,5 and 7 are available, other subfunctions return error
with code 2.
@@ -4076,8 +4073,7 @@ is called for corresponding device.
[ebx] - SSF_READ_FILE (0), SSF_READ_FOLDER (1), SSF_CREATE_FILE (2),
SSF_WRITE_FILE (3), SSF_SET_END (4), SSF_GET_INFO (5),
SSF_SET_INFO (6), SSF_START_APP (7), SSF_DELETE (8),
SSF_CREATE_FOLDER (9), SSF_RENAME (10), SSF_CREATE_SYMLINK (11),
SSF_READ_SYMLINK (12)
SSF_CREATE_FOLDER (9)
======================================================================
=== Function 70, subfunction 0 - read file with long names support. ==
======================================================================
@@ -4427,60 +4423,6 @@ Remarks:
* New path forming differs from general rules:
relative path relates to the target's parent folder,
absolute path relates to the partition's root folder.
---------------------- Constants for registers: ----------------------
eax - SF_FILE (70)
[ebx] - SSF_RENAME (10)
======================================================================
=========== Function 70, subfunction 11 - create symlink. ============
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 11 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: pointer to the target path string
* +20 = +0x14: path, general rules of names forming (link path)
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
Remarks:
* The parent folder must already exist.
* The function is not supported for CD (returns error code 2).
---------------------- Constants for registers: ----------------------
eax - SF_FILE (70)
[ebx] - SSF_CREATE_SYMLINK (11)
======================================================================
============ Function 70, subfunction 12 - read symlink. =============
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 12 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: buffer size in bytes
* +16 = +0x10: dword: pointer to buffer for target path
* +20 = +0x14: path, general rules of names forming (link path)
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = number of bytes written to the buffer
Remarks:
* The function does not follow the symlink; it reads the target path
that the symlink points to.
* The target path is always terminated with 0, even when truncated;
at most (buffer size - 1) path bytes are written.
* The value returned in ebx includes the terminating 0, as in
subfunction 2 of function 30.
---------------------- Constants for registers: ----------------------
eax - SF_FILE (70)
[ebx] - SSF_READ_SYMLINK (12)
======================================================================
================== Function 71 - set window caption ==================
======================================================================
@@ -5331,8 +5273,8 @@ Returned value:
* eax = futex handle, 0 on error
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_CREATE (0)
eax - SF_FUTEX (77)
ebx - SSF_CREATE (0)
======================================================================
========= Function 77, Subfunction 1, Destroy futex object ===========
======================================================================
@@ -5347,8 +5289,8 @@ Remarks:
terminates.
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_DESTROY (1)
eax - SF_FUTEX (77)
ebx - SSF_DESTROY (1)
======================================================================
=============== Function 77, Subfunction 2, Futex wait ===============
======================================================================
@@ -5364,8 +5306,8 @@ Returned value:
-2 - futex control value doesn't match
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_WAIT (2)
eax - SF_FUTEX (77)
ebx - SSF_WAIT (2)
======================================================================
=============== Function 77, Subfunction 3, Futex wake ===============
======================================================================
@@ -5378,8 +5320,8 @@ Returned value:
* eax = number of waiters that were woken up
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FUTEX_WAKE (3)
eax - SF_FUTEX (77)
ebx - SSF_WAKE (3)
======================================================================
Remarks:
* Subfunctions 4-7 are reserved and currently return -1.
@@ -5401,8 +5343,8 @@ Remarks:
* Only pipe descriptors are supported.
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FD_READ (10)
eax - SF_FUTEX (77)
ebx - SSF_FILE_READ (10)
======================================================================
=========== Function 77, Subfunction 11, Write to file. =============
======================================================================
@@ -5420,8 +5362,8 @@ Remarks:
* Only pipe descriptors are supported.
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FD_WRITE (11)
eax - SF_FUTEX (77)
ebx - SSF_FILE_WRITE (11)
======================================================================
========== Function 77, Subfunction 13, Create pipe. ================
======================================================================
@@ -5439,8 +5381,8 @@ Remarks:
write handle.
---------------------- Constants for registers: ----------------------
eax - SF_POSIX (77)
ebx - SSF_FD_PIPE2 (13)
eax - SF_FUTEX (77)
ebx - SSF_PIPE_CREATE (13)
======================================================================
=== Function 80 - file system interface with parameter of encoding ===
======================================================================
Loaded 100 of 330 files, more files were not shown because too many files have changed in this diff. Show more