porty wejscia-wyjscia
do spisu tresci tematu 7
7.1.3 Porty wejscia-wyjscia (IO ports)
Spis tresci
Wprowadzenie
Rezerwowanie portow wejscia-wyjscia
Korzystanie z portow wejscia-wyjscia
Zrodla informacji
Wprowadzenie
Porty wejscia-wyjscia stanowia interfejs miedzy programem obslugi a
fizycznym urzadzeniem. Sa to adresy z przestrzeni adresowej jadra, odpowiadajace
specjalnym rejestrom sluzacym do sterowania praca urzadzen. Numery portow
(od 0 do 65536) odpowiadajacych poszczegolnym urzadzeniom zaleza od konfiguracji
sprzetu, tzn. nie mozna ich ustawic programowo. Sterownik urzadzenia musi
podczas swej inicjalizacji "znalezc" (probe) porty odpowiadajace
fizycznemu urzadzeniu ktore ma obslugiwac. W tym celu program obslugi przechodzi
adresy portow, pod ktorymi spodziewa sie znalezc urzadzenie, zapisujac
do nich kody polecen dla urzadzenia i oczekujac przez pewien czas na sensowna
odpowiedz oznaczajaca, ze zostalo ono odnalezione.
Rezerwowanie portow wejscia-wyjscia
Oczywiscie wpisywanie wartosci kontrolnych do portow zajetych juz przez
inne urzadzenie spowodowaloby prawdopodobnie jego bledne dzialanie, istnieja
wiec struktury danych pozwalajace na rezerwowanie obszarow portow wejscia-wyjscia.
Rozpoczynajacy prace sterownik moze bezpiecznie poszukiwac swojego urzadzenia
tylko w obszarach, ktore nie zostaly jeszcze zarezerwowane.
Zarezerwowany obszar (region) portow wejscia-wyjscia opisuje struktura
resource_entry_t zdefiniowana w pliku kernel/resource.c
struct resource_entry_t {
u_long from,num;
const char *name;
struct resource_entry_t *next;
}
from
adres pierwszego zarezerwowanego portu
num
dlugosc zarezerwowanego obszaru
name
nazwa urzadzenia ktore rezerwuje porty
Struktury resource_entry_t zawarte sa w tablicy iotable
o rozmiarze ograniczonym do IOTABLE_SIZE czyli 64 elementow, i
polaczone w uporzadkowana liste iolist.
Funkcje dzialajace na liscie iolist (zdefiniowane w
kernel/resource.c):
int check_region(unsigned int from, unsigned int num )
sprawdza czy obszar [from, from+num-1] jest zarezerwowany, jesli tak
to program obslugi innego urzadzenia nie powinien nic zapisywac do portow
w tych numerach.
void request_region( unsigned int from, unsigned int num, const
char *name)
rezerwuje obszar portow (jesli nie pokrywa sie z uprzednio zarezerwowanymi),
dodajac go do listy.
void release_region( unsigned int from, unsigned int num)
usuwa obszar z listy, powinna byc wywolana jesli program obslugi konczy
prace, w przeciwnym przypadku portow nie bedzie mozna uzyc ponownie.
Liste zarezerwowanych obszarow portow wraz z nazwami urzadzen mozna
obejrzec czytajac plik /proc/ioports.
Zarejestrowanie obszaru portow nie jest konieczne aby moc z nich korzystac.
Przy wpisywaniu i odczytywaniu wartosci z portow, system nie sprawdza w
zaden sposob, czy porty te sa zarezerwowane i przez jakie urzadzenie, i
nie generuje wyjatku, ale oczywiscie wpisanie nieodpowiedniej wartosci
do portu moze spowodowac blad w pracy korzystajacego z portu urzadzenia.
Istnieje niebezpieczenstwo, ze program obslugi, szczegolnie inicjalizowany
podczas startu systemu, kiedy jest jeszcze duzo niezarejestrowanych urzadzen,
pomyli jedno z nich z urzadzeniem ktorego szuka, dlatego kazdy sterownik
powinien dawac uzytkownikowi mozliwosc okreslenia ktorych portow uzywa
urzadzenie i w ten sposob unikniecia szukania
Korzystanie z portow wejscia-wyjscia
Do zapisywania i odczytywania wartosci do (i z) portow sluza funkcje
inline zdefiniowane w pliku include/asm/io.h
outb,outw,outl
zapisuja do portu - jako parametr przyjmuja numer portu i wartosc odpowiednio:
typu char, typu short i typu int
inb,inw,inl
czytaja z portu - jako parametr przyjmuja numer portu, zwracaja wartosc
typu char, short lub int
outsb,outsw,outsl
zapisuja ciag wartosci z pod wskazanego adresu do portu, parametrami
sa: numer portu, adres w pamieci, ilosc slow (char,short,int)
insb,insw,insl
analogiczne wersje procedur sluzacych do czytania z portow
outb_p,outw_p,outl_p,inb_p,inw_p,inl_p
funkcje z przyrostkiem _p robia "pauze" po zapisaniu
lub odczytaniu wartosci do (lub z) portu a przed powrotem z funkcji, aby
umozliwic pobranie tych wartosci sprzetowi, ktory zwykle nie nadaza za
procesorem.
Dostep do wszystkich 65536 portow mozna rowniez uzyskac za posrednictwem
specjalnego pliku znakowego /dev/port - wykonujac na nim operacje
lseek, read i write. Jest to oczywiscie sposob wolniejszy niz uzywanie
wyzej opisanych funkcji.
Zrodla informacji
Pliki zrodlowe:
include/asm/io.h
kernel/resource.c
Linux Journal - artykuly w dziale Kernel Korner
Michael K. Johnson: Artykuly dotyczace programow obslugi urzadzen w Kernel Hackers'
Guide
Michael K. Johnson: Wrirting Linux Device Drivers
Artur Zawlocki
Wyszukiwarka
Podobne podstrony:
Linux714 (3)Linux714Linux735linux721Linux712 (4)Linux736 (4)Linux736 (3)Linux722 (4)więcej podobnych podstron