Hi, I used to have the problem described by Branden Robinson in a previous mail on DebianPPC: a Samsung CDRW/DVD that would not eject discs nor play, nor anything. I patched a 2.4.24-ben1 with your code and now the CD features are working fine. I didn't test burning CDs or playing DVDs yet.
Cheers, Marco Le dim 15/02/2004 à 03:48, Benjamin Herrenschmidt a écrit : > Hi ! > > Recently, there have been lost of reports of ATAPI issues, typically > with CD/DVD burners, where DMA would be disabled for no obvious reasons, > with the driver spitting a message about a timeout waiting for dbdma > command stop. > > The problem is that our driver doesn't deal with buffer underruns due > to the drive not sending as many data as requested. > > This patch is an attempt at fixing this. Please let me know if it > helps. > > Ben. > > ===== drivers/ide/ppc/pmac.c 1.50 vs edited ===== > --- 1.50/drivers/ide/ppc/pmac.c Sat Feb 14 19:29:16 2004 > +++ edited/drivers/ide/ppc/pmac.c Sun Feb 15 13:47:12 2004 > @@ -55,7 +55,7 @@ > > #define IDE_PMAC_DEBUG > > -#define DMA_WAIT_TIMEOUT 100 > +#define DMA_WAIT_TIMEOUT 50 > > typedef struct pmac_ide_hwif { > unsigned long regbase; > @@ -2032,8 +2032,11 @@ > dstat = readl(&dma->status); > writel(((RUN|WAKE|DEAD) << 16), &dma->control); > pmac_ide_destroy_dmatable(drive); > - /* verify good dma status */ > - return (dstat & (RUN|DEAD|ACTIVE)) != RUN; > + /* verify good dma status. we don't check for ACTIVE beeing 0. We > should... > + * in theory, but with ATAPI decices doing buffer underruns, that would > + * cause us to disable DMA, which isn't what we want > + */ > + return (dstat & (RUN|DEAD)) != RUN; > } > > /* > @@ -2047,7 +2050,7 @@ > { > pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; > volatile struct dbdma_regs *dma; > - unsigned long status; > + unsigned long status, timeout; > > if (pmif == NULL) > return 0; > @@ -2063,17 +2066,8 @@ > * - The dbdma fifo hasn't yet finished flushing to > * to system memory when the disk interrupt occurs. > * > - * The trick here is to increment drive->waiting_for_dma, > - * and return as if no interrupt occurred. If the counter > - * reach a certain timeout value, we then return 1. If > - * we really got the interrupt, it will happen right away > - * again. > - * Apple's solution here may be more elegant. They issue > - * a DMA channel interrupt (a separate irq line) via a DBDMA > - * NOP command just before the STOP, and wait for both the > - * disk and DBDMA interrupts to have completed. > */ > - > + > /* If ACTIVE is cleared, the STOP command have passed and > * transfer is complete. > */ > @@ -2085,15 +2079,26 @@ > called while not waiting\n", HWIF(drive)->index); > > /* If dbdma didn't execute the STOP command yet, the > - * active bit is still set */ > - drive->waiting_for_dma++; > - if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { > - printk(KERN_WARNING "ide%d, timeout waiting \ > - for dbdma command stop\n", HWIF(drive)->index); > - return 1; > - } > - udelay(5); > - return 0; > + * active bit is still set. We consider that we aren't > + * sharing interrupts (which is hopefully the case with > + * those controllers) and so we just try to flush the > + * channel for pending data in the fifo > + */ > + udelay(1); > + writel((FLUSH << 16) | FLUSH, &dma->control); > + timeout = 0; > + for (;;) { > + udelay(1); > + status = readl(&dma->status); > + if ((status & FLUSH) == 0) > + break; > + if (++timeout > 100) { > + printk(KERN_WARNING "ide%d, ide_dma_test_irq \ > + timeout flushing channel\n", HWIF(drive)->index); > + break; > + } > + } > + return 1; > } > > static int __pmac > >
signature.asc
Description: Ceci est une partie de message =?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e=2E?=