O mrocznych czasach sprzed standardu USB

Dzisiejszy standard USB, którego akronim rozwija się do „Universal Serial Bus”, wcale nie jest taki „Universal”, jak wielu z nas by chciało. Powoli rosnąca liczba wariantów gniazd, jak wersje mini i micro, otrzymała towarzystwo w postaci rosnącej liczby kabli, zgodnych z USB-C. Niektóre z nich pozwalają tylko ładować, niektóre przesyłać dane i ładować (ale powoli), a niektóre potrafią robić i jedno i drugie. Są też takie, które są tylko reklamowane jako kable do wszystkiego, bo ich podpięcie do gniazda Thunderbolt 3 kończy się małym pożarem. Gdzie ta uniwersalność, gdy do USB potrzebna jest paleta przejściówek, a w wariancie C nie możemy już nawet zaufać kablom? Przecież gniazdka USB miały uśmiercić paradę specyficznych złącz, jak PS/2, Game Port, „igłowe” porty szeregowe i równoległe, oznaczane jako COM i LPT oraz szereg innych. Po to, by mieć już tylko jedną wtyczkę i martwić się tylko tym, że za pierwszym razem nie udało się jej wpiąć w poprawną stronę. Dlaczego mimo to mamy znowu problem z wtyczkami? Jaką kwestię tak naprawdę rozwiązano z tym całym USB? 

Oj tak. Jakże łatwo człowiek przyzwyczaja się do wygody. Z biegiem czasu zaczynają wadzić coraz mniejsze trudności, a jeszcze tak niedawno dzielnie walczyło się z przełącznikami i zworkami… No właśnie. Aby przypomnieć, jaką ulgą dla świata USB, należy wykopać urządzenie, które dziś podpinamy wyłącznie w taki sposób, a które powstało jednak zanim USB w ogóle zdefiniowano. Jestem szczęśliwym posiadaczem takowego, a imię jego: Logitech ScanMan 256. Ręczny skaner operujący na odcieniach szarości. Podpinany przez… dedykowaną kartę do rozszerzeń, przeznaczoną do samodzielnego montażu wewnątrz peceta :) Mamy tu więc do czynienia nie tylko z urządzeniem starszym od USB, ale również starszym od PCI i takiej oczywistości, jak technologia Plug and Play. To idealny okaz do zbadania poruszanego zagadnienia.

W czasach sprzed tych wszystkich nowomodnych wynalazków, rozszerzanie funkcjonalności komputera polegało na fizycznym dodaniu rozszerzenia w postaci karty. Nie można było podpiąć urządzenia do żadnego istniejącego „gniazdka” z tyłu obudowy, bo tam znajdowały się tylko dwa: jedno na klawiaturę i drugie, opcjonalne zresztą, na… magnetofon kasetowy. Wszystkie inne gniazda były dostarczane w postaci kart rozszerzeń. Z biegiem czasu, „notoryczni” kandydaci zostali zintegrowani, i na płycie głównej znalazły się igły do wyprowadzenia gniazd COM i LPT oraz kanały IDE dla napędów dyskowych. Te jednak zintegrowano, bo nie ulegały zmianie: nie da się wymyślić portu równoległego 25 na nowo. Karty graficzne, obecne przecież w każdym komputerze, nie uległy zintegrowaniu z płytami AT.

Aby system operacyjny mógł się porozumiewać z kartą rozszerzeń, konieczne jest przypisanie jej przerwania (IRQ). W przeciwnym wypadku, komputer nie „zatrzymuje się” nigdy, by czegokolwiek od takiej karty chcieć. To okropne i naciągane wytłumaczenie, ale w jakiś sposób rymuje się z prawdą. Porty COM i LPT mają swoje przerwania, ustawia się je w BIOSie. Kontrolery dysków też. Każda następna karta rozszerzeń musiała mieć swoje „miejsce w kolejce” i otrzymać jedno z przerwań. Dzięki temu, możliwa jest komunikacja z danym urządzeniem.

