From: Manfred Scherer While reading data from the hard disk and a read error occurs as reported below, the kernel will hang in ide-io.c in the function try_to_flush_leftover_data() in the statement hwif->INSW(IDE_DATA_REG, buffer, wcount<<1). On the console 10 appears this messages: hde: dma_intr: status=0x59 { DriveReady SeekComplete DataRequest Error } hde: dma_intr: error=0x01 { AddrMarkNot Found }, LBAsect=1253209, high=0, low=1253209, sector=1252805 This strange behaviour seems to be a special issue with promise controllers especially with the models ID_PROMISE_20268 (thats was my personal test case) and ID_PROMISE_20269 as reported years ago in the internet. My suggestion is to leave off try_to_flush_leftover_data() for promise controllers. Unfortunately it is hard to reproduce this test case if you don't have such a disk controller and such a disk fault. Signed-off-by: Manfred Scherer Cc: Bartlomiej Zolnierkiewicz Cc: Alan Cox Alan Cox wrote: > > On Llu, 2005-10-31 at 14:46 -0800, akpm@osdl.org wrote: > > diff -puN drivers/ide/ide-iops.c~ide-promise-flushing-hang-fix drivers/ide/ide-iops.c > > --- 25/drivers/ide/ide-iops.c~ide-promise-flushing-hang-fix Mon Oct 31 14:44:08 2005 > > +++ 25-akpm/drivers/ide/ide-iops.c Mon Oct 31 14:44:08 2005 > > @@ -1074,7 +1074,8 @@ static void check_dma_crc(ide_drive_t *d > > if (drive->current_speed >= XFER_SW_DMA_0) > > (void) HWIF(drive)->ide_dma_on(drive); > > } else > > - (void)__ide_dma_off(drive); > > + // (void)__ide_dma_off(drive); > > + return; // 2005-09-10 --ms, no crc-error, leave speed as it is! > > #endif > > > That doesn't look a good idea. Patch would make much more sense if it > added hwif->flush_leftover_data() and called it if it was set by the > host interface. That would then match the rest of the kernel and not > mangle it all. > > Also hwif->pci_dev may be NULL so the code is going to crash systems > too. > > Theory may be sound (Bart - are we perhaps resetting the state machine > too early ?) implementation needs rework. > Signed-off-by: Andrew Morton --- drivers/ide/ide-io.c | 40 +++++++++++++++++++++++++++++++++++++++- drivers/ide/ide-iops.c | 3 ++- 2 files changed, 41 insertions(+), 2 deletions(-) diff -puN drivers/ide/ide-io.c~ide-promise-flushing-hang-fix drivers/ide/ide-io.c --- devel/drivers/ide/ide-io.c~ide-promise-flushing-hang-fix 2005-11-05 02:24:10.000000000 -0800 +++ devel-akpm/drivers/ide/ide-io.c 2005-11-05 02:24:10.000000000 -0800 @@ -445,10 +445,48 @@ static ide_startstop_t ide_ata_error(ide /* help it find track zero */ rq->errors |= ERROR_RECAL; } + /* 2005/09/10 --ms, this case was left here */ + else if (err & MARK_ERR) { + /* retry because AddrMarkNotFound */ + rq->errors |= ERROR_RECAL; + } } if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) - try_to_flush_leftover_data(drive); + /* 2005-09-10 --ms + * To avoid a system hang in hwif->INSW(IDE_DATA_REG, buffer, + * wcount<<1), possibly caused by a bug in the disk controller, + * hence we check here the disk controller model. + */ + switch (HWIF(drive)->pci_dev->device) { + // case PCI_DEVICE_ID_PROMISE_20277: + // case PCI_DEVICE_ID_PROMISE_20276: + // case PCI_DEVICE_ID_PROMISE_20275: + // case PCI_DEVICE_ID_PROMISE_20271: + // case PCI_DEVICE_ID_PROMISE_20270: + case PCI_DEVICE_ID_PROMISE_20269: + case PCI_DEVICE_ID_PROMISE_20268: // my pci device + printk(KERN_WARNING "%s: ide_ata_error, " + "PROMISE_202*\n", drive->name); + /* + * try_to_flush_leftover_data() will hang in + * various cases like: + * ABRT_ERR DriveStatusError + * ICRC_ERR BadCRC BadSector + * ECC_ERR UncorrectableError (will hang + * too) + * ID_ERR SectorIdNotFound + * TRK0_ERR TrackZeroNotFound + * MARK_ERR AddrMarkNotFound (this was my + * actual testcase) + */ + if (!(err & (ABRT_ERR | ICRC_ERR | ECC_ERR | + ID_ERR | TRK0_ERR | MARK_ERR))) + try_to_flush_leftover_data(drive); + break; + default: + try_to_flush_leftover_data(drive); + } if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) /* force an abort */ diff -puN drivers/ide/ide-iops.c~ide-promise-flushing-hang-fix drivers/ide/ide-iops.c --- devel/drivers/ide/ide-iops.c~ide-promise-flushing-hang-fix 2005-11-05 02:24:10.000000000 -0800 +++ devel-akpm/drivers/ide/ide-iops.c 2005-11-05 02:24:10.000000000 -0800 @@ -1068,7 +1068,8 @@ static void check_dma_crc(ide_drive_t *d if (drive->current_speed >= XFER_SW_DMA_0) (void) HWIF(drive)->ide_dma_on(drive); } else - (void)__ide_dma_off(drive); + // (void)__ide_dma_off(drive); + return; // 2005-09-10 --ms, no crc-error, leave speed as it is! #endif } _