Re: ide-cd problem

From: Alan Chandler
Date: Fri Nov 26 2004 - 18:49:34 EST


On Tuesday 23 November 2004 21:49, Alan Chandler wrote:

>
> Before, I thought my hardware was a little out of spec - now I think there
> is something else at play here.
>

Firstly, I think there might be another race condition like the one Alan Cox
found. I attach a patch below with the fix for that (against 2.6.10-rc2, an
including Alan's patch) I'm not 100% sure its necessary, but it seems fix a
variation I have been seeing.

With it in place, and apart from the ongoing issue - see below, I have managed
to remove the delay in drive_is_ready() altogether without any ill effects.

[my reading of the ATA spec is that 400ns is needed after reading the status
reg before IRQ is removed, I had wondered whether it would be better to
record the time here and then check whether we had used up the 400ns just
before returning from the interrupt state]

> Nov 23 20:37:33 kanger kernel: ide-cd:cdrom_newpc_intr - cmd=0x0 stat=0x50
> ireason=3 len=2048 rq len=0
..
> Nov 23 20:37:33 kanger kernel: ide-cd:cdrom_newpc_intr - cmd=0x1b stat=0x58
> ireason=2 len=0 rq len=0

I think these two lines hold the crux of the problem. They are the result of
a printk in cdrom_newpc_intr just after reading the interrupt reason register
and byte count registers.

However, I have been unable to get any closer as to why DRQ gets set.

The patch

--- ide-cd.c 2004-11-26 20:29:59.000000000 +0000
+++ ide-cd.patch.c 2004-11-26 20:51:23.000000000 +0000
@@ -890,8 +890,12 @@
ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC,
cdrom_timer_expiry);
return ide_started;
} else {
+ unsigned long flags;
+ spin_lock_irqsave(&ide_lock, flags);
+ HWIF(drive)->OUTBSYNC(drive, WIN_PACKETCMD, IDE_COMMAND_REG);
+ ndelay(400);
+ spin_unlock_irqrestore(&ide_lock, flags);
/* packet command */
- HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
return (*handler) (drive);
}
}
@@ -938,8 +942,12 @@
cmd_len = ATAPI_MIN_CDB_BYTES;

/* Send the command to the device. */
+ unsigned long flags;
+ spin_lock_irqsave(&ide_lock, flags);
HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
-
+ ndelay(400);
+ spin_unlock_irqrestore(&ide_lock, flags);
+
/* Start the DMA if need be */
if (info->dma)
hwif->dma_start(drive);

--
Alan Chandler
alan@xxxxxxxxxxxxxxxxxxxxx
First they ignore you, then they laugh at you,
then they fight you, then you win. --Gandhi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/