Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 [ 77 ] 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

ние контроллера диска, если считывать из него данные, а при записи в него данных передает команду контроллеру. Кроме того, часто сам факт записи данных в порт ввода/вывода приводит к выполнению некоторых действий, независимо от характера передаваемых данных. Например, это так для регистра команд АТ-совместимого контроллера. При работе с ним параметры заносятся в младшие регистры, а в регистр команд помещается код операции. Сигналом начала операции является факт записи данных в регистр команд.

В дополнение, этот случай является иллюстрацией ситуации, когда назначение регистров зависит от режима работы. В приведенном в таблице примере режим выбирается шестым битом шестого регистра (см. табл. 3.7). Данные, записываемые или считываемые в регистры 3-5, а также младшие четыре бита регистра 6 по-разному интерпретируются в зависимости от значения бита LBA.

Теперь рассмотрим, как при помощи com out команда передается контроллеру. Прежде чем менять какие-либо регистры, программа узнает, занят ли контроллер, считывая бит STATUS BSY. Здесь важна скорость, и так как контроллер обычно должен быть свободен или станет свободен скоро, здесь используется активное ожидание. Поэтому в начале кода функции вызывается команда waitfor, тестирующая значение бита STATUS BSY. Для повышения скорости эта команда реализована в виде макроса, который один раз проверяет значение бита, и только если контроллер занят, вызывает функцию ожидания. Это позволяет избежать накладных расходов на вызов функции в большинстве случаев. В тех редких ситуациях, когда контроллер занят, вызывается функция w waitfor, в цикле проверяющая значение бита занятости до тех пор, пока контроллер не освободится или не истечет заданный интервал времени. В результате, если контроллер свободен, будет возвращено значение истина с минимальной задержкой. Если контроллер занят, будет возвращено значение истина , когда удалось дождаться его освобождения, и ложь в другом случае. Подробнее мы расскажем об этом, когда займемся самой функцией w waitfor.

Контроллер способен обслуживать более одного диска, поэтому, когда он освободится, в регистры записывается байт, выбирающий привод, головку и режим работы, и waitfor вызывается снова. Иногда приводу не удается выполнить команду или правильно вернуть код ошибки, в конце концов, это механическое устройство, которое может заесть или просто сломаться, и для страховки отправляется сообщение задаче таймера, с целью запланировать вызов подпрограммы, которая разблокирует драйвер. Следом за этим команда передается контроллеру, для чего сначала все параметры записываются в разные регистры, а затем в регистр команд кладется код самой команды. Последний шаг является критической секцией, поэтому он обрамлен вызовами процедур lock и unlock, которые, соответственно, запрещают и разрешают прерывания.

Следующие несколько функций, которые мы рассмотрим, меньше по объему. Мы уже отмечали, что w finish вызывает w need reset, когда счетчик сбоев превышает половину от максимального числа попыток (MAX ERRORS). Кроме того, та же функция вызывается в том случае, когда приходится ожидать готовности или прерывания диска. Работа функции w need reset сводится к тому, чтобы устано-



вить переменную state для каждого диска в массиве wini, чтобы при следующем обращении была повторена инициализация.

Функция w do close в отношении обычного жесткого диска очень проста. Если необходима поддержка CD-ROM или других приводов со сменными носителями, подпрограмма должна быть усложнена, в нее следует добавить код, отпирающий дверцу привода или выбрасывающий носитель, в зависимости от того, какие действия поддерживает оборудование.

Функция com simple отправляет команду контроллеру и немедленно завершается, не выполняя обмен данными. В эту категорию попадают команды, которые служат для идентификации диска, установки некоторых параметров и повторной калибровки привода.

Когда com out подготавливает задачу таймера к возможному сбою, она передает адрес подпрограммы w timeout, чтобы задача таймера вызвала ее, когда истечет заданный период времени. Обычно диск успевает выполнить задание раньше, после чего присваивает переменной w command значение CMD IDLE. Обнаружив это значение, w timeout определяет, что команда выполнена, и завершается. Если команда чтения или записи не успела завершиться, имеет смысл уменьшить объем запросов на чтение или запись данных. Это делается в два этапа, для чего количество запрашиваемых секторов уменьшается сначала до 8, затем до 1. Во всех случаях истечения времени ожидания на экран выводится сообщение и для повторной инициализации всех приводов вызывается функция w need reset. Кроме того, вызывается функция interrupt, которая отправляет сообщение задаче жесткого диска, имитируя аппаратное прерывание, которое должно произойти по завершении дисковой операции.

