Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
Рисунок 1. Формат команды START/STOP UNIT
Формат этой команды простой. Поле Operation code содержит код команды 0x1B, а тип требуемой операции задают бит LoEj и Start:
LoEj |
Start |
Действие |
1 |
0 |
открыть лоток CD-ROM |
1 |
1 |
закрыть лоток CD-ROM |
Команда START/STOP UNIT относится к классу пакетных команд, не требующих передачи данных (Non-data Commands). Алгоритм выполнения таких команд следующий (см. п. 5.13, спецификация INF-8020i):
n хост считывает регистр состояния устройства, дожидаясь нулевого значения битов BSY и DRQ. После этого хост заносит в регистр выбора устройство байт, бит DEV которого указывает на адресуемое устройство;
n хост записывает код пакетной команды 0xA0 в командный регистр;
n устройство устанавливает бит BSY в регистре состояния и готовится к приёму пакетной команды;
n подготовившись к приёму пакетной команды, устройство сбрасывает бит BSY и устанавливает бит DRQ;
n хост записывает 12-байтный командный пакет в регистр данных устройства;
n устройство устанавливает бит BSY и приступает к выполнению поступившей команды. После выполнения команды устройство сбрасывает бит BSY, DRQ и устанавливает бит DRDY;
n хост считывает регистр состояния.
Рассмотрим листинг программы, выполняющей открытие и закрытие лотка CD-ROM (файл RAW/atapi_o_c.c).
Биты регистра состояния SR и макроопределения для работы с портами:
#define BSY 0x80
#define DRQ 0x08
#define DRDY 0x40
#define OUT_P_B(val,port) __asm__("outb %%al, %%dx"::"a"(val),"d"(port))
#define OUT_P_W(val,port) __asm__("outw %%ax, %%dx"::"a"(val),"d"(port))
#define IN_P_B(val,port) __asm__("inb %%dx, %%al":"=a"(val):"d"(port))
#define IN_P_W(val,port) __asm__("inw %%dx, %%ax":"=a"(val):"d"(port))
Функция send_packet_command реализует алгоритм выполнения пакетных команд, не требующих передачи данных. Входные параметры функции – указатель на 12-байтный командный пакет:
void send_packet_command(__u8 *cmd_buff)
{
int i;
__u8 status = 0;
__u16 port, a;
port = 0x177; // регистр состояния SR
/* В соответствии с алгоритмом ждем нулевого значения битов BSY и DRQ */
for(;;) {
do {
IN_P_B(status, port);
} while(status & BSY);
if(!(status & DRQ)) break;
}
/* Выбираем устройство Master и в его регистр команд записываем код пакетной команды */
port = 0x176; OUT_P_B(0xA0, port); // бит DEV сброшен
port = 0x177; OUT_P_B(0xA0, port);
/* Ждём сброса бита BSY и установки DRQ */
for(;;) {
do {
IN_P_B(status, port);
} while(status & BSY);
if(status & DRQ) break;
}
port = 0x170; // регистр данных