Ale to nie wszystko. Proces „rozszerzania” sprzętu bez obsługi plug and play wymaga jeszcze kilku kroków. Jednym z nich jest przydzielenie mu odpowiedniego zakresu w pamięci (adresu) oraz wybór jednego z dostępnych obsługiwanych kanałów bezpośredniego dostępu do pamięci. Urządzenia rozszerzeń muszą nie tylko mieć swoje miejsce w kolejce, ale i należeć do jakiejś przestrzeni adresowej. System operacyjny nieobsługujący technologii Plug and Play (np. dlatego, że ta jeszcze nie istniała) nie umiał samodzielnie zainicjalizować takich urządzeń i przydzielić im odpowiednich zasobów. Z kolei BIOS nieobsługujący ACPI nie potrafił automatycznie zarezerwować np. odpowiedniego przerwania. Dlatego konfiguracja urządzeń następowała ręcznie.

Każda karta rozszerzeń przychodziła z instrukcją, która zazwyczaj zawierała pustą, przygotowaną do wypełnienia tabelkę: „wpisz tutaj, jakie przerwanie i kanał DMA przypisano dla tego urządzenia”. Montując nowe, należało znać ustawienia poprzednich, by nie doprowadzić do konfliktu. Szczególnie groźny był konflikt adresów w pamięci, te bowiem były ustawiane z użyciem zworek. Na ich podstawie urządzenie bezpośrednio adresowało odpowiednie komórki pamięci i jeżeli kilka urządzeń próbowało zrobić to samo, oba mogły przestać działać albo doprowadzać do przedziwnych zakleszczeń. Ustawienie przerwania i kanału DMA oraz innych, pomniejszych detali niezbędnych do zainicjalizowania urządzenia, następowało poprzez dopisanie do pliku CONFIG.SYS odpowiedniej dyrektywy ładującej dostarczony (na dyskietce) sterownik. Do owego sterownika dodawano zbiór parametrów, tak by on – znając adres w pamięci – próbował wysłać oczekiwaną konfigurację zasobów do urządzenia, celem jego inicjalizacji.

Tak skomplikowana procedura uruchamiania nowych urządzeń wymusiła tworzenie różnorakich protokołów automatycznej konfiguracji urządzeń. Dzięki temu, np. w kostce Award BIOS umieszczono rozszerzenie standardu ACPI, które odpytywało wszystkie karty w gniazdach ISA i gdy odpowiedziały (o ile odpowiedziały), przydzielał im odpowiednie, wolne zasoby. Magistrala PCI (oraz nadbudowane nad nią gniazdo AGP) była jeszcze mądrzejsza. Odpowiednie przerwanie, miejsce w pamięci i kanał DMA były negocjowane na etapie inicjalizacji urządzenia, a następnie mogły zostać przemapowane na żądanie przez system operacyjny. Poza usunięciem największego bólu głowy, jakim była konieczność ręcznego ustawiania zasobów, rozwiązano problem „ciasnoty”: im więcej urządzeń było dostępnych w systemie, tym mniejsza dostępność przerwań i coraz gęstsze upakowanie przestrzeni adresowej. Tymczasem użycie kart PCI pozwalało na automatyczny przydział zasobów, a w dodatku – uwspólnianie przerwań. Każde przerwanie przeznaczone dla PCI było zajmowane przez wirtualne urządzenie pośrednika, który rozdysponowywał je między odpowiednie karty. Czysta radość.

Kłopoty zaczynają się, gdy usiłuje się pomieszać oba te podejścia. Przez wiele lat komputery PC zawierały jednocześnie gniazda PCI i ISA, a to pozwalało na podpięcie starszych kart ISA, bez PnP, wymagających ręcznego przydzielania zasobów. Trzeba bowiem połączyć automatyczny przydział zasobów z ręczną dzierganiną. To może się okazać bardzo trudne. I w ten sposób docieramy z powrotem do mojego kochanego skanera. Wymaga on ręcznego ustawienia zakresu pamięci (zworki) oraz kanału DMA i IRQ (system). Znalezienie wolnego obszaru w przestrzeni adresowej było proste. Gorzej było z przerwaniem. Nie było wolne ani jedno. Użyłem wszystkich slotów PCI, ISA i AGP, a zastosowana karta graficzna, zdecydowanie „za nowa” jak na ten sprzęt, zajęła od razu trzy przerwania. Trzy karty PCI gnieździły się na jednym przerwaniu. A SoundBlaster na ISA zarezerwował sobie jedno dodatkowe IRQ na… stół mikserski? Matko jedyna.

