diff -ur linux-2.5.24/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c --- linux-2.5.24/drivers/ide/ide-disk.c Thu Jun 27 13:34:42 2002 +++ linux/drivers/ide/ide-disk.c Fri Jun 28 22:53:53 2002 @@ -279,14 +279,16 @@ rq->bio = NULL; ret = ide_stopped; } else if (!ok) { - /* no data yet, so wait for another interrupt */ - /* FIXME: --bzolnier */ - if (!ch->handler) - ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); + /* not ready yet, so wait for next IRQ */ + ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); + ret = ide_started; } else { int mcount = drive->mult_count; + /* prepare for next IRQ */ + ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); + do { char *buf; int nsect = rq->current_nr_sectors; @@ -314,6 +316,7 @@ rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9; } } + rq->errors = 0; /* FIXME: why? --bzolnier */ /* * Ok, we're all setup for the interrupt re-entering us on the @@ -323,12 +326,6 @@ bio_kunmap_irq(buf, &flags); } while (mcount); - rq->errors = 0; - - /* FIXME: --bzolnier */ - if (!ch->handler) - ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); - ret = ide_started; } @@ -526,6 +523,7 @@ printk("buffer=%p\n", rq->buffer); #endif } + rq->special = ar; /* * Channel lock should be held on entry. @@ -552,28 +550,25 @@ /* FIXME: this is actually distingushing between PIO and DMA requests. */ if (ar->XXX_handler) { + if (ar->command_type == IDE_DRIVE_TASK_IN || + ar->command_type == IDE_DRIVE_TASK_NO_DATA) { - ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL); - OUT_BYTE(cmd, IDE_COMMAND_REG); + ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL); + OUT_BYTE(cmd, IDE_COMMAND_REG); + + return ide_started; + } /* FIXME: Warning check for race between handler and prehandler * for writing first block of data. however since we are well * inside the boundaries of the seek, we should be okay. - * - * FIXME: Replace the switch by using a proper command_type. + * FIXME: should be fixed --bzolnier */ - - if (cmd == CFA_WRITE_SECT_WO_ERASE || - cmd == WIN_WRITE || - cmd == WIN_WRITE_EXT || - cmd == WIN_WRITE_VERIFY || - cmd == WIN_WRITE_BUFFER || - cmd == WIN_DOWNLOAD_MICROCODE || - cmd == CFA_WRITE_MULTI_WO_ERASE || - cmd == WIN_MULTWRITE || - cmd == WIN_MULTWRITE_EXT) { + if (ar->command_type == IDE_DRIVE_TASK_RAW_WRITE) { ide_startstop_t startstop; + OUT_BYTE(cmd, IDE_COMMAND_REG); + if (ata_status_poll(drive, DATA_READY, drive->bad_wstat, WAIT_DRQ, rq, &startstop)) { printk(KERN_ERR "%s: no DRQ after issuing %s\n", @@ -591,7 +586,10 @@ unsigned long flags; char *buf = ide_map_rq(rq, &flags); + ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL); + /* For Write_sectors we need to stuff the first sector */ + /* FIXME: what if !rq->current_nr_sectors --bzolnier */ ata_write(drive, buf, SECTOR_WORDS); rq->current_nr_sectors--; @@ -621,6 +619,7 @@ printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n"); } + /* will set handler for us */ return ar->XXX_handler(drive, rq); } } @@ -632,6 +631,7 @@ * FIXME: Handle the alternateives by a command type. */ + /* FIXME: ide_started? --bzolnier */ if (!drive->using_dma) return ide_started; @@ -656,6 +656,7 @@ } } + /* not reached */ return ide_started; } diff -ur linux-2.5.24/drivers/ide/ide-taskfile.c ide/ide-taskfile.c --- linux-2.5.24/drivers/ide/ide-taskfile.c Thu Jun 27 13:34:42 2002 +++ ide/ide-taskfile.c Fri Jun 28 23:06:27 2002 @@ -209,27 +209,22 @@ rq->errors = 0; rq->rq_status = RQ_ACTIVE; rq->rq_dev = mk_kdev(major,(drive->select.b.unit)<waiting = &wait; + spin_lock_irqsave(drive->channel->lock, flags); + } - spin_lock_irqsave(drive->channel->lock, flags); + if (action == ide_preempt) + drive->rq = NULL; + else if (!blk_queue_empty(&drive->queue)) + queue_head = queue_head->prev; /* ide_end and ide_wait */ - if (blk_queue_empty(&drive->queue) || action == ide_preempt) { - if (action == ide_preempt) - drive->rq = NULL; - } else { - if (action == ide_wait) - queue_head = queue_head->prev; - else - queue_head = queue_head->next; - } q->elevator.elevator_add_req_fn(q, rq, queue_head); do_ide_request(q); - spin_unlock_irqrestore(drive->channel->lock, flags); - if (action == ide_wait) { + spin_unlock_irqrestore(drive->channel->lock, flags); wait_for_completion(&wait); /* wait for it to be serviced */ return rq->errors ? -EIO : 0; /* return -EIO if errors */ } diff -ur linux-2.5.24/drivers/ide/ide.c linux/drivers/ide/ide.c --- linux-2.5.24/drivers/ide/ide.c Thu Jun 27 13:34:42 2002 +++ linux/drivers/ide/ide.c Fri Jun 28 23:55:28 2002 @@ -161,6 +161,7 @@ { struct ata_channel *ch = drive->channel; + /* FIXME: change it later to BUG_ON(ch->handler) --bzolnier */ if (ch->handler) printk("%s: %s: handler not null; old=%p, new=%p, from %p\n", drive->name, __FUNCTION__, ch->handler, handler, __builtin_return_address(0)); @@ -177,43 +178,29 @@ static void check_crc_errors(struct ata_device *drive) { if (!drive->using_dma) - return; + return; /* check the DMA crc count */ if (drive->crc_count) { udma_enable(drive, 0, 0); if (drive->channel->speedproc) { - u8 pio = XFER_PIO_4; + u8 mode = drive->current_speed; drive->crc_count = 0; - switch (drive->current_speed) { - case XFER_UDMA_7: pio = XFER_UDMA_6; - break; - case XFER_UDMA_6: pio = XFER_UDMA_5; - break; - case XFER_UDMA_5: pio = XFER_UDMA_4; - break; - case XFER_UDMA_4: pio = XFER_UDMA_3; - break; - case XFER_UDMA_3: pio = XFER_UDMA_2; - break; - case XFER_UDMA_2: pio = XFER_UDMA_1; - break; - case XFER_UDMA_1: pio = XFER_UDMA_0; - break; + if (mode > XFER_UDMA_0) + mode--; + else /* * OOPS we do not goto non Ultra DMA modes * without iCRC's available we force * the system to PIO and make the user * invoke the ATA-1 ATA-2 DMA modes. */ - case XFER_UDMA_0: - default: - pio = XFER_PIO_4; - } - drive->channel->speedproc(drive, pio); + mode = XFER_PIO_4; + + drive->channel->speedproc(drive, mode); } - if (drive->current_speed >= XFER_SW_DMA_0) + if (drive->current_speed >= XFER_UDMA_0) udma_enable(drive, 1, 1); } else udma_enable(drive, 0, 1); @@ -901,12 +888,12 @@ drive->rq = rq; - ide__sti(); /* allow other IRQs while we start this request */ +// ide__sti(); /* allow other IRQs while we start this request */ /* command started, we are busy */ } while (ide_started != start_request(drive, rq)); /* make sure the BUSY bit is set */ /* FIXME: perhaps there is some place where we miss to set it? */ - set_bit(IDE_BUSY, ch->active); +// set_bit(IDE_BUSY, ch->active); } }