Do tematu: Podsystem wejścia-wyjścia
Do tematu: Struktury danych
Struktura blk_dev_struct
Struktura blk_dev_struct opisuje urządzenie blokowe. Zawiera listę żądań skierowanych do danego urządzenia oraz wskaźnik do zdefiniowanej w sterowniku urządzenia funkcji, realizującej żądania. Struktury blk_dev_struct są pamiętane w tablicy blk_dev, której definicja znajduje się w pliku /drivers/block/ll_rw_blk.c:
MAX_BLKDEV 128
struct blk_dev_struct blk_dev[MAX_BLKDEV]
Tablica ta jest indeksowana numerami głównymi urządzeń blokowych. Definicja struktury blk_dev_struct znajduje się w pliku /include/linux/blkdev.h.
typ | nazwa pola | opis |
void | (*request_fn)(void) | Wskaźnik do funkcji zdefiniowanej w sterowniku urządzenia. Funkcja ta realizuje obsługę żądań zapisu/odczytu do/z urządzenia. |
struct request * | current_request | Kolejka żądań skierowanych do urządzenia. |
struct request * | plug | (ang. korek) Pole plug jest żądaniem, które
dla większości urządzeń jest wstawiane na listę żądań current_request,
gdy lista ta jest pusta. W funkcji blk_dev_init, zdefiniowanej
w pliku /drivers/block/ll_rw_blk.c, która inicjalizuje tablicę
blk_dev, nadawane są również wartości początkowe żądaniu plug.
Są one następujące:
plug.rq_status = RQ_INACTIVE plug.cmd = -1 plug.next = NULL Funkcja add_request, realizująca szeregowanie żądań do urządzeń blokowych, po wstawieniu żądania na pustą listę current_request, wywołuje funkcję zdefiniowaną w sterowniku urządzenia, której zadaniem jest doprowadzenie do wykonania operacji wejścia-wyjścia. Jeśli lista current_request nie jest pusta, to niskopoziomowa funkcja sterownika nie jest wywoływana. Wyjątek stanowią tu urządzenia SCSI. Jeżeli o tym, kiedy rozpocząć obsługę żądań, chcemy decydować poza funkcją add_request, możemy posłużyć się żądaniem plug. Aby wstawić na pustą listę current_request żądanie plug, wywołujemy funkcję plug_device zdefiniowaną w pliku /drivers/block/ll_rw_block.c. Funkcja ta dodatkowo, rejestruje w kolejce zadań tq_disk funkcję unplug_device, jako funkcję "bottom half". Funkcja add_request nie rozróżnia żądania plug od innych żądań, w związku z tym wszystkie nadchodzące żądania ustawia na liście current_request za żądaniem plug, nie rozpoczynając, przy tym, ani razu niskopoziomowej obsługi żądań. Dopiero, gdy wywołana zostanie funkcja run_task_queue dla kolejki tq_disk, funkcja unplug_device, usunie żądanie plug z listy current_request i zainicjalizuje obsługę żądań. (Funkcja run_task_queue wywołuje wszystkie funkcje "bottom half" zarejestrowane w odpowiedniej kolejce zadań) |
struct tq_struct | plug_tq | Pole plug_tq reprezentuje funkcję "bottom half",
której zadaniem jest inicjalizowanie obsługi żądań do urządzenia blokowego.
Pole to otrzymuje wartości początkowe w funkcji blk_dev_init:
plug_tq.routine = &unplug_device plug_tq.data = dev dev jest wskaźnikiem do struktury blk_dev_init, argumentem dla funkcji unplug_device. Informacje na temat wykorzystania funkcji unplug_device zostały podane przy opisie pola plug. |