Pozostało mi zwolnić przerwania. W BIOSie wyłączyłem oba porty szeregowe i port równoległy. Jako, że z płyty (przez piny!) były wyprowadzone gniazda PS/2 i USB, chwilowo nie potrzebowałem COM1 i COM2. Po restarcie zwolniły się dwa przerwania (nie trzy!), a układ zajętych IRQ był… zupełnie inny. Automat ACPI przydzielił zasoby kompletnie inaczej, niż poprzednio. I jak tutaj stosować karty bez Plug-and-Play?

Na szczęście, Windows Millennium zawiera rozbudowane środowisko ustawień zgodności ze starym dziadostwem, więc wymusiłem „rezerwację” jednego z przerwań i kanału DMA. Dzięki temu zawsze miałem wolny zasób dla mojej antycznej karty. Niniejsze zasoby wpisałem do panelu konfiguracji sterownika TWAIN dla owego skanera. Oprogramowanie ScanWare z 1992 roku wygląda horrendalnie brzydko i zawiera mnóstwo bezużytecznych przełączników. Gdzieś w gąszczu opcji jest też pole na konfigurację zasobów. Podałem tam więc moje rezerwacje.

Stare dziadostwo na zawsze pozostanie jednak starym dziadostwem. Mimo odpowiedniego przydziału zasobów, komputer resetował się, gdy usiłowałem cokolwiek zeskanować. Dopiero, gdy zdjąłem rezerwację na kanał DMA (dalej go używając!), urządzenie zaczęło działać. Tymczasem dziś, taki skaner (choć skanery ręczne nie bez powodu wymarły) nie byłby zakończony kablem podpinanym pod dedykowaną kartę, a zwyczajną wtyczką USB. A po podpięciu, system operacyjny samodzielnie pobrałby w tle potrzebne sterowniki z Internetu.

W takim kontekście, marudzenie na USB wydaje się mocno przesadzone. Nie chodzi tu o to, by ignorować wady, a tych jest niemało, zwłaszcza w wariancie „C”. Ale pojawiające się gdzieniegdzie głosy, że USB tworzy więcej problemów, niż rozwiązuje i jakimś cudem z powrotem prowadzi do mnogości gniazd, jest bardzo chybione. Standard USB, w niemałych zresztą bólach, wdrażano w komplecie z komponentami ACPI i Plug and Play. Jest to standard niezwykle nowoczesny, jak na owe czasy, swoim projektem kojarzący się z dzisiejszymi rozwiązaniami a nie z rokiem 1996. Zrywa on kompletnie ze starym podejściem do konfigurowania urządzeń peryferyjnych i wyprzedza swoją innowacyjnością nawet autokonfiguratory PCI, niewątpliwie się zresztą nimi inspirując. Ówczesne systemy operacyjne były do niego kompletnie nieprzystosowane. Dodanie obsługi USB do Windows 95 wiązało się z astronomicznymi wygibasami, jak przeszczepienie kawałka jądra NT (słynny NTKERN.VxD), podczas, gdy sam NT nie tylko nie obsługiwał USB, ale nawet Plug and Play! Chodziło tylko o dodanie obsługi nowego, nowoczesnego modelu sterownika, czyli WDM. Sam NT musiał czekać na obsługę USB aż do 2000 roku! Mimo, że Microsoft należy do konsorcjum definiującego tenże standard.

Problemy z hubami USB, niskie próbkowanie myszy dla graczy, blokowanie klawiszy na klawiaturach nie-PS/2 oraz niekompatybilne kable: to wszystko zasadne zarzuty. Ale alternatywą było własnoręczne wkręcanie kart rozszerzeń i ustawianie zworek. To dlatego wtedy dostawaliśmy pięknie wydane instrukcje obsługi w segregatorach, a dziś tylko pismo obrazkowe i regulacje EU dotyczące elektrośmieci. Nie dlatego, że wszyscy oszczędzają. Dlatego, że mamy za sobą doprawdy frustrujące czasy, co warto momentami mieć na uwadze.

A sam ten skaner ręczny to też urocza zabawka. Może napiszę o nim samym w kolejnej części, jeżeli będą chętni :)