_____________________________________________________________________________________
Что мы используем при отладке программ для ATA/ATAPI-устройств ?
Почему ошибки все-же остаются незамеченными ?
_____________________________________________________________________________________

*** Все программисты знают, что отлаживать программы нужно с помощью "дебаггера",
но не все программисты знают, что отладка программы типа "бухгалтерский учет"
и отладка программы для управления каким-нибудь электронным устройством,
вещи абсолютно разные и требуют разных подходов и квалификации.

...Если для написания и отладки программы типа "бухгалтерский учет", требуется только
знание назначения и применения, некоторой части инструкций, какого-нибудь
языка "высокого" уровня и правил порядка различных бухгалтерских расчетов и подсчетов,
то для написания и отладки программы для управления электронным устройством,
нужно еще как минимум, знать его принципиальное устройство, ньюансы его работы
и умение программировать на языке ассемблера, что в свою очередь,
ведет к необходимости знания компьютерного "железа".

... Трудность обнаружения ошибок при отладке программ управления электронными устройствами,
связана с тем, что "дебаггер" не может остановить выполнение микропрограммы самого устройства,
а значит, не имеет возможности, получить результата работы, происходящей в реальном времени.

... Примером может послужить извращения программы "HDD Regenerator 1.41 FULL":
_____________________________________________________________________________________
___________________Logs_Signs_History_____________________
  _   = Read From Register               Examle: 1X5_8A
  =   = Write To Register                Examle: 1X7=EC
  <<  = Single Read From 1X0 Register    Examle: <<7A42
  >>  = Single Write To 1X0 Register     Examle: >>AA55
  #x: = Maximal ATA-Standard Number For The Met Command
__________________________________________________________

3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50 - Status Register /DRDY+DSC/ =Устройство вышло в готовность.

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C5
Command: ATA-#6: WRITE MULTIPLE
1x7_D0 - Status Register /BUSY+DRDY+DSC/ = Устройство ЕЩЕ НЕ ГОТОВО к обмену данными !!!

[****** Host WRITE Data To HDD *******]....Однако данные посылаются.
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
_____________________________________________________________________________________

Подобные ошибки невозможно отследить никакими программными "дебаггерами",
потому что, при пошаговом исполнении программы из отладчика,
HDD всегда выдаст готовность к обмену данными, так-как, время выхода в состяние
готовности HDD, гораздо меньше времени пошагового исполнения программы.
А так-как, инструкции обычно группируются в отдельные подпрограммы и вызываются
посредством CALL (Procedure),
...
BEGIN:
CALL RESET
CALL DRV_SELECT
CALL GET_STATUS
CMP  AL,ERROR
JE   DRV_ERROR
...
CALL WRITE_SECTOR
CALL GET_STATUS
CMP  AL,ERROR
JE   DRV_ERROR
CALL INC_SECTOR
JMP  BEGIN
DRV_ERROR:
...
то, как мы видим, и визуально, явных ошибок не наблюдается.
И вряд-ли, кто нибудь, начнет проверять отдельные процедуры,
если они не вызывают ошибок при исполнении в отладчике.

*** К чему это я ?...

А все к тому, что лучше, удобнее, универсальнее и дешевле
IDE-BUS ANALYZER IDEGRABB16(ALL), для этих целей вы не найдете.
Он поможет вам быстро обнаруживать любые ошибки в программах для ATA/ATAPI-устройств,
при работе в реальном времени, и писать действительно идеальные программы для них.
Кроме того, он позволяет быстро научиться программировнию ATA/ATAPI-устройств,
на примерах лучших программ профессиональных программистов (я таким не являюсь).
______________________________________________________________________________________
__________________________________Цитаты______________________________________________
______________________________________________________________________________________

HDD Regenerator 1.41 FULL

Вы часто попадали в ситуацию, когда из-за поврежденных секторов "летел" ваш винчестер?
Данная программа восстанавливает сбойные сектора на жестком диске.
Не прячет, а именно восстанавливает используя специальный алгоритм сигналов
высокого и низкого уровней.
...
Supported file systems
----------------------
The product works exclusively at physical level...

______________________________________________________________________________________
__________________________________Комментарии_________________________________________
______________________________________________________________________________________

*** "Не прячет, а именно восстанавливает..."

Автор видимо абсолютно не в курсе алгоритмов исключения сбойных секторов,
используемых в Firmware современных HDD-накопителей и не знает о том,
что сбойный сектор может быть "скрыт" даже при попытке его чтения и что,
решение об исключении (наличии) сбойного сектора принимается только
самим HDD (его Firmware), независимо от желания писателей хдд-регенераторов.

*** "используя специальный алгоритм..."

В понимании автора, "специальным алгоритмом", является чередование записи сектора
сплошными единицами [FFFF] или нулями [0000]. О том что существуют такие паттерны
как [AA55-55AA], [0F0F-F0F0] и многие другие, автору видимо не известно или-же,
паттерн FFFF-0000, является для него самым сложным и специальным.
Кроме того, данный паттерн и метод не являются изобретениеми
и не могут быть защищены никакими патентами или лицензионными заявлениями,
а последние, кстати, могут быть использованны как доказательства обмана
покупателей данного продукта, в суде против автора.

*** "The product works exclusively at physical level..."

Понятие автора о работе на физическом уровне, то-же своеобразно.
Работая с секторами в LBA-режиме (LBA = адресация ЛОГИЧЕСКОГО блока),
он всех уверяет, что продукт работает ИСКЛЮЧИТЕЛЬНО на ФИЗИЧЕСКОМ уровне.
По стилю работы программы с диском, видно что автор не работает с портами HDD
напрямую, а использует прерывания BIOS (13H), которое никак не приспособленно
для работы с программами, решающими такого рода задачи (смотрите ниже).
Видно, прочитав давно устаревшую информацию об INT-13H, автор и решил,
что работает на физическом уровне, либо он, просто путает HDD с Floppy Drive.

*** "HDD Regenerator" - это пока единственная, встреченная мной,
продаваемая, рекламируемая и распостроняемая программа,
представляющая пример абсолютно безграмотного программирования
и наглого обмана купивших ее пользователей, путем рекламирования
вымышленных и несуществующих, основных возможностей программы.

*** Ниже приведены доказательства всего вышеперечисленного.

______________________________________________________________________________________
__________________________________Реальность__________________________________________
______________________________________________________________________________________

     LOGS-DECODER For IDEGrabb16(ALL) Log-Files V3.1

___________________Logs_Signs_History_____________________
  _   = Read From Register               Examle: 1X5_8A
  =   = Write To Register                Examle: 1X7=EC
  <<  = Single Read From 1X0 Register    Examle: <<7A42
  >>  = Single Write To 1X0 Register     Examle: >>AA55
  #x: = Maximal ATA-Standard Number For The Met Command
__________________________________________________________
 (C)NazYura 2006 Krasnodar <> EMail: NazYura(C)Rambler.ru


**********************************************************
    Decoding IDEGrabb16ALL Log-File --> HDDREG.GRB 
**********************************************************

 Start HDD-Regenerator 1.41
============================
3x6=08 - DevCtrl
1x6=E0 - Select Drive

*** Программа не считывает паспорт диска и не проверяет его готовность,
а видимо, берет паспортные данные, посредством DOS-прерывания INT 21H
или INT 13H, хотя давно известно, что данные функции имеют ошибки и могут
неправильно интерпритировать данные установленных устройств.
Кроме того, физическое наличие диска не проверяется и во время работы программы.
Если HDD "завис", остановился или находится в Sleep-режиме, перестав реагировать
на команды, то программа, не "заметит" этого и будет "лечить" HDD, даже физически
отсоединенный от компьютера (по методу Кашпировского - на расстоянии),
сообщая, приблизительно 1 раз в 3 секунды о том что:
Sector 0 was wasn't recovered
Sector 1 was wasn't recovered
Sector 2 was wasn't recovered
Sector 3 was wasn't ...

И если пользователь честно будет ждать завершения сканирования остановившегося HDD,
размером в 80Gb, то на это уйдет около 15 лет, а "зависшего", около 5 лет.

продолжение...
 Start HDD-REG scan from 1794000 LBA
=====================================
3x6=08 - DevCtrl
1x6=E0 3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=D0 1x4=5F 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58

