Linux713 (2)


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)
Linux714
Linux735
linux721
Linux712 (4)
Linux736 (4)
Linux736 (3)
Linux722 (4)

więcej podobnych podstron