From: Ross Biro <rossb@google.com>
To: Andre Hedrick <andre@linux-ide.org>
Cc: alan@lxorguk.ukuu.org.uk, marcelo@conectiva.com.br,
linux-kernel@vger.kernel.org
Subject: Re: PATCH: [2.4.21-pre3] IDE error recovery
Date: Tue, 14 Jan 2003 09:08:15 -0800 [thread overview]
Message-ID: <3E2443FF.1030101@google.com> (raw)
In-Reply-To: Pine.LNX.4.10.10301132318090.18906-100000@master.linux-ide.org
I knew this was going to be a problem.
ATA-6 no longer allows a device to claim ATA-2 compatibility. The bit
is obsolete.
ATA-3 does not allow IDLE IMMEDIATE. We need to changre the error
recovery depending on which bits are set.
ATA-6 => use srst
ATA-2 => idle immediate
Anything else is probably srst as well.
One of the drives that has trouble claims ATA-2 through ATA-6, which is
interesting, This means this device claims to support ATA-5, hence we
should be able to interpret the bits in the Identify device according to
ATA-5 which means it supports ATA-2 which it clearly does not. Only 1
of the 3 different drives I've looked at gets it right and does not
claim ATA-2 support when it does not support it. I'll drop an email to
a couple of manufacturers and let them know their drives have a problem.
Ross
Andre Hedrick wrote:
>Whoa, you need to check whic spec you are refering to first.
>
> Model=FUJITSU MHJ2181AT, FwRev=D034, SerialNo=01001697
> Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs }
> RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=4
> BuffType=unknown, BuffSize=512kB, MaxMultSect=16, MultSect=16
> CurCHS=17475/15/63, CurSects=-78446341, LBA=yes, LBAsects=35433216
> IORDY=yes, tPIO={min:240,w/IORDY:120}, tDMA={min:120,rec:120}
> PIO modes: pio0 pio1 pio2 pio3 pio4
> DMA modes: mdma0 mdma1 mdma2 udma0 udma1 *udma2 udma3 udma4
> AdvancedPM=yes: disabled (255)
> Drive Supports : Reserved : ATA-2 ATA-3 ATA-4 ATA-5
> Kernel Drive Geometry LogicalCHS=2205/255/63 PhysicalCHS=37495/15/63
>
>This drive claims ATA2-5 support, and thus it accepts the status quo.
>Where are you finding the violations?
>If the drive vendor states a range of support they are in violation.
>This is clearly the point where the driver core needs to have a
>
> unsinged long drive->support_bits
>
>The mess this is going to create.
>
>Cheers,
>
>On Mon, 13 Jan 2003, Ross Biro wrote:
>
>
>
>>Take this patch with a big grain of salt.
>>
>>The current IDE error recovery code will send a IDLEIMMEDIATE in the
>>case when a drive is still busy or has drq set during an error. This is
>>a violation of the ATA spec and hoses up quite a few drives. The
>>prefered form of error recovery seems to be a soft reset followed by a
>>set features. This patch replaces the IDLEIMMEDIATE with a reset, but
>>does not do the set features. The set features should not be necessary,
>>but at least one drive vendor does most of their testing with the set
>>features. OK_TO_RESET_CONTROLLER must be set to 1 if this patch is applied.
>>
>>I've modified the google kernel to add a desired_speed to ide_drive_t
>>and check to see if current_speed != desired_speed before every read or
>>write request. This causes a set features after a reset. I can provide
>>patches to do something similiar for 2.4.21, but I'm not sure it's
>>appropriate. There are bugs in the way hdparm -X is handled in 2.4.20,
>>and this patch would fix them as well, but it may be too large of a
>>patch for a stable kernel.
>>
>>This also fixes drive_cmd_intr to do a little better checking to make
>>sure the device is ready. The spec requires this, but any device that
>>sends an interrupt before it's ready is probably broken.
>>
>>I have no idea what impact this will have on older devices or non disks.
>>
>>This patch has only been minimally tested.
>>
>>----- snip -------
>>diff -durbB linux-2.4.20-p1/drivers/ide/ide-cd.c
>>linux-2.4.20-p2/drivers/ide/ide-cd.c
>>--- linux-2.4.20-p1/drivers/ide/ide-cd.c Wed Jan 8 16:25:04 2003
>>+++ linux-2.4.20-p2/drivers/ide/ide-cd.c Thu Jan 9 11:38:22 2003
>>@@ -644,7 +644,11 @@
>> }
>> if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
>> /* force an abort */
>>- HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
>>+ /* This violates the ATA Spec and causes trouble for
>>+ many modern hard drives. I'm not sure if it is
>>necessary
>>+ for older devices or even modern cd-roms. -- RAB
>>+ HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); */
>>+ rq->errors |= ERROR_RESET;
>> }
>> if (rq->errors >= ERROR_MAX) {
>> DRIVER(drive)->end_request(drive, 0);
>>diff -durbB linux-2.4.20-p1/drivers/ide/ide-disk.c
>>linux-2.4.20-p2/drivers/ide/ide-disk.c
>>--- linux-2.4.20-p1/drivers/ide/ide-disk.c Wed Jan 8 16:25:17 2003
>>+++ linux-2.4.20-p2/drivers/ide/ide-disk.c Thu Jan 9 11:40:20 2003
>>@@ -943,7 +943,11 @@
>> }
>> if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
>> /* force an abort */
>>- hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
>>+ /* This violates the ATA Spec and causes trouble for
>>+ many modern hard drives. I'm not sure if it is
>>necessary
>>+ for older devices or even other modern devices. -- RAB
>>+ hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); */
>>+ rq->errors |= ERROR_RESET;
>> }
>> if (rq->errors >= ERROR_MAX)
>> DRIVER(drive)->end_request(drive, 0);
>>diff -durbB linux-2.4.20-p1/drivers/ide/ide-io.c
>>linux-2.4.20-p2/drivers/ide/ide-io.c
>>--- linux-2.4.20-p1/drivers/ide/ide-io.c Wed Jan 8 16:25:37 2003
>>+++ linux-2.4.20-p2/drivers/ide/ide-io.c Mon Jan 13 18:01:52 2003
>>@@ -328,7 +328,12 @@
>> }
>> if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
>> /* force an abort */
>>+ /* This violates the ATA Spec and causes trouble for
>>+ many modern hard drives. I'm not sure if it is
>>necessary
>>+ for older devices or even other modern ata devices
>>-- RAB
>> hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
>>+ */
>>+ rq->errors |= ERROR_RESET;
>> }
>> if (rq->errors >= ERROR_MAX) {
>> if (drive->driver != NULL)
>>@@ -397,18 +402,63 @@
>> struct request *rq = HWGROUP(drive)->rq;
>> ide_hwif_t *hwif = HWIF(drive);
>> u8 *args = (u8 *) rq->buffer;
>>- u8 stat = hwif->INB(IDE_STATUS_REG);
>>+ u8 stat;
>> int retries = 10;
>>
>>+ /* The ATA-6 spec requires a 400ns wait when entering the
>>+ HPIOI1: Check_status State from the HI4 state. We should
>>+ only get here coming from the HPIOI0 INTRQ_wait state, but
>>+ better safe than sorry. The spec also says a read of the
>>+ alt status register accomplishes this wait. */
>>+ if (IDE_CONTROL_REG)
>>+ (void)hwif->INB(IDE_ALTSTATUS_REG);
>>+ else
>>+ ide_delay_400ns();
>>+
>>+ /* The ATA-6 spec says that the should enter the check status
>>+ state when it get's an interrupt for a drive command, so
>>+ technically, the device can send an interrupt before it has
>>+ finished. I would consider any device that does this to be
>>+ broken, but the spec allows it. --RAB 1/10/03 */
>>+ stat = hwif->INB(IDE_STATUS_REG);
>>+ if (stat & BUSY_STAT) {
>>+ /* We are just supposed to poll from here on out. */
>>+ if (HWGROUP(drive)->poll_timeout == 0) {
>>+
>>HWGROUP(drive)->poll_timeout=WAIT_CMD/CMD_POLL_TICKS;
>>+ } else if (--HWGROUP(drive)->poll_timeout == 0) {
>>+ return DRIVER(drive)->error(drive,
>>+ "drive_cmd timeout",
>>+ stat);
>>+ }
>>+ ide_set_handler(drive, drive_cmd_intr, CMD_POLL_TICKS,
>>NULL);
>>+ return ide_started;
>>+ }
>>+
>> local_irq_enable();
>>- if ((stat & DRQ_STAT) && args && args[3]) {
>>+
>>+ /* We want to make sure that the device and the command
>>+ both agree on wether or not data is returned by the command
>>+ that was just issued. If they do not, it is an error. */
>>+ if (args && args[3]) {
>> u8 io_32bit = drive->io_32bit;
>>+ /* The software expects some data back. If the drive does
>>+ not, then it is an error. */
>>+ if (!(stat & DRQ_STAT)) {
>>+ return DRIVER(drive)->error(drive, "drive_cmd
>>no data", stat);
>>+ }
>> drive->io_32bit = 0;
>> hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
>> drive->io_32bit = io_32bit;
>> while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) &&
>>retries--)
>> udelay(100);
>>+ } else {
>>+ /* The software does not expect data, so if the drive
>>+ returns some, then it's an error. */
>>+ if (stat & DRQ_STAT) {
>>+ return DRIVER(drive)->error(drive, "drive_cmd
>>unexpected data", stat);
>>+ }
>> }
>>+
>>
>> if (!OK_STAT(stat, READY_STAT, BAD_STAT))
>> return DRIVER(drive)->error(drive, "drive_cmd", stat);
>>diff -durbB linux-2.4.20-p1/drivers/ide/ide-taskfile.c
>>linux-2.4.20-p2/drivers/ide/ide-taskfile.c
>>--- linux-2.4.20-p1/drivers/ide/ide-taskfile.c Wed Jan 8 16:25:43 2003
>>+++ linux-2.4.20-p2/drivers/ide/ide-taskfile.c Fri Jan 10 11:19:07 2003
>>@@ -485,7 +485,13 @@
>> }
>> if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
>> /* force an abort */
>>- hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
>>+ /* This violates the ATA Spec and causes trouble for
>>+ many modern hard drives. I'm not sure if it is
>>necessary
>>+ for older devices or even other modern ata devices
>>-- RAB
>>+ hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
>>+ */
>>+ rq->errors |= ERROR_RESET;
>>+
>> }
>> if (rq->errors >= ERROR_MAX) {
>> DRIVER(drive)->end_request(drive, 0);
>>diff -durbB linux-2.4.20-p1/include/linux/ide.h
>>linux-2.4.20-p2/include/linux/ide.h
>>--- linux-2.4.20-p1/include/linux/ide.h Thu Jan 9 15:37:22 2003
>>+++ linux-2.4.20-p2/include/linux/ide.h Mon Jan 13 18:04:47 2003
>>@@ -271,6 +271,10 @@
>> #define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when
>>spinning up */
>> #define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to
>>happen */
>> #define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */
>>+#define CMD_POLL_TICKS (1) /* How long to wait in ticks between
>>+ status checks for a drive cmd
>>+ that set it's interrupt before it
>>+ was complete. */
>>
>> #define HOST(hwif,chipset) \
>> { \
>>
>>
>>
>>
>
>Andre Hedrick
>LAD Storage Consulting Group
>
>
>
next prev parent reply other threads:[~2003-01-14 17:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-14 2:39 PATCH: [2.4.21-pre3] IDE error recovery Ross Biro
2003-01-14 3:44 ` Ross Biro
2003-01-14 7:23 ` Andre Hedrick
2003-01-14 17:08 ` Ross Biro [this message]
2003-01-14 17:36 ` Ross Biro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3E2443FF.1030101@google.com \
--to=rossb@google.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=andre@linux-ide.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo@conectiva.com.br \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.