[****** Host READ Data From HDD ******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50 - Status Register /DRDY+DSC/ = Устройство вышло в готовность

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=D1 1x4=5F 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58 - Status Register /DRDY+DSC+DRQ/ = Устройство готово к обмену данными

[****** Host READ Data From HDD ******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50
....____________cutting____________....

*** Программа считывает строго по одному сектору, хотя для обеспечения
быстродействия, желательно, считывать максимально-возможное количество
секторов (обычно, блоком, по 256 секторов до встреченной ошибки).
Однако программа не останавливается в борьбе за снижение производительности
и наносит самый мощный по ней удар - запись в порт 3x6(DeviceControl)
абсолютно бесполезного значения  и запись в 1x6(DeviceSelect), после чтения каждого сектора.
Это прямо указывает на использование 13H BIOS-прерывания.
Именно в этом прерывании наблюдается такая логика работы:
3x6=08 - посылка давно устаревшего (ATA-1) бита в порт "DeviceControl"
1x6=E0 - постоянная посылка старшего адреса LBA-28, независимо от того,
изменился он или нет, хотя для 28-битной аресации, это нужно проделать
всего 16 раз, а не 285212670 раз (при чтении сектора по одному).
Автор видимо не в курсе, что порты 3x6(DeviceControl) и 1x6(DeviceSelect) коммандные,
a порт 1x6(DeviceSelect), имеет высший приоритет перед любыми другими IDE-портами
так-как, любое обращение к нему, вызывает внутреннее прерывание процессора HDD,
останавливающее все (кроме дописывания текущего сектора) операции.

... При любом обращении к порту 3x6(DeviceControl), HDD завершает последнюю операцию,
(например, дописывает сектора данными оставшимися в буфере), сохраняет значения
всей регистров и переменных итд, итп, проверяет записываемое значения в порт
3x6(DeviceControl), "ресетует" - если включен флаг "SoftReset"
или реинициализирует режимы (например CHS, LBA28-бит, LBA48-бит).
Кроме этого, реинициализируется сам IDE-контроллер на предмет реагирования на "nIEN"
(генерирование сигнала прерывания комьютеру по завершениии операции HDD).
Поэтому, даже после физического отключения HDD, программа, постоянно обращающаяся к этому
порту, использующая DOS-прерывания или такую-же логику работы с портами,
будет продолжать работать очень медленно.

... При любом обращении к порту 1x6, HDD дописывает сектора данными оставшимися
в буфере, после чего, происходит немедленная и полная остановка текущих
операций, сохранение значений всей регистров и переменных в памяти итд, итп,
проверка записываемого значения в порт 1x6(DeviceSelect) и, если был выбран
другой HDD (например Slave), ожидание следующей обращения к этому порту (выбор Master),
после чего, все переменные восстанавливаются и HDD продолжает прерванную операцию.

... Записанное в порты 3x6(DeviceControl (исключая HOB-флаг)) и 1x6(DeviceSelect) значения,
не изменяются до новой перезаписи, или "ресета" (или появлении ошибки для CHS-режима),
поэтому, нет никакой необходимости каждый раз перезаписывать флаг "LBA",
это следует делать только после изменения старшего адреса LBA28
или после НЕОБХОДИМОГО включения флага "SoftReset".

... Все операции с портами 3x6(чтение/запись) и 1x6(чтение/запись),
занимают очень много времени, поэтому, для увеличения быстродействия и предотвращения
бесполезных реинициализаций HDD, обращаться к этим портам, нужно только в случае
необходимости, а статус считывать, именно из порта 1x7 а не 3x6.

... Этого автор мог и не знать конечно, в ATA так не написано,
но в ATA, так-же и не сказано, что нужно после чтения каждого сектора, проделывать эти операции.

*** Программа определяет не код ошибки, а только ее наличие, при этом полагая,
что существуют только ошибки чтения или записи сектора, поэтому, если до запуска
программы, HDD находился например в Sleep-режиме, то программа не будет ждать
готовности HDD, а сразу начнет его "лечить", что приведет к бесконечной ошибке.
Что-бы вывести его из этого состояния, нужно, как минимум, произвести "ресет"
и заново проинициализировать HDD, чего в программе, нет и в помине.
"Ресет", бывает так-же необходим и при возникновении ошибки (хотя и не часто).
В частности, если произошла ошибка при чтении или записи командой READ/WRITE MULTIPLE,
то нет никакой уверенности, что следующая команда READ/WRITE MULTIPLE, не завершится
с поднятым флагом ABORT, если предварительно не подать команду SET MULTIPLE
как того требует ATA-стандарт. Автор, даже не удосужился подать такую команду в начале.

... На первый взгляд, "Software Reset", кажется очень простой и понятной процедурой,
но на практике, очень часто используется не по назначению и без пользы.
Многие используют "Software Reset", ожидая от него результата "Hardware Reset" .
... Сигнал "Hardware Reset", управляет (грубо говоря) перезапуском генератора тактовой частоты
процессора HDD, что приводит к полному перезапуску всего устройства в целом.
"Hardware Reset", можно сравнить с ключом зажигания автомобиля или кнопкой "Reset" компютера.
Сигнал "Hardware Reset", передается по проводнику и не является параметром команды.
"Hardware Reset", позволяет вывести устройство из "зависшего" состояния,
при условии физической исправности устройства.

... Команда (а не сигнал) "Software Reset", дает указание программе управления HDD (Firmware),
произвести сброс всех настроек устройства на параметры используемые по умолчанию
(такие-же как и при включении питания устройства), исключая глобальные параметры
инициализирующие основные режимы работы устройства (например режимы PIO, DMA, UDMA и пр.),
которые управляются своими командами.
"Software Reset", НЕ ПОЗВОЛЯЕТ вывести устройство из "зависшего" состояния,
поэтому, подавать эту команду нужно, если был изменен какой нибудь режим работы
устройства (например Power Management, Look-Ahead, Write Cache итд.) и необходимо
отменить раннее произведенные настройки.
На практике-же, часто "ресетуют" после после возникновения ошибки, хотя это и не нужно,
или-же, не "ресетуют", когда это (согласно ATA-стандарта) необходимо.

... Ошибки эти, часто остаются незамеченными, из-за того, что мрогие производители ATA-устройств,
не во всем следуют рекомендациям ATA-стандарта. Например, при установленном флаге BUSY,
ATA-стандарт, призывает производителей, контролировать только установку флага "Software Reset"
в регистре 3x6(DeviceControl) и флаг "Device Select", в регистре 1x6(Device/Head).
То-есть, подразумевается, что программа, должна держать паузу, в ожидании снятия флага BUSY,
и если время ожидания превысило значение "Time Out", то должен быть установлен флаг
"Software Reset-ON" и после определенной паузы, "Software Reset-OFF".
Однако, очень часто, производители ATA-устройств, не мудрствая лукаво, просто-напросто,
ничего не предпринимают для опеспечения именно такой последовательности.
"Firmware", продолжает контролировать все порты как обычно и выполняет
любую посланную команду, тем самым, прерывая исполнение текущей операции.
Но ведь так, поступают не все производители и поэтому, ошибки проявляются не на всех устройствах.
Из-за этого, невозможно гарантировать, корректное исполнение раннее посланной команды.
Например, как можно гарантировать успешный рестарт микропрограммы, если без ожидания
необходимой паузы после включения флага "SRST", прервать операцию следующей командой ?

Порт 3x6(DeviceControl):
________________________
04h [00000100] \  SoftReset ON  - Единственно-верное значение (остальные биты бесполезны, хотя и не вредны (кроме 0-ого))
:Pause          > Ждем паузу...
00h [00000000] /  SoftReset OFF - Вот здесь можно установить и другие биты (кроме 0-ого)

02h [00000010] = nIEN Enable
80h [10000000] = HOB
82h [10000010] = HOB + nIEN Enable
08h [00001000] = Бит использовался только в ATA-1 (отменен).

... Если включен бит SRST(SoftReset) [00000100], остальные биты игнорируются, так-как,
после "ресета", все флаги сбрасываются (обнуляются).
... После "ресета", необходимо проверять регистры на наличие следующей сигнатуры:
(это необходимо для полной уверенности, что "ресет" действительно был произведен)
1x2 = 01h
1x3 = 01h
1x4 = 00h
1x5 = 00h
1x6 = 00h

... Использование флага nIEN, в основном, имеет практическое значение только в программах
управления сложными, дисковыми системами (RAID/SCSI и пр.) использующими Command Queue,
а так-же в операционных системах (DMA), для увеличения их быстродействия и поэтому здесь
не рассматривается, хотя использование этих возможностей для сканирования дисков
большой емкости (без DMA), выглядит заманчиво.
... Флаг HOB, необходимый элемент для адресации 48-битного адреса.
Жаль только, что механизм реализации адресации, довольно "кривой".
Мало того, что используется активный командный регистр, так еще нужно "вручную",
перед каждой записью 48-битного адреса, включать этот флаг, так-как при записи
командного регистра 1x7, флаг автоматически обнуляется.
Поэтому, скорость сканирования в режиме LBA48, довольно низкая.

продолжение...
------------------------------------------------------------------------
---------------- НАЧАЛО ПРОБЛЕММНОЙ ОБЛАСТИ ДИСКА ----------------------
------------------------------------------------------------------------
----- В этой области диска, неуверенно читается сервометка трека -------
----- Такую ошивку исправить невозможно без замены всего трека ---------
------------------------------------------------------------------------
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_51 \_ Найден первый сектор с ошибкой - LBA 1B6342h (1794882)
1x7_51 /
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50 - Status Register /DRDY+DSC/ = Устройство вышло в готовность

------------------------------------------------------------------------
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_51 \_ Найден второй сектор с ошибкой - LBA 1B6343h (1794883)
1x7_51 /
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50
------------------------------------------------------------------------
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_51 \_ Повторно читается первый сектор с ошибкой - LBA 1B6342h (1794882)
1x7_51 /
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50 - Status Register /DRDY+DSC/ = Устройство вышло в готовность
------------------------------------------------------------------------
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE - Записывается паттерн FFFF в первый сектор

1x7_D0
1x7_D0 - Status Register /BUSY+DRDY+DSC/ = Устройство НЕ готово к обмену данными !!!

[****** Host WRITE Data To HDD *******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....
------------------------------------------------------------------------

3x6=08 - DevCtrl
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_51 \_ Повторно читается второй сектор с ошибкой - LBA 1B6343h (1794883)
1x7_51 /
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE - Записывается паттерн FFFF во второй сектор

1x7_D0
1x7_D0 - Status Register /BUSY+DRDY+DSC/ = Устройство НЕ готово к обмену данными !!!

[****** Host WRITE Data To HDD *******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....

------------------------------------------------------------------------
3x6=08 - DevCtrl
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58 - Status Register /DRDY+DSC/ = Устройство готово к обмену данными

[****** Host READ Data From HDD ******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....

1x7_50 \_ Читается первый сектор - LBA 1B6342h (1794882) (ошибки нет)
1x7_50 /
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE - Записывается паттерн 0000 в первый сектор

1x7_D0
1x7_D0 - Status Register /BUSY+DRDY+DSC/ = Устройство НЕ готово к обмену данными !!!

[****** Host WRITE Data To HDD *******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58 - Status Register /DRDY+DSC+DRQ/ = Устройство готово к обмену данными

[****** Host READ Data From HDD ******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....

1x7_50 \_ Читается второй сектор - LBA 1B6342h (1794882) (ошибки нет)
1x7_50 /
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE - Записывается паттерн 0000 во второй сектор

1x7_D0
1x7_D0

[****** Host WRITE Data To HDD *******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58 - Status Register /DRDY+DSC+DRQ/ = Устройство готово к обмену данными

[****** Host READ Data From HDD ******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....

1x7_50
1x7_50
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE

1x7_D0
1x7_D0 - Status Register /BUSY+DRDY+DSC/ = Устройство НЕ готово к обмену данными !!!

[****** Host WRITE Data To HDD *******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....

"Устройство НЕ готово к обмену данными !!!"
... Программа не дожидаясь снятия флага BUSY, записывает на диск данные.
Ошибки не происходит только потому, что HDD, все-же успевает выйти в режим готовности
к приему, пока программа переходит на процедуру отправки данных.
Если-бы программа была "побыстрее" или HDD "помедленнее выходил в готовность",
то часть данных, посылаемых программой, была-бы пропущена.
Никакую ошибку при этом, данная программа не обнаружит, так-как HDD, будет оставаться
в режиме приема недостающих данных (DRDY+DSC+DRQ) и флаг ошибки выставлен не будет,
потому-что операция еще не закончена.
Если при этом будет записываться информация, то она конечно-же запортится.
...
Такого рода ошибки, почему-то, делают многие (в том числе и опытные) программисты,
использующие, не свои собственные библиотеки макросов, в которых со временем,
накапливаются еще и неиспользуемые (отмененные) флаги и функции.
Обычно флаги опрашиваются раздельно, например так:
...
test al,10000000b ;Sheck For BUSY
test al,00000001b ;Sheck For ERROR
test al,01000000b ;Sheck For DRDY
test al,00001000b ;Sheck For DRQ
...
При таком опросе очень важен приоритет опрашиваемых битов.
Какой бит опрашивать первым ERROR или BUSY ?
На этот вопрос ответить достаточно трудно, все зависит от контекста предыдущей команды.
Если это была команда PIO data-in - это одно, PIO data-out - это другое, No-Data - это третье...
... Device Diagnostic - это седьмое...
Ведь флаг ERROR недействителен когда поднят флаг BUSY.
С другой стороны, во многих случая, время удержания устройством флага BUSY, настолько коротоко,
что его невозможно "уловить". К тому-же, флаг BUSY не означает запрет на посылку других команд...
... Поэтому приходится опрашивать флаги поочередно и на всякий случай,
проверять дополнительно код ошибки, что далеко не всегда делается.
Учитывать все ньансы действительных и недействительных флагов во время исполнения различных команд,
время необходимых задержек ожидания и прочего, достаточно нетривиальная задача.
Я то-же много думал над тем, как упростить эту задачу и нашел, на мой взгляд, удачное решение.

... "Табличный метод распознавания флагов"
... "Tabulared method of recognition of flags" (C)nazyura
Теперь я, проверяю не конкретные флаги, а возвращаемое значение порта по подготовленной
таблице, которая включает любые, возможные комбинации сочетания флагов и их интерпритацию.
Вот обобщенный пример моего подхода на ассемблере (думаю, что кому нибудь сгодится):
;___________________________________________________________________________________________________________
...
		CALL SEND_COMMAND   ;Send Command To Drive
		CALL CHECK_STATUS   ;Check Status Code
		CMP  AL,'R'         ;Drive Is Ready ?
		JE   ALL_OK
...
		CMP  AL,'r'         ;Drive Is Ready With CORR flag ?
		JE   ALL_OK_CORR

		CMP  AL,'E'         ;Found Error ?
		JE   CHECK_ERROR
...
		CMP  AL,'T'         ;TimeOut Expired ?
		JE   TIME_OUT
...
		CMP  AL,'Q'         ;Found DRQ ?
		JE   RD_WR_DATA
...
		CMP  AL,'N'         ;Drive None, Sleep or Stupor ?
		JE   NONE_STUPOR
...
		CMP  AL,'K'         ;IDE-Conroller None or Windows ?
		JE   CONTROLLER_NONE

...
ALL_OK:
...
ALL_OK_CORR:
...
RD_WR_DATA:
...
CHECK_ERROR:
		CALL CHECK_ERROR   ;Check Error Code
...
TIME_OUT:
...
;___________________________________________________________________________________________________________
CHECK_STATUS    PROC    NEAR
		PUSH    BX
		PUSH    DX

		LEA     BX,MASK_STATUS		;Load Mask Table For Status Register
		MOV     DX,STATUS_REG
;----------------------------------------------------------------------------------------
;		LEA     BX,MASK_ERROR		;Load Mask Table For Error Register
;		MOV     DX,ERROR_REG
;----------------------------------------------------------------------------------------

LOOP_IN:

		IN      AL,DX
		XLAT                    ;Decoding Input Value
		CMP     AL,'B'          ;Check For BUSY
		JNE     EXIT_STATUS     ;Exit If Not BUSY
		CALL    PAUSE           ;Wait Some Time (Return = [AL = "T" If TimeOut Expired] (TimeOut=Pause*x))
		CMP     AL,'T'          ;TimeOut Expired ?
		JNE     LOOP_IN

EXIT_STATUS:

		POP    DX
		POP    BX

                RETN
CHECK_STATUS    ENDP

;________Таблица интерпритирована упрощенно и не полностью (для примера)____________________________________
;              00   01 02  03 04 05 06 07  08 09  0A 0B 0C 0D 0E 0F
;___________________________________________________________________________________________________________
MASK_STATUS DB 'N','E',02, 03,04,05,06,07, 08,09, 0A,0B,0C,0D,0E,0F   ;00h - "N" = Drive None, Sleep or Stupor
            DB 10, 'E',12, 13,14,15,16,17, 18,19, 1A,1B,1C,1D,0E,0F
            DB 'F','F','F','F','F','F','F','F','F','F','F','F','F','F','F','F' ; Drive Fault
            DB 30, 'E',32, 33,34,35,36,37, 38,39, 3A,3B,3C,3D,3E,3F
            DB 40, 'E',42, 43,44,45,46,47, 48,49, 4A,4B,4C,4D,4E,4F   ;Примеры для DRDY "R", "r" и DRQ "Q"
            DB 'R','E','R',53,'r',55,'r',57,'Q',59,'Q',5B,5C,5D,5E,5F ;50h/52h/54h/56h (DRDY/DRDY+IDX/DRDY+CORR/DRDY+CORR+IDX)
            DB 60, 'E',62, 63,64,65,66,67, 68,69, 6A,6B,6C,6D,6E,6F   ;58h/5Ah (DRDY+DSC+DRQ/DRDY+DSC+DRQ+IDX)
            DB 70, 'E',72, 73,74,75,76,77, 78,79, 7A,7B,7C,7D,7E,7F   ;54h/56h "r" = Drive Ready With Corrected Data
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B' ; BUSY ON
            DB 'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','K' ; BUSY ON FFh - "K" = Controller OFF or None
;___________________________________________________________________________________________________________
Две таблицы (для регистров STATUS и ERROR), обеспечат удобную, универсальную и безошибочную
работу с определением статуса и кодов ошибок.
Таблицы заполняются в соответствии с допустимым сочетанием флагов.
По таким таблицам можно "монторить" любые регистры. Можно вставить в них смещения для "JMP TABLE".
В саму процедуру CHECK_STATUS, можно добавить сообщения об ошибках, ожидание только запрошенного
кода с определением тайм-аута, разбор результата итд.
В результате выполнения такой процедуры, мы уверенно получим имменно то состояние HDD, которое ожидаем,
либо, уже интерпритированный код ошибки, без дополнительного разбора значений отдельных флагов.

продолжение...
3x6=08 - DevCtrl
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58

[****** Host READ Data From HDD ******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....

1x7_50
1x7_50
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=43 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE

1x7_D0
1x7_D0

[****** Host WRITE Data To HDD *******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58

[****** Host READ Data From HDD ******]
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF   яяяяяяяяяяяяяяяя
....____________cutting____________....

1x7_50
1x7_50
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50

1x6=E0 1x6=E0 1x1=00 1x2=01 1x3=42 1x4=63 1x5=1B 1x6=E0 1x7=C5

 Command: ATA-#6: WRITE MULTIPLE

1x7_D0
1x7_D0

[****** Host WRITE Data To HDD *******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000 0000 0000 0000   ................
....____________cutting____________....
.........
........
.......
......
.....
....
...
..
. и.т.д. и.т.п.
           *** Done Files Decoding ***
------------------------------------------------------------------------
------------------------------------------------------------------------
------------------------------------------------------------------------

*** В итоге, "восстановив" 2 сектора, путем прописывания FFFF и OOOO по 4 раза,
программа авторитетно заявила о том, что все восстановлено и поблагодарила
за использование уникального продукта. Однако, при повторном ее запуске,
опять обнаружила ошибки, на том-же месте.
Если-бы автор, для проверки сектора использовал старую, добрую команду
из ATA-3 "Read verify sector(s) (w/o retry)", а не "READ MULTIPLE",
то тогда, в большинстве случаев, он мог-бы обнаружить,
что сектор остается неисправным и псевдо-регенерация не помогает.
После очистки Glist на этом-же HDD, в котором было 217 исключенных секторов,
сей уникального продукт был запущен заново и после окончания работы программы,
в Glist оказалось 228 исключенных секторов, что доказывает абсолютную несостоятельность
утверждения автора "Не прячет, а именно восстанавливает..."


Программист, это не тот, кто пишет программы, а тот, кто знает то, для чего пишет.
(C)nazyura
________________________________________________________________________________

*** Теперь поговорим о искажениях и так называемых "фантомах"...

... В идеальном случае, программы работающие с ATA/ATAPI-устройствами, должны
получать от HDD данные, обусловленные только ATA-стандартом и производителями.
То-есть, устройство, должно принимать и возвращать, только верную информацию
о состоянии текущей операции или выполненой команды и неискаженные данные сектора.
Но это, к сожалению, возможно, только в идеале...
В реальных условиях обмена данными, и программы и HDD, получают немалое количество
искаженной информации, причины которых, можно разделить на две основные группы.

1: Физическое искажение сигналов на IDE-шине , происходящие по причинам
   некачественного напряжения питания, отсутствии заземления,
   "разгона" CPU и различных наисправностей HDD-контроллера.

2: Данные, появляющиеся при переходных процессах, во время (ре)инициализации
   IDE и HDD-контроллеров а так-же, при неучтенных (несогласованных) состояниях
   HDD-контроллера, во время исполнения им внутренних операций (Фантомы).
________________________________________________________________________________

1: Физическое искажение сигналов на IDE-шине...
   (подразумевается, что HDD, MB компьютера, CPU и оперативная память, исправны).
--------------------------------------------------------------------------------
Вот пример SMART-отчета реального, исправного HDD, долгое время, работающего
от некачественного блока питания без заземления:
--------------------------------------------------------
HDD: ST360021A; FW: 3.19; SN: 3.19
--------------------------------------------------------
            Name                        Val Worst Raw
Att #   1 : Read error rate           :  73   69  198864993  
Att #   3 : Spin up time              :  72   70  0  
Att #   4 : Number of spin-up times   :  97   97  3950  
Att #   5 : Reallocated sectors count : 100  100  0  
Att #   7 : Seek error rate           :  85   60  384250224  
Att #   9 : Power-on time             :  89   89  9740  
Att #  10 : Spin-up retries           : 100  100  0  
Att #  12 : Start/stop count          :  95   95  5219  
Att # 194 : HDA Temperature           :  32   53  32  
Att # 195 : Hardware ECC recovered    :  73   69  198864993  
Att # 197 : Current pending sectors   : 100  100  0  
Att # 198 : Offline scan UNC sectors  : 100  100  0
Att # 199 : Ultra ATA CRC Error Rate  : 200    1  868
Att # 200 : Write error rate          : 100  253  0  
Att # 202 : Unknown                   : 100  253  0  
--------------------------------------------------------

Обратите внимание на атрибут # 199...
-- Ultra ATA CRC Error Rate  : 200    1  868 --
Он полностью "завален", хотя остальные атрибуты в норме. Почему так происходит ?

... Атрибут "Ultra ATA CRC Error Rate", учитывает частоту появления ошибок
в контрольных суммах блоков данных, посылаемых для записи на диск, в DMA-режимах.

... При использовании DMA-режимов, программа, сначала высчитывает контрольную сумму
посылаемого блока данных, а потом, отправляет данные и контрольную сумму HDD.
HDD принимает блок данных, подсчитывает его контрольную сумму и сравнивает
ее с контрольной суммой, посланной программой.
Если обе суммы равны, значит блок данных принят без ошибок и его можно записывать на диск.
Если контрольные суммы не равны, значит блок данных содержит ошибки.
HDD фиксирует это событие изменением SMART-атрибута "Ultra ATA CRC Error Rate",
поднимает флаг ERROR в регистре статуса и отправляет в регистр ошибки код "UNC".
Обнаружив ошибку, программы должна несколько раз послать этот-же блок данных
и, если ошибки часто повторяются, изменить DMA-режим, на более низкую скорость.
Однако на практике, никто не изменяет DMA-режим из-за частого искажения данных,
что и приводит к постоянному именению атрибута "Ultra ATA CRC Error Rate".
... По сути, программа (операционная система), должна сначала произвести тестирование
IDE-шины (кабеля), на предмет корректного приема-передачи данных и установить
номинально-приемлемый DMA-режим, по аналогии настройки скорости в модемах,
независимо от того, что HDD поддерживает более быстрый режим.
Так, во всяком случае, было задумано...

... К искажению посылаемых данных, в данном случае, приводит наличее электрических
помех на IDE-шине (компьютер не заземлен) и заниженное питание HDD.
При заниженном или завышенном напряжениях питающих HDD, изменяется напряжения уровней
сигналов на внутренних шинах HDD и порогов срабатывания его логических устройств.
Электрические помехи, приводят к общему подъему уровней сигналов (фон), а пониженное
питание HDD, к снижению порога "чувствительности" логической "1" (физический "0"),
так-как, развязывающие резисторы шин, "подтянуты" к логическому "0" (физическая "1").
В такой ситуации, во время появления очередного (даже не сильного) импульса помехи,
напряжение сигнала логической "1" (физический "0"), будет выше порога срабатывания
логических устройств HDD и будет принята за логический "0" (физическая "1").
Проще говоря, появляется несоглассованность порогов срабатывания логических элементов,
как в случае сопряжения 3.3V и 5V логики.

... Другие атрибуты данного SMART-отчета остались в норме.
Это говорит о том, что рассогласование порогов, наблядается только на входе
и не затрагивает внутренние шины HDD-контроллера.
Хотя напряжение питания и заниженно, но все-же, нет большого "перекоса" напряжений
(например: 12.7V-4,4V или 11.2V-5,5V), которое, привело бы уже, к внутреннему
рассоглассованию порогов срабатывания логических элементов и повлекло за собой
более сущесвенные ошибки, такие как:

Att #   1 : Read error rate
Att #   5 : Reallocated sectors count
Att #   7 : Seek error rate
Att # 195 : Hardware ECC recovered
Att # 197 : Current pending sectors
Att # 198 : Offline scan UNC sectors
Att # 200 : Write error rate

Такое, часто наблюдается в тех моделях HDD, у которых, питание отдельных микросхем контроллера
и создание опорных напряжений, производится от различных источников питания (5V и 12V).
В таких моделях, даже небольшой "перекос" напряжений, может приводить к множеству ошибок.

... Самое опасное (для HDD), в искаженых данных, это изменение посылаемых HDD-контроллеру
команд и изменение считываемых из регистров HDD значений кодов состояния.
________________________________________________________________________________

Некоторое отступление...

... Контроллер HDD, работает под управлением собственной программы (Firmware).
Программа эта очень сложна, имеет множество оверлеев, подпрограмм, таблиц и данных,
и правильнее было-бы называть ее, не иначе как, "Сервисная Операционная Система Диска".
Эта система, имеет свои собственные аналоги FAT-таблиц (ZoneMap, Translator...),
кластеры, разделы (zone), директории (dir, sptdir), большой набор утилит и тестов
(format, erase, testgain, pesscan, SMART-utils...) и даже вторую, тестовую (скановую) OS.

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

... Порты IDE (1x0h-1x7h, 3x6h-3x7h), это не порты HDD, а порты самого IDE-контроллера.
Вот адреса портов HDD-контроллера 08h-0Fh (IDE=1x0h-1x7h) и 16h-17h (IDE=3x6h-3x7h),
а если еще вернее, то имеется 2 шлюза с адресами 00h-07h (IDE=1x0h-1x7h) и 06h-07h (IDE=3x6h-3x7h).

... Если мы работаем с портами IDE "напрямую", это совсем не значит, что мы
работаем с диском на "физическом" уровне. Мы только передаем команды IDE-контроллеру,
который, в свою очередь, пересылает их HDD-контроллеру (Сервисной Операционной Системе Диска).
Работать "напрямую" с внутренними регистрами HDD-контроллера (например GainControl),
и иметь доступ к реальными, физическими секторам и головкам, возможно только посредством
команд производителя (Vendor Command Set). Ни одна из команд, описанная в ATA-стандарте
и доступная пользователю, не имеет таких возможностей.

... Из этого следует, что, для того что-бы работать с HDD на физическом уровне
(хотя-бы с целью физическогой адресации секторов и головок), необходимо, как минимум,
знать команды производителя, их назначение, различные структуры файловой системы
сервисной области (Service Area) и их организацию.

... А если есть желание, попробовать реализовать "регенерацию" магнитного слоя диска,
то, уже дополнительно, нужно знать, адреса, команды и назначения внутренних,
управляющих регистров электронных фильтров, усилителей головок чтения-записи,
много других тонкостей и еще..., иметь пол-пяди во лбу, для того, что-бы,
отчетливо понять, всю бессмысленность этой затеи. :)
________________________________________________________________________________
2: Данные, появляющиеся при переходных процессах, во время (ре)инициализации
   IDE и HDD-контроллеров а так-же, при неучтенных (несогласованных) состояниях
   HDD-контроллера, во время исполнения им внутренних операций (Фантомы).
--------------------------------------------------------------------------------

... Как-бы не старались составители ATA-стандарта и производители ATA/ATAPI-устройств,
но учесть все ньюансы и состояния устройств в различных ситуациях, они не смогут.
К тому-же, ньюансов добавляют и производители различных ATA/ATAPI-контроллеров,
о которых в ATA-стандарте и не упоминается.
Мало того, что в Firmware могут быть невыявленные ошибки, так еще и ATA-стандарт
иногда рекомендует противоречивые правила.
... С одной стороны, ATA-стандарт требует, не делать никаких SMART-записей после
команды SMART-OFF, с другой стороны, отдает часть атрибутов вендору, для записи
их собственных значений и логов, которые записываются постоянно и без которых,
Firmware просто нельзя обойтись. Такое-же творится и с командами.
... ATA-стандарт не запрещает использование контекста "Task File" описанных им команд,
для использования в других целях и некоторые производители используют их для своих нужд.
Например: SMART-команды "Read Log" и "Write Log", некоторыми производителями,
используются для чтения и записи модулей в системной (SA) области диска и Flash !!!
... Конечно-же, это делается только после подачи вендор-команды, переводящей HDD
в сервисный режим, однако известно, что HDD самостоятельно может переходить в этот режим
в случае невозможности считывания некоторых модулей из SA, а это, может произойти
даже при банальном скачке напряжения, во время инициализации диска.
В этом режиме, при идентификации, HDD может вести себя как обычно, "отдавая"
паспортные данные. BIOS, OS и программы, пытаются считывать и записывать SMART-логи !!!.
Что и куда будет записано при этом, знает только господь.
Недаром, многие ремонтники HDD, частенько обнаруживают "мусор" в модулях и во Flash.
... Рассмотрим тот-же Sleep-режим.
ATA-стандарт требует снять флаг BUSY, после успешного входа в Sleep-режим,
но как это сделать, если Sleep-режим, подразумевает остановку синхронизации
всех внутренних блоков CPU (MPU) HDD-контроллера (т.е. CPU уже не работает)?
Поэтому, сначала приходится снимать флаг BUSY, а потом уже, идти "спать",
либо, вообще не входить Sleep-режим, а только, остановить мотор и притвориться спящим.
... При вхождении в Sleep-режим, во всех регистрах HDD, появляются,
хаотичные значения, относительно-плавно, переходящие в "0".
Если программа, в этот момент будет опрашивать регистр статуса, то в результате,
может получить какой угодно код и принять его значение, за истинное состояние HDD.
Такие-же выбросы, происходят при изменении режимов работы самого IDE-контроллера.
...Но и конечное значение "00" как в Sleep-режиме, приносит немало неудобств, так-как,
ни один из флагов ошибки и BUSY не включен, а DRDY и DSC, обычно не проверяются.

Вот небольшой пример работы известной программы GHOSTPE (программировано профессионалами):
[преимущество метода "табличного" распознования флагов, здесь очевидны].
К IDE-каналу, подключен только один HDD как "Master".
--------------------------------------------------------------------------------
     LOGS-DECODER For IDEGrabb16(ALL) Log-Files V3.1

___________________Logs_Signs_History_____________________
  _   = Read From Register               Examle: 1X5_8A
  =   = Write To Register                Examle: 1X7=EC
  <<  = Single Read From 1X0 Register    Examle: <<7A42
  >>  = Single Write To 1X0 Register     Examle: >>AA55
  #x: = Maximal ATA-Standard Number For The Met Command
__________________________________________________________
 (C)NazYura 2006 Krasnodar <> EMail: NazYura(C)Rambler.ru

 Start GHOSTPE.EXE
===================

1x7_50 - HDD уже находится в состоянии готовности
1x6_A0 - HDD является "мастером" (после этого, нужно делать проверку "Everybody home ?" (см. ниже))
1x6=A0 - Выбирается "Master" (лишнее)
1x7_50 - HDD находится в состоянии готовности
1x6_A0 - HDD является "мастером" (лишнее)
1x7_50 - HDD находится в состоянии готовности (лишнее)

1x7=EC - Посылается команда

 Command: ATA-#6: IDENTIFY DEVICE

1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3131   ....DWW-AC9J9111
3437 2038 2020 2020 0000 0040 3A00 3331   47 8    ...@:.31
302E 4733 3331 4457 2043 4457 3038 4A30   0.G331DW CDW08J0
2D42 3030 4D46 3041 2020 2020 2020 2020   -B00MF0A        
2020 2020 2020 2020 2020 2020 2020 1080                 Ђ
....____________cutting____________....

1x7_50 - HDD находится в состоянии готовности
1x7_50 - HDD находится в состоянии готовности
1x6_A0 - HDD является "мастером" (лишнее)
1x6=B0 - Выбирается "Slave", на предмет наличия HDD-Slave
1x7_00 \_ HDD-Slave отсутствует, но ни один флаг не включен и DRDY не проверяется...
1x7_00 /  (здесь нужно было делать проверку "Everybody home ?" (см. ниже))
1x6_B0 - Повторно выбирается "Slave", на предмет наличия HDD-Slave
1x7_00 \
1x7_00  |
1x7_00  |
1x7_00  | HDD-Slave отсутствует, но ни один флаг не включен и DRDY не проверяется...
1x7_00  | (Подвисший HDD, то-же может выдавать "00")
1x7_00  |
1x7_00 /

1x7=EC - Подается команда, хотя HDD, либо отсутствует, либо занят "внутренними операциями" (см. ниже) !!!

 Command: ATA-#6: IDENTIFY DEVICE

1x7_00 \ 
1x7_00  |
1x7_00  | HDD-Slave отсутствует, но ни один флаг не включен и DRDY не проверяется...
1x7_00  | (Подвисший HDD, то-же может выдавать "00")
1x7_00  |
1x7_00  |
1x7_00  |
1x4_00  > - "1x4_00" = 3400h - то-же фантом (слава господу, что не 3740h/3750 - "DRDY/DRDY+DSC"...)
1x7_00 /
1x6_B0 - Опять выбирается "Slave", на предмет наличия HDD-Slave...

1x6=A0 - Заново выбирается "Master" (наконец-то поняли что со "Slave", что-то не так...)
1x7_50 - HDD находится в состоянии готовности
1x6_A0 - HDD является "мастером"

1x3=A5 \  Тест "Вопрос-Ответ" (Eeverybody home ?), для проверки приема-ответа HDD и обрыва кабеля.
1x3_A5  | Посылается теcтовый паттерн A5h [10100101] и тут-же считывается. Если "вопрос" и "ответ" равны, то все OK!
1x3_A5  | Тест выполнен неправильно !!! Оба раза, посылается один и тот-же паттерн A5h [10100101] !!!
1x3=A5  | Проверены не все биты !!! Во второй раз, в данном случае, нужно было посылать 5Ah [01011010].
1x3_A5 /  Этот тест должен осуществлятся при выборе HDD и после возникновения фатальных ошибок.

Вот один из примеров правильного теста "Eeverybody home ?":
________________________________________________________________________________
 START DLG-DIAG (UDMA)
=======================
1x6=E0 - Выбирается "Мастер" и Включается флаг LBA  [...хотя еще неизвестен MAX-LBA] :)
1x7_50 - HDD находится в состоянии готовности
1x2_3F 1x3_01 - Считывается  и сохраняется в памяти компьютера, предыдущее значение тестовых регистров
1x2=00 1x3=00 - Все биты тестовых регистров очищаются
1x2=FF 1x3=FF - Все биты тестовых регистров устанавливаются в "1"
1x2=A5 1x3=5A - Записываются разные паттерны в 2 регистра, [10100101] и [01011010]
1x2_A5 1x3_5A - Считываются значения тестовых регистров (считанное, равно записанному - все OK!)
1x2=3F 1x3=01 - Восстанавливаются предыдущее значение тестовых регистров
3x6=06 - DevCtrl \_ "Reset" - А это уже лишнее... :)
3x6=02 - DevCtrl /  Зачем-же тогда, нужно было восстанавливать предыдущее значение регистров ?
3x6_80 - Busy
3x6_80 - Busy
3x6_50
3x6_50 - Ready
1x6=A0 - Выбирается "Мастер" и ВЫключается флаг LBA [...так зачем тогда включали ?] :)
3x6_50
1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE - Читается паспорт диска
....____________cutting____________....
________________________________________________________________________________

продолжение...
3x6=08 - DevCtrl
1x6=E0 - Включается флаг LBA...
1x7_50
1x6=E0 - Опять включается флаг LBA
1x7_50
1x7_50
1x1=00 1x2=01 1x3=01 1x4=00 1x5=00 1x6=E0
1x7_50 - HDD находится в состоянии готовности
1x7=C4 - Посылается команда

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
33C0 8ED0 BC00 7CFB 5007 501F FCBE 1B7C   3АЋРј.|ыPPьѕ|
BF1B 0650 57B9 E501 F3A4 CBBE BE07 B104   їPW№еу¤Лѕѕ±
382C 7C09 7515 83C6 10E2 F5CD 188B 148B   8,|.uѓЖвхН‹‹
EE83 C610 4974 1638 2C74 F6BE 1007 4EAC   оѓЖIt8,tцѕN¬
....____________cutting____________....

________________________________________________________________________________
"Внутренние операции".
________________________________________________________________________________

... "Внутренние операции" HDD-контроллера, это не что иное,
как подпрограммы и функции управления отдельными узлами HDD,
которые имеют, предопределенные "Firmware" и "Hardware" циклы повторений,
из которых нет "выхода" по внешнему прерыванию, до полного окончания цикла,
или, до срабатывания watchdog-таймера по тайм-ауту.
Таких микро-операций очень много и НЕ ВСЕ они контроллируются watchdog-таймером.

... Обобщенный пример операции: Подана команда "Write Sector".
MPU HDD-контроллера, посылает в VCM (VoiceCoilMotor) адрес необходимого сектора
и команду "Seek". VCM начинает установку на трек, включающий нужный сектор,
но серводекодер, не может сраэу обнаружить идентификатор нужного трека.
Вот здесь то и включается 1-я циклическая операция по настройке головок чтения,
то-есть, начинается цикл дискретного увеличения-уменьшения, значения регистра
"HeadGainControl" до определенного значения, с попыткой чтения ID-трека,
после каждого изменения этого значения. После завершения этого цикла, по такому-же
принципу, начинается цикл настройки электронного фильтра (GainFilterControl)
дифференциального сигнала, поступающего с усилителя головок и после каждого
изменения значения "GainFilterControl", происходит переход на 1-й цикл.
То-есть, 1-й цикл, превращается во вложенный цикл 2-го...
А ведь есть еще и цикл термо-рекалибровки головок и несколько, разных по глубине,
циклов коррекции ECC, включенных в эту-же задачу...
Пока циклы такой операции не будут закончены или-же не поступит сигнал watchdog-таймера,
HDD-контроллер не сможет реагировать на поступающие с интерфейса запросы.

... Многие наверняка сталкивались с долгим "клацанием" HDD с поднятым флагом "BUSY",
когда даже "ресет" не помогает. Это и есть "Внутренние операции" HDD-контроллера.
... Но все-же, когда регистр статуса сообщает о "BUSY", это помогает программе
определить дальнейший путь действий, а что делать, если не сообщает ?...
... Такое, к примеру, может произойти при наличии сбойного SMART-сектора в SA.
При этой неисправности происходит следующее:
После включении питания PC, HDD инициализируется и пытается записать SMART-данные и логи.
При этом компьтер, обычно очень долго "думает", но потом, все-же продолжает загрузку.
... Если, после этой паузы, опросить регистр статуса, то мы увидем, поднятый флаг ошибки,
хотя дальше, HDD будет нормально работать и выдаст долгий "BUSY" и ошибку, только
тогда, когда из программы, поступит команда чтения или записи SMART-таблицы.
... Однако всем известно, что система SMART, через определенное время бездействия HDD,
может начать OffLine-тестирование диска. При этом, никакие флаги не изменяются.
... Любая, посланная HDD-контроллеру команда, вынудит HDD, прекратить SelfTest,
сохранить состояние текущего теста (номер теста, адрес сектора, кол-во ошибок и.т.д.)
в SMART-логи и только после этого, HDD, отреагирует на поступившую команду.
... На завершение Self-теста, ATA-стандарт выделяет 2 секунды (что то-же немало),
однако в реальности, из-за сбойного SMART-сектора, эта операция займет очень много времени.
При этом, регистры статуса и ошибки, будут возвращать, либо предыдущее (до начала Self-теста)
значение, либо "00" (если идут "Внутренние операции" и IO-модуль ОТКЛЮЧЕН),
либо хаотичные, постоянно изменяющиеся значения (фантомы), поступающие с внутренней
шины данных HDD-контроллера (если идут "Внутренние операции" и IO-модуль ВКЛЮЧЕН).
... В последнем случае - HDD становится мощным "генератором" фантомов, вводя программу в тупик.
Такие-же фантомы, появляются и при изменении режимов самого IDE-конроллера.
Именно поэтому, во многих BIOSах компьютеров была введена опция установки паузы (тайм-аут),
при определении подключенных дисков.

Вот пример загрузки компьютера после включения питания (BIOS-лог):

________________________________________________________________________________

     LOGS-DECODER For IDEGrabb16(ALL) Log-Files V3.1

___________________Logs_Signs_History_____________________
  _   = Read From Register               Examle: 1X5_8A
  =   = Write To Register                Examle: 1X7=EC
  <<  = Single Read From 1X0 Register    Examle: <<7A42
  >>  = Single Write To 1X0 Register     Examle: >>AA55
  #x: = Maximal ATA-Standard Number For The Met Command
__________________________________________________________
 (C)NazYura 2006 Krasnodar <> EMail: NazYura(C)Rambler.ru

**********************************************************
    Decoding IDEGrabb16ALL Log-File --> 16ALL000.GRB
**********************************************************

 Power ON Computer
===================
----------------------- Начало генерации фантомов ------------------------------

1x5_13    Через 3-4 секунды, после включения питания компьютера,
1x7_50    на IDE-шине появляются фантомы (каждый раз - разные),
1x7_00    часть из которых, HDD принимает как различные команды...
1x7_50
1x6=00
1x7_A1
1x7_00
1x6=00
1x6_30
1x6=00
1x7_00
1x7_B0
1x6=50
1x6=51
1x7_20
1x7_51
1x6=51
1x6=51
1x6=58

[****** Host READ Data From HDD ******]
0043 0031 3030 2080 FFFC 0300 0000 C000   .C.100 Ђяь...А.
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 250C                            ....%

1x2_05
1x7_50
1x7_00
1x7_50
1x6_30
1x7_30
1x7_B0
1x6=00
1x7_00
1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE

1x7_A1
1x7_51
1x7_51
1x7_51
1x6=51
1x6=51
1x7_20
1x6=58
1x7_58

[****** Host READ Data From HDD ******]
5731 2030 1000 7800 0100 0000 0000 0000   W1 0.x........
0000 0000 0000 0000 0000 0000 0000 0000   ................
00FC                                      .ь

1x7_50
1x6_20
1x7_50
1x2=00
1x7_50
1x7_50
1x7_50
1x1=FF
1x6=AF
1x7_50
1x7_50
1x7_50
1x4=00
1x7_50
1x6=A0
1x3=00
1x7_50
1x7_50
1x7_50
1x7_50
1x7_50
1x7_50
1x7_50
1x7=B0

 Command: ATA-#6: SMART OPERATIONS

1x7_50
1x7_50
1x7_50
1x7_50
1x7_50
1x7_50
1x7_50
1x4=00
1x7_50
1x7_58

[****** Host READ Data From HDD ******]
0000 0000 0000 0000 0000 0000 0000 0000   ................
0000 0000 0000 0000 0000                  ..........
----------------------- Конец генерации фантомов -------------------------------

---------------------- Далее, все идет нормально -------------------------------

1x7_50
1x6=A0 1x1=03 1x2=0C
1x7_50
1x7=EF

 Command: ATA-#6: SET FEATURES  (Установка режима PIO-4) Проверка поддержки режима ?

1x7_D0
1x7_50
1x2=42
1x7_50
1x7=EF

 Command: ATA-#6: SET FEATURES   (Установка режима Ultra DMA-2 mode) Проверка поддержки режима ?

1x7_D0
1x7_50
1x1=03 1x6=E0
1x7_50
1x6=A0
1x7_50
1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7_50
1x7=10

 Command: ATA-#3: Recalibrate

1x7_50
1x6=AF 1x7_50
1x7_50
1x1=00 1x2=3F 1x3=00 1x4=00 1x5=00 1x6=AF 1x7_50
1x7=91

 Command: ATA-#5: Initialize drive parameters

1x7_D0
1x7_50
1x6=EC 1x7_50
1x7_50
1x1=00 1x2=10 1x3=00 1x4=00 1x5=00 1x6=EC 1x7_50
1x7=C6

 Command: ATA-#6: SET MULTIPLE MODE

1x7_50
1x4=AA 1x4_AA
1x2=00 1x6=A0 1x7_50
1x7=E3

 Command: ATA-#6: IDLE

1x7_D0
1x7_50
1x6=E0 1x7_50
1x6=A0 1x7_50
1x7_50
1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7_50
1x7=10

 Command: ATA-#3: Recalibrate

1x7_50
1x6=AF 1x7_50
1x7_50
1x1=00 1x2=3F 1x3=00 1x4=00 1x5=00 1x6=AF 1x7_50
1x7=91

 Command: ATA-#5: Initialize drive parameters

1x7_D0
1x7_50
1x6=E0 1x7_50
1x7_50
1x1=00 1x2=10 1x3=00 1x4=00 1x5=00 1x6=E0 1x7_50
1x7=C6

 Command: ATA-#6: SET MULTIPLE MODE

1x7_50
1x7_50
3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7_50
1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3131   ....DWW-AC9J9111
3437 2038 2020 2020 0000 0040 3A00 3331   47 8    ...@:.31
302E 4733 3331 4457 2043 4457 3038 4A30   0.G331DW CDW08J0
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7_50
1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3131   ....DWW-AC9J9111
3437 2038 2020 2020 0000 0040 3A00 3331   47 8    ...@:.31
302E 4733 3331 4457 2043 4457 3038 4A30   0.G331DW CDW08J0
....____________cutting____________....

3x6=08 - DevCtrl
1x6=E0 1x7_50
1x6=E0 1x7_50
1x7_50
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7_50
1x7=C4

 Command: ATA-#6: READ MULTIPLE

1x7_58
1x7_58

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3131   ....DWW-AC9J9111
3437 2038 2020 2020 0000 0040 3A00 3331   47 8    ...@:.31
302E 4733 3331 4457 2043 4457 3038 4A30   0.G331DW CDW08J0
....____________cutting____________....
.......
......
.....
....
...
..
.

 done
======

           *** Done Files Decoding ***
________________________________________________________________________________

... Я думаю, что, неожиданная (без объяснимых причин) потеря информации или порча FAT-таблицы,
после перезагрузки или включения питания компьютера, в некоторых случаях, вызвана именно фантомами.
... Неплохой защитой от таких фантомов, может служить новая возможность SATA-HDD (как у SCSI),
позволяющая включать питание HDD только по сигналу управляющей OS или программы.
Но защищать программу от них, должен сам программист...

... Вот один из способов, отсечки фантомов в программе.
Так-как фантомы хаотичны, то их значения, повторяются не часто, то-есть, возножность
появления двух одинаковых фантомов подряд, очень редка, поэтому можно поставить заслон
из простого, программного фильтра:

Пример: "Phantoms Filter"
(можно вставить в процедуру CHECK_STATUS ("Табличный метод распознования флагов"))

--------------------------------------------------------------------------------
CHECK_STATUS    PROC    NEAR
		PUSH    BX
		PUSH    DX

		LEA     BX,MASK_STATUS		;Load Mask Table For Status Register
		MOV     DX,STATUS_REG

LOOP_IN:
;------------------------ Phantoms Filter --------------------------------------
		IN      AL,DX           ;Read Status Value
		MOV     AH,AL           ;Store Value To AH
		JMP     $+2             ;Pause
		JMP     $+2             ;Pause
		IN      AL,DX           ;Read Status Value Again
		CMP     AH,AL           ;Compare Old & New Values (If [Old]=[New] This Is Not Phantom)
		JNE     LOOP_IN         ;If This Is Phantom - Jmp Read Status
;-------------------------------------------------------------------------------

		XLAT                    ;Decoding Input Value
		CMP     AL,'B'          ;Check For BUSY
		JNE     EXIT_STATUS     ;Exit If Not BUSY
		CALL    PAUSE           ;Wait Some Time (Return = [AL = "T" If TimeOut Expired] (TimeOut=Pause*x))
		CMP     AL,'T'          ;TimeOut Expired ?
		JNE     LOOP_IN

EXIT_STATUS:
...

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

... Правда, версия программы HDDL, у меня не последняя и наверняка, в более поздних
выпусках, этих ошибок уже не существует, но как пример по поиску "багов",
данные логи, показывают, насколько сильны, преимущества сканера при поиске ошибок,
перед любыми, программными отладчиками.

... И так, HDDL, на ладони у IDEGRABB16(ALL).
--------------------------------------------------------------------------------

 HDLL.EXE V3.1  PASSPORT READ
==============================
1x6=A0 1x6=A0 - Выбирается "Master"

1x2=55 1x2_55 \
1x2=AA 1x2_AA  | Двойной тест "Everybody home ?"
1x3=55 1x3_55  |
1x3=AA 1x3_AA /

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE  - Читается паспорт диска

1x7_58
1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3132   ....DWW-AC9J9112
....____________cutting____________....

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE  - Читается паспорт диска

1x7_58
1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3132   ....DWW-AC9J9112
....____________cutting____________....

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE  - Читается паспорт диска

1x7_58
1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3132   ....DWW-AC9J9112
....____________cutting____________....

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=F8

 Command: ATA-#6: READ NATIVE MAX ADDRESS

1x3_AF\
1x4_F8 | Считывается максимальный адрес LBA (E950F8AFh)
1x5_50 |
1x6_E9/

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE  - Читается паспорт диска

1x7_58
1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3132   ....DWW-AC9J9112
....____________cutting____________....
--------------------------------------------------------------------------------
Такая вот странная, конструкция чтения паспорта, назовем ее пока "многоэтажный паспорт".
Ошибок здесь нет, но видны явные излишества, хотя в других операциях программы,
применяется "одноэтажный" метод чтения паспорта (может быть это "остатки от отладки" ?).
--------------------------------------------------------------------------------
продолжение...
 SPIN DOWN
===========
1x6=A0 1x6=A0 - Выбирается "Master"

1x2=55 1x2_55 \
1x2=AA 1x2_AA  | Двойной тест "Everybody home ?"
1x3=55 1x3_55  |
1x3=AA 1x3_AA /

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=E0
 Command: ATA-#6: STANDBY IMMEDIATE
--------------------------------------------------------------------------------
... Подробнее о тесте "Everybody home ?".

... Когда мы записываем какие нибудь значения в регистры 1x1h-1x6h (TaskFile) исправного
ATA/ATAPI-устройства, подключенного к исправному IDE-контроллеру посредством,
исправного интерфейсного кабеля, то они запоминаются в электронных регистрах-защелках,
IO-модуля устройства, и могут быть считаны в любой момент, в неизменном виде, до записи
какой либо команды в командные регистры 1x7h, 3x6h (иначе, эти значения, могут измениться).
... Если считывая эти-же регистры, мы получили то-же, что в них записывали, то это значит,
что, IDE-контроллер правильно передал данные на интерфейсный кабель, по интерфейсному кабелю
данные прошли без потерь и ATA/ATAPI-устройство, приняло, сохранило и передало данные,
так-же без потерь. То-есть, можно предположить, что IDE-контроллер и интерфейсная часть
ATA/ATAPI-устройства исправны. Что-же касается IDE-кабеля, то такой тест позволяет
проверить только половину (младшую) адресной шины (8 проводников), так-как,
в тесте, используются только 8ми-разрядные регистры.
... Поэтому, к такому тесту, желательно добавить тест буфера HDD, который, позволит полностью
проверить не только кабель, но и работу конроллера памяти HDD.
... Вот так, мог бы выглядеть, расширенный тест "Everybody home ?".
--------------------------------------------------------------------------------
1x6=A0 1x6=A0 - Выбирается "Master"

1x2=55 1x2_55 \
1x2=AA 1x2_AA  | Двойной тест "Everybody home ?"
1x3=55 1x3_55  |
1x3=AA 1x3_AA /

1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=E8
 Command: ATA-#6: WRITE BUFFER
1x7_D0
1x7_58
[****** Host WRITE Data To HDD *******] - Записываем паттерн 5555h [0101010101010101] 16 бит.
5555 5555 5555 5555 5555 5555 5555 5555   UUUUUUUUUUUUUUUU
....____________cutting____________....

1x1_00
1x7_50
1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=E4
 Command: ATA-#6: READ BUFFER
1x7_D0
1x7_58
[****** Host READ Data From HDD ******] - Считываем и сравниваем...
5555 5555 5555 5555 5555 5555 5555 5555   UUUUUUUUUUUUUUUU
....____________cutting____________....

1x1_00
1x7_50
1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=E8
 Command: ATA-#6: WRITE BUFFER
1x7_D0
1x7_58
[****** Host WRITE Data To HDD *******] - Записываем паттерн AAAAh [1010101010101010] 16 бит.
AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA   кккккккккккккккк
....____________cutting____________....

1x1_00
1x7_50
1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=E4
 Command: ATA-#6: READ BUFFER
1x7_D0
1x7_58
[****** Host READ Data From HDD ******] - Считываем и сравниваем...
AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA   кккккккккккккккк
....____________cutting____________....
1x1_00
1x7_50
--------------------------------------------------------------------------------
продолжение...
 SOFT RESET
============
3x6=0C  -- DevCtrl \_ Soft Reset в HDDL используется "экономно", только в "ручном" режиме,
3x6=08  -- DevCtrl /  и нигде в программе, больше не применяется (в логах не встречалось).
--------------------------------------------------------------------------------
... В целом, программа написана на высоком проффесиональном уровне,
поэтому я пропускаю все безошибочные операции.
--------------------------------------------------------------------------------
А вот и засада...

Во вкладке [Тест позиционирования], есть тест позиционирования с неразрушающей записью.
Я и раньше им пользовался, но обычно, на тестируемых дисках, не было информации
и поэтому, я не мог заметить неладное...

... Логика теста сектора, такова:
1: Сектор проверяется на ошибку
2: Содержимое сектора, считывается в буфер временного хранения
3: Сектор записывается определенным тестовым патерном
4: Сектор считывается с проверкой тестового патерна
5: Восстанавливается содержимое сектора, из буфера временного хранения
--------------------------------------------------------------------------------
 Seek Tests: Not Destroying Recording
======================================
1x6=A0 1x6=A0 - Выбирается "Master"             

1x2=55 1x2_55 \
1x2=AA 1x2_AA  | Двойной тест "Everybody home ?"
1x3=55 1x3_55  |
1x3=AA 1x3_AA /

1x7_50 - HDD в состоянии готовности (ошибок нет)

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=A0 1x7=EC

 Command: ATA-#6: IDENTIFY DEVICE  - Читается паспорт диска

1x7_58 - HDD готов к обмену данными и программа их считывает...

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3131   ....DWW-AC9J9111
3437 2038 2020 2020 0000 0040 3A00 3331   47 8    ...@:.31
302E 4733 3331 4457 2043 4457 3038 4A30   0.G331DW CDW08J0
2D42 3030 4D46 3041 2020 2020 2020 2020   -B00MF0A        
....____________cutting____________....

1x7_50 - HDD в состоянии готовности (ошибок нет)
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=40

 Command: ATA-#6: READ VERIFY SECTOR(S) #123:(w/retry) - Сектор проверяется на ошику

1x7_50 - HDD в состоянии готовности (ошибок нет)
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=20

 Command: ATA-#6: READ SECTOR(S) #12:(w/retry) - Сектор считывается в буфер хранения программы

1x7_58 - HDD готов к обмену данными и программа их считывает... (считывает верно)

[****** Host READ Data From HDD ******]
0000 0000 EBEB EBEB EBEB EBEB EBEB EBEB   ....лллллллллллл
2A20 4844 444C 202A 00EB EBEB EBEB EBEB   * HDDL *.ллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл

1x7_50 - HDD в состоянии готовности (ошибок нет)
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=30

 Command: ATA-#6: WRITE SECTOR(S) #12:(w/retry) - Сектор прописывается патерном Magic Word :)
                                                  В первых 4-х байтах - номер LBA (Sector Number)
1x7_58 - HDD готов к обмену данными и программа их записывает... (записывает верно)

[****** Host WRITE Data To HDD *******]
0000 0000 4675 636B 4675 636B 4675 636B   ....FuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck

1x7_50 - HDD в состоянии готовности (ошибок нет)
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=20

 Command: ATA-#6: READ SECTOR(S) #12:(w/retry)
1x7_58 - HDD готов к обмену данными и программа их считывает... (считывает верно)

[****** Host READ Data From HDD ******]
0000 0000 4675 636B 4675 636B 4675 636B   ....FuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck
4675 636B 4675 636B 4675 636B 4675 636B   FuckFuckFuckFuck

1x7_50 - HDD в состоянии готовности (ошибок нет)
1x1=00 1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=30

 Command: ATA-#6: WRITE SECTOR(S) #12:(w/retry)
1x7_58 - HDD готов к обмену данными и программа их записывает... (!!! ОШИБКА !!!)

[****** Host WRITE Data To HDD *******]
0074 0000 EB74 EB58 EB06 EB00 EB00 EB74   .t..лtлXлл.л.лt
2A58 4806 4400 20EB 0000 EB74 EB58 EB06   *XHD. л..лtлXл
EB00 EBEB EB00 EB74 EB58 EB06 EBEB EB00   л.ллл.лtлXлллл.
EB74 EB58 EB06 EBEB EBEB EB00 EB74 EB58   лtлXлллллл.лtлX
EB06 EBEB EBEB EB00 EB74 EB58 EBEB EBEB   лллллл.лtлXлллл
EB00 EB74 EB58 EBEB EBEB EBEB EB00 EB74   л.лtлXллллллл.лt
EB58 EBEB EBEB EBEB EB00 EB74 EBEB EBEB   лXллллллл.лtлллл
EBEB EB00 EB74 EBEB EBEB EBEB EBEB EB00   ллл.лtллллллллл.
EB74 EBEB EBEB EBEB EBEB EB00 EB74 EBEB   лtллллллллл.лtлл
EBEB EBEB EBEB EB00 EB74 EBEB EBEB EBEB   ллллллл.лtлллллл
EBEB EB00 EB74 EBEB EBEB EBEB EBEB EB00   ллл.лtллллллллл.
EB74 EBEB EBEB EBEB EBEB EB00 EB74 EBEB   лtллллллллл.лtлл
EBEB EBEB EBEB EB00 EB74 EBEB EBEB EBEB   ллллллл.лtлллллл
EB00 EB74 EBEB EBEB EBEB EBEB EB00 EB74   л.лtллллллллл.лt
EBEB EBEB EBEB EBEB EB00 EB74 EBEB EBEB   ллллллллл.лtлллл
EBEB EBEB EB00 EB74 EBEB EBEB EBEB EBEB   ллллл.лtлллллллл
EB00 EB74 EBEB EBEB EBEB EBEB EB74 EBEB   л.лtлллллллллtлл
EBEB EBEB EBEB EBEB EB74 EBEB EBEB EBEB   лллллллллtлллллл
EBEB EBEB EB74 EBEB EBEB EBEB EBEB EBEB   лллллtлллллллллл
EB74 EBEB EBEB EBEB EBEB EBEB EB74 EBEB   лtлллллллллллtлл
EBEB EBEB EBEB EBEB EB74 EBEB EBEB EBEB   лллллллллtлллллл
EBEB EBEB EB74 EBEB EBEB EBEB EBEB EBEB   лллллtлллллллллл
EB74 EBEB EBEB EBEB EBEB EBEB EB74 EBEB   лtлллллллллллtлл
EBEB EBEB EBEB EBEB EB74 EBEB EBEB EBEB   лллллллллtлллллл
EBEB EBEB EB74 EBEB EBEB EBEB EBEB EBEB   лллллtлллллллллл
EB74 EBEB EBEB EBEB EBEB EBEB EB74 EBEB   лtлллллллллллtлл
EBEB EBEB EBEB EBEB EB74 EBEB EBEB EBEB   лллллллллtлллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл
EBEB EBEB EBEB EBEB EBEB EBEB EBEB EBEB   лллллллллллллллл

1x7_50 - HDD в состоянии готовности (ошибок нет)
--------------------------------------------------------------------------------
... Как видно из лога, все операции, кроме последней, проходят правильно.
По какой-то причине, данные содержимого сектора, считанные в буфер временного хранения,
посылаются на диск с ошибкой в каждом втором байте и имеют даже некоторую кратную структуру !!!
Искажению, может быть подвергнута как часть буфера (в данном примере, конец сектора верен),
так и полностью весь буфер (с ошибкой в каждом втором байте).
... Можно предположить что, буфер хранения портится стэком (хотя довольно странно портится)
или его адрес, используется в других операциях, или...
... Как-бы то ни было, а данные диска, теряются, безвозвратно.
--------------------------------------------------------------------------------
... В тестах [Запись секторов], [Тест позиционирования] и [График скорости доступа],
обнаружена еще одна, общая для всех этих тестов, ошибка.

... При исполнении этих тестов, проверяется (по всей видимости) только флаг BUSY,
поэтому, когда сектора читаются с ошибкой (51h [01010001] DRDY+DSC+ERROR),
программа этого "не замечает" и продолжает тестировать следующий сектор.

Вот лог Теста позиционирования, в линейном режиме с верификацией секторов.

--------------------------------------------------------------------------------
 Test Positioning --> Mode: Linear + Verification
==================================================
1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=40 - Читается 0-й блок секторов
 Command: ATA-#6: READ VERIFY SECTOR(S) #123:(w/retry)
1x7_D0 (BUSY+DRDY+DSC)
1x7_D1 (BUSY+DRDY+DSC+ERROR)
1x7_51 - Команда завершилась ошибкой (51h [01010001] DRDY+DSC+ERROR)

1x1=00 1x2=00 1x3=00 1x4=00 1x5=00 1x6=E0 1x7=40 - Повторно читается 0-й блок секторов
 Command: ATA-#6: READ VERIFY SECTOR(S) #123:(w/retry)
1x7_D0 (BUSY+DRDY+DSC)
1x7_D1 (BUSY+DRDY+DSC+ERROR)
1x7_51 - Команда завершилась ошибкой (51h [01010001] DRDY+DSC+ERROR)

1x1=00 1x2=00 1x3=00 1x4=01 1x5=00 1x6=E0 1x7=40 - Читается 1-й блок секторов
 Command: ATA-#6: READ VERIFY SECTOR(S) #123:(w/retry)
1x7_D0 (BUSY+DRDY+DSC)
1x7_D1 (BUSY+DRDY+DSC+ERROR)
1x7_51 - Команда завершилась ошибкой (51h [01010001] DRDY+DSC+ERROR)

1x1=00 1x2=00 1x3=00 1x4=02 1x5=00 1x6=E0 1x7=40 - Читается 2-й блок секторов
 Command: ATA-#6: READ VERIFY SECTOR(S) #123:(w/retry)
1x7_D0 (BUSY+DRDY+DSC)
1x7_D1 (BUSY+DRDY+DSC+ERROR)
1x7_51 - Команда завершилась ошибкой (51h [01010001] DRDY+DSC+ERROR)

1x1=00 1x2=00 1x3=00 1x4=03 1x5=00 1x6=E0 1x7=40 - Читается 3-й блок секторов
 Command: ATA-#6: READ VERIFY SECTOR(S) #123:(w/retry)
1x7_D0 (BUSY+DRDY+DSC)
1x7_D1 (BUSY+DRDY+DSC+ERROR)
1x7_51 - Команда завершилась ошибкой (51h [01010001] DRDY+DSC+ERROR)
....
...
..
.
....____________cutting____________....
--------------------------------------------------------------------------------

А это, снимок, созданный HDDL, после операции [График скорости доступа].
(у данного HDD, запорчены служебные модули и работа с секторами невозможна, но программа "не замечает"
ошибки и рисует симпатичную "кремлевскую" стену, показывая при этом, ошеломляющую скорость).


SCREENSHOT WDC ROM MODEL

И напоследок, пожелания о поддержке LBA-48бит в HDDL...

... При установке в тесте [Верификация секторов], флажка [Режим LBA48], HDDL сообщает,
что "Винт не поддерживает LBA48", а в [Окне регистров], молчит об этом.
... У испытуемого HDD, действительно меньше 268.435.456 секторов и программа,
проанализировав паспорт диска, обнаруживает, что флаг поддержки LBA48 выключен.

... Известно, что, на самом деле, практически все HDD, размером 40GB и более, физически
и программно (на уровне Firmware), полностью поддерживают 48-битовую адресацию.
Просто, в паспорте HDD, размером менее 132Gb, не включен флаг поддержки LBA48 из-за
отсуттсвия реальной необходимости такой адресации и сохранения производительности.
(время адресации регистров в LBA48, как-минимум, в два раза больше, чем в режиме LBA28).
Из двух режимов алресации, производитель выбирает более быстрый режим LBA28.
Однако, в различных тестах и экспериментах с паспортом и конфигурацией, иногда,
возникает необходимость тестирования HDD, именно, в режиме LBA48.
... Хотелось-бы, что-бы, в будущих версиях программы HDDL, имелась такая возможность.

--------------------------------------------------------------------------------
Хочу рассеять устоявшийся миф о том, что персонал, работающий на фирмах производителей
различных устройств, состоит только из "крутых" программистов и всезнающих "гуру".
На самом деле, это очень далеко от истины.

... В головной состав персонала группы разработчиков, входят 10 - 15 программистов
микроконтроллеров, но все они, имеют узкую специализацию и отвечают только
за свои направления, например, такие как: I/O logic, Clocks, Microprocessor Interface,
Serial Interface, ECC, Servo, Spindle и другие.
Никто из них и близко не знает полной работы устройства в целом.
Каждый делает только свое дело.

... Ими руководит элита из 2-4 "гуру", в составе которой входят специалисты
производителей микроконтроллеров, входящих в состав устройства.
Только эта, небольшая група людей и знает досконально весь проект.

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

...
reset()
selectdrv(1)
identify(w,*)
getbuffer(b,512,in_buffer)
cmp (w,*in_buffer+22,'WD')
...
native()
settaskfile(,,scnt,snum,,drv,8Eh)
sendtaskfile()
geterror(V1)
if (V1==1)
...
printf 'n\Error! This is not "Papuas" driver'
...

Основная задача такого программиста, скомпоновать по проекту исходник из макросов,
тщательно следуя рекомендациям по их использованию (что далеко не всегда делается).
В принципе, программист, толком не знает, что именно, делает программа.

Такая политика разработки устройств, позволяет максимально повысить конфедициальность
(систему безопасности) разработки и уменьшает ее стоимость, за счет привлечения
программистов более низких категорий.

... Так-что зря их иногда называют "небожителями" или "крутыми".

--------------------------------------------------------------------------------
... А вот и живой пример трудов программиста "небожителя" из касты WD
--------------------------------------------------------------------------------

___________________Logs_Signs_History_____________________
  _   = Read From Register               Examle: 1X5_8A
  =   = Write To Register                Examle: 1X7=EC
  <<  = Single Read From 1X0 Register    Examle: <<7A42
  >>  = Single Write To 1X0 Register     Examle: >>AA55
  #x: = Maximal ATA-Standard Number For The Met Command
__________________________________________________________

 Start DLGDIAG V.409
=====================
1x6=A0 - Выбирается "Master"
1x7_50 - HDD в состоянии готовности
1x6=A0 - Выбирается "Master"
1x7=EC
 Command: ATA-#6: IDENTIFY DEVICE - Читается паспорт диска

1x7_D0 - BUSY+DRDY+DSC
1x7_58 - Устройство готово к обмену данными

[****** Host READ Data From HDD ******]
7A42 FF3F 37C8 1000 0000 0000 3F00 0000   zBя?7И.....?...
0000 0000 4457 572D 4143 394A 3931 3131   ....DWW-AC9J9111
3437 2038 2020 2020 0000 0040 3A00 3331   47 8    ...@:.31
302E 4733 3331 4457 2043 4457 3038 4A30   0.G331DW CDW08J0
2D42 3030 4D46 3041 2020 2020 2020 2020   -B00MF0A        
2020 2020 2020 2020 2020 2020 2020 1080                 Ђ
....____________cutting____________....

1x7_50 - HDD в состоянии готовности
1x1_00 - Error Register без ошибок
1x7_50 - HDD в состоянии готовности

--------------------------------------------------------------------------------
На первый взгляд здесь нет ошибок, но...
Именно, при анализе паспорта, "небожитель" делает первую ошибку.

... Все модели, различных семейств, у любых производителей, имеют свой собственный
идентификационный номер (Model-ID) и (или) ревизию, которые, обычно, встроены в имя
и (или) серийный номер данной модели. Все эти данные, находятся в паспорте устройства.
Проанализировав паспорт, программа должна определить свою совместимость с устройством.
Если ID-номер, выходит за диапазон поддерживаемых моделей, то программа, должна выдать
сообщение о несовместимости и прекратить дальнейшую работу.
... Но, по всей видимости, программист сделал ошибку первокласника, проверив
только нижнюю границу диапазона поддерживаемых моделей, что в дальнейшем привело
к несовместимости vendor-команд, так-как, тестируемый HDD, входит в состав более
современного семейства, имеет другой набор vendor-команд и другую архитектуру SA.
--------------------------------------------------------------------------------

продолжение...
3x6=06  -- DevCtrl \_ Reset Drive
3x6=02  -- DevCtrl /
1x7_80 - BUSY
1x7_50 - HDD в состоянии готовности

1x1=57 1x2=44 1x3=43 1x4=00 1x5=00 1x6=A0 1x7=8A - Подается несовместимая vendor-команда !!!
 Command: ATA-#6: Vendor specific commands (VS)

1x7_D0 - BUSY+DRDY+DSC
1x7_51 - !!! Error !!!
1x1_04 - Error Register = !!! ABORT !!! Устройство, чуть-ли не криком сообщает об ошибке...

--------------------------------------------------------------------------------
... но, мы-же "небожители", думает программист.
На кой нам, проверять регистры статуса и ошибки...,
лучше, сразу начнем читать service-area...
--------------------------------------------------------------------------------

1x2=01 1x3=10 1x4=FC 1x5=FF 1x6=EF 1x7=20
 Command: ATA-#6: READ SECTOR(S) #12:(w/retry) - Попытка чтения отрицательных цилиндров...

1x7_D0 - BUSY+DRDY+DSC
1x7_51 - !!! Error !!!
1x1_10 - Error Register = !!! IDNF !!! - подумаешь... ID не нашел...

1x2=01 1x3=4F 1x4=FC 1x5=FF 1x6=EF 1x7=20
 Command: ATA-#6: READ SECTOR(S) #12:(w/retry) - Подсунем другой адресок...

1x7_D0 - BUSY+DRDY+DSC
1x7_51 - !!! Error !!!
1x1_10 - Error Register = !!! IDNF !!! - Вот ведь, разорался...

3x6=06  -- DevCtrl \_ Reset Drive  -  Ладно... попробуем еще разок...
3x6=02  -- DevCtrl /

1x7_80
1x7_50 - HDD в состоянии готовности
1x1_01 - Error Register = !!! AMNF !!!

1x1=57 1x2=44 1x3=43 1x4=00 1x5=00 1x6=A0 1x7=8A - Подается несовместимая vendor-команда !!!
 Command: ATA-#6: Vendor specific commands (VS)

1x7_D0
1x7_51 - !!! Error !!!
1x1_04 - Error Register = !!! ABORT !!!

1x2=01 1x3=10 1x4=FC 1x5=FF 1x6=EF 1x7=20
 Command: ATA-#6: READ SECTOR(S) #12:(w/retry)

1x7_D0
1x7_51 - !!! Error !!!
1x1_10 - Error Register = !!! IDNF !!!

1x2=01 1x3=4F 1x4=FC 1x5=FF 1x6=EF 1x7=20
 Command: ATA-#6: READ SECTOR(S) #12:(w/retry)

1x7_D0
1x7_51 - !!! Error !!!
1x1_10 - Error Register = !!! IDNF !!! - Вот-же блин, зараза...

3x6=06  -- DevCtrl \_ Reset Drive - Ну ничего... куда ты денешься... начнем все заново ...
3x6=02  -- DevCtrl /
1x7_80
1x7_50 - HDD в состоянии готовности
1x1_01 - Error Register = !!! AMNF !!!

1x6=AF 1x2=3F 1x7=91
 Command: ATA-#5: Initialize drive parameters - проинициализируем параметры...

1x7_D0
1x7_50 - HDD в состоянии готовности
1x1_00 - Error Register без ошибок - Слава те, Господи, в конце-концов...

1x6=A0 1x7=10
 Command: ATA-#3: Recalibrate - рекалибруем его...

1x7_D0
1x7_50 - HDD в состоянии готовности
1x1_00

1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x1=DA 1x4=4F 1x5=C2 1x7=B0 - Что там SMART-статус кажет ?
 Command: ATA-#6: SMART OPERATIONS

1x7_D0
1x7_50 - HDD в состоянии готовности
1x1_00 - Error Register без ошибок
1x4_4F \_ SMART-статус в норме...
1x5_C2 /

1x2=01 1x3=00 1x4=00 1x5=00 1x6=E0 1x4=4F 1x5=C2 1x1=D0 1x7=B0 - А атрибуты в порядке ?
 Command: ATA-#6: SMART OPERATIONS = SMART READ DATA

1x7_D0
1x7_58
1x1_00 - Error Register без ошибок
1x7_58

[****** Host READ Data From HDD ******]
1000 010B 00BF BF5B 1600 0000 0000 0307   ..її[.....
0066 63D2 0800 0000 0000 0432 0064 64C8   .fcТ.....2.ddИ
0100 0000 0000 0533 00C7 9C03 0000 0000   .....3.Зњ....
0000 070B 00C8 C500 0000 0000 0000 0932   ...ИЕ........2
....____________cutting____________....

1x7_50 - Все хорошо

1x4=4F 1x5=C2 1x1=D4 1x2=01 1x3=81 1x7=B0 - Запустим-ка Self-тест... может потом, съест вендора ?
 Command: ATA-#6: SMART OPERATIONS

1x7_D0
1x7_51 - Self-тест не пройден, не поддерживается сей тест... а нам все по барабану

1x4=4F 1x5=C2 1x3=06 1x1=D5 1x7=B0 - Почитаем self-test log (прошлогодний)
 Command: ATA-#6: SMART OPERATIONS

1x7_D0
1x7_58
1x1_00

[****** Host READ Data From HDD ******]
0100 0339 B901 4100 00F0 FF00 0000 0000   .9№A..ря.....
0000 0000 0000 0000 0000 8139 B901 4100   ..........Ѓ9№A.
00F0 FF00 0000 0000 0000 0000 0000 0000   .ря.............
0000 8139 BC01 4100 00F0 FF00 0000 0000   ..Ѓ9јA..ря.....
....____________cutting____________....

1x7_50 - Все хорошо вроде...

1x2=01 1x3=00 1x4=00 1x5=F0 1x6=EF \_ Может регистры плохо пишутся ?
1x2=01 1x3=00 1x4=00 1x5=F0 1x6=EF /  Попробуем дважы записать адрес трека...
1x1=57 1x2=01 1x7=8A - ... и добавим кусочек от вендора - эдакий, "Vendor Cocktail"...
 Command: ATA-#6: Vendor specific commands (VS) Баааа... Бааххх...

1x7_D0
1x7_51 - !!! Error !!!
1x1_04 - Error Register = !!! ABORT !!! - Ой... что-то опять мимо... можа съел что-нибудь ?...

 Cancell User
==============
Эх жаль... а ведь могло и получится что-нить... если-б юзер не прервал... :(

           *** Done Files Decoding ***
--------------------------------------------------------------------------------

... Опасность таких ошибок в том, что, vendor-команда может подойти (как часто бывает) и на
более современную модель, у которой совершенно другая архитектура Searice Area
(состав, назначение и расположение модулей, структуры (версии) транслятора, таблиц и пр.)
и такое поведение программы, может просто "убить" HDD.
... Кстати, подобная ошибка есть и в DLGDIAG V.412

Видно, наследственное... :)
--------------------------------------------------------------------------------

... На просторах инета, в форумах "хардовых" и прочих, действительно есть немало "гуру"...
Программисты, копатели, ремонтники и любители "железа"...
Не очень они, приветливый народ, скрытный, не сразу лезут целоваться, но это от трудов...

Так-что, кому ближе до неба, это очень спорный вопрос...
--------------------------------------------------------------------------------


будет продолжение...
to be continued...

!!! Happy New Year !!!

17-12-2006 (D-M-Y) (C)NazYura