Сложный конечный автомат
if (! rq › nr__sectors) { /* all done? */ rq = hwgroup › rq;
for (i = rq › nr_sectors; i > 0;){ i – = rq › current_nr_sectors;
ide_end_request(1, hwgroup); } return ide stopped;
return ide_stopped; /* Оригинальный код делал это здесь (?) */
! Внешних
[return ide_errcr(drive, "multwrite_intr", stat);
/*
i do rw disk() передает команды READ и WRITE приводу,
* используя LBA если поддерживается, или CHS если нет, для адресации
* секторов. Функция do_rw_disk также передает специальные запросы.
*/
static ide_startstop__t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
{ if (IDE_CONTROL_REG)
OUT_BYTE (drive › ctl, IDE_CONTROL_REG);
OUT_BYTE (rq › nr_sectors, IDE_NSECTOR_REG); if (drive › select.b.lba) (
OUT_BYTE (block, IDE_SECTOR_REG);
OUT_BYTE (block"=8, IDE_LCYL_REG);
OUT_BYTE (block"=8, I DE_HC YL_REG);
OUT_BYTE(((block"8) &0x0f) I drive › select .all, IDE_SELECT_REG); } else f
unsigned int sect, head, cyl, track;
track = block / drive › sect;
sect = block % drive › sect + 1;
ODT^BYTE (sect, IDE__SECTOR_REG);
head = track % drive › head;
cyl = track / drive › head;
OUT__BYTE (cyl, IDE_LCYL_REG);
OUT_BYTE (cyl"8, IDE_HCYL_REG);
OUT_BYTE (head I drive › select.all, IDE_SELECT_REG);
if (rq › cmd == READ) { ^#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive – >using_dma &&! (HWIF (drive) › dmaproc (ide_dma_read, drive))
return ide_started; #endif /* CONFIG_BLK_DEV_IDEDMA */
ide_set_handler (drive, iread_intr, WAIT_CMD, NULL);
OUT_BYTE(drive › mult_count? WIN_MULTREAD: WIN_READ, IDE COMMAND REG);
''– -^
return ide started;
if (rq › cmd == WRITE) (
ide_startstop_t startstop; lifdef CONFIG_BLK_DEV_IDEDMA
if (drive › using_drna &&!(HWIF(drive) › dmaproc(ide dma^write,
drive)))
return ide_started; lendif /* CONFIG_BLK_DEV_IDEDMA */
OUT_BYTE(drive › mult_COUnt? WIN_MULTWRITE: WIN_WRITE,
IDE_COMMAND_REG); if (ide_wait_stat(Sstartstop, drive, DATA_READY, drive › bad_wstat,
WAIT^DRQ)) (printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive › na:r.e,
drive › mult_count? "MULTWRITE": "WRITE"); return startstop;
if (!drive › unmask)
__cli(); /* только локальное ЦПУ */
if (drive › mult_count) (
ide_hwgroup_t *hwgroup = HWGROUP(drive);
/*
* Эта часть выглядит некрасиво, потому что мы ДОЛЖНЫ установить
* обработчик перед выводом первого блока данных.
* Если мы обнаруживаем ошибку (испорченный список буферов)
* в ide_multiwrite(),
* нам необходимо удалить обработчик и таймер перед возвратом.
* К счастью, это НИКОГДА не происходит (правильно?).
* Кажется, кроме случаев, когда мы получаем ошибку… */
hwgroup › wrq = *rq; /* scratchpad */
ide_set_handler (drive, &multwrite_intr, WAIT__CMD, NULL);
if (ide_multwrite(drive, drive › mult_count)) {
unsigned long flags;
spin_lock_irqsave (&io__request_lock, flags);
hwgroup › handler = NULL;
del_timer(&hwgroup › timer);
spin unlock_irqrestore(&io_request_lock, flags);
return ide_stopped;
Глава 10. Драйверы внешних
} else {
ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
idedisk_output_data(drive, rq › buffer, SECTOR_WORDS);
}
i return ide_started;
)
i'-printk (KERN_ERR "%s: bad command: %d\n", drive › name, rq › cmd)
ide_end_request(0, HWGROUP(drive)); return ide_stopped;