Когда требуется сброс, вызывается w reset. Эта подпрограмма использует одну из функций, входящих в драйвер часов, milli delay. Сначала w reset делает начальную задержку, чтобы дать приводу время вернуться в исходное состояние после предыдущих действий. Затем апробируется бит регистра управления контроллера диска, то есть сначала на заданное время бит устанавливается в 1, а затем возвращается в 0. Далее вызывается waitfor, чтобы позволить диску прийти в состояние готовности. Если сброс не завершился успехом, на экран выводится сообщение и возвращается код ошибки. Сделавшей вызов программе остается решить, как в этом случае поступить.

Команды, затрагивающие обмен данными с диском, обычно завершаются генерацией прерывания, которое отправляет сообщение обратно драйверу. Фактически прерывание генерируется каждый раз, когда считывается или записывается сектор. Таким образом, после того как дана команда, всегда вызывается w intr wait. В свою очередь, эта подпрограмма в цикле обращается к receive, игнорируя содержимое сообщений. Цикл завершается, когда приходит сообщение, устанавливающее w status в значение не занято . По получении подобного сообщения проверяется состояние запроса. Это еще одна критическая секция, поэтому, чтобы гарантировать, что во время ее обработки не произойдут новые прерывания, используются команды lock и unlock.

Мы встретили несколько мест с подставленным макросом waitfor, означающим активное ожидание определенного значения бита занятости регистра



состояния контроллера диска. Этот макрос сначала проверяет бит и, если контроллер оказался занят, вызывает функцию w waitfor. В свою очередь, она устанавливает таймер при помощи milli start и входит в цикл, поочередно проверяющий регистр состояния и таймер. Если интервал времени истекает, вызывается w need reset, чтобы обеспечить сброс контроллера при следующем обращении к диску.

Параметр TIMEOUT, используемый функцией w waitfor, равен 32 с. Аналогичный параметр, WAKEUP, нужный при планировании пробуждения драйвера по сигналу задачи часов, равен 31 с. Это очень большие периоды времени для активного ожидания, если сравнить их с обычным процессом, которому на работу дается 100 мс. Такие большие задержки обусловлены существующими стандартами для АТ-совместимых дисков. Согласно этим стандартам, диску может потребоваться до 31 с, чтобы разогнаться. Конечно, на практике такое время требуется только в самом худшем случае, а разгон диска в большинстве систем происходит при включении питания или после длительных периодов бездействия. MINIX - развивающаяся система. Возможно, когда будет добавлена поддержка CD-ROM (или других устройств, у которых раскрутка происходит часто), возникнет необходимость в новом способе обработки задержек.

Функция w handler играет роль обработчика прерываний. Адрес этой функции записывается функцией wjdentify в таблицу дескрипторов прерываний (IDT) при первом запуске драйвера. Когда генерируется прерывание, регистр состояния контроллера диска копируется в переменную w status, после чего вызывается функция ядра interrupt, чтобы повторно запланировать задачу жесткого диска. Конечно, в тот момент, когда приходит прерывание от жесткого диска, его задача уже находится в приостановленном состоянии в результате предшествующего вызова receive, который сделала подпрограмма w intr wait после инициирования дисковой операции.

Последняя функция в файле at wini.c это w geometry. Она возвращает максимальное значение номеров цилиндров, дорожек и секторов для выбранного жесткого диска. В отличие от RAM-диска, где эти значения имитировались, здесь в эти числа вложен реальный смысл.

3.7.5. Работа с дисководом для гибких дисков

Драйвер флоппи-дисковода (для гибких дисков) сложнее, чем драйвер жесткого диска, а его код больше. Это на первый взгляд парадоксально, так как механизмы дисковода для гибких дисков должны быть проще, чем механизмы винчестера, но контроллер первого проще и требует к себе больше внимания от операционной системы. Помимо того, некоторые сложности вносит сменный носитель. В текущем разделе мы рассмотрим некоторые вопросы, которые могут оказаться полезными для программиста, имеющего дело с гибкими дисками. В основных деталях код драйвера сходен с кодом драйвера жесткого диска. Детально же разбирать код, ввиду его сложности, мы не будем.

Одна из проблем, с которыми мы не столкнемся, работая с флоппи-приводами, - это необходимость поддерживать много типов контроллеров, что было



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 [ 77 ] 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.