Subject: Re: 3.0-stable newbee questions
To: Martin Husemann <martin@duskware.de>
From: J.D. Bronson <jbronson@wixb.com>
List: netbsd-users
Date: 07/16/2006 14:39:00
At 02:18 PM 7/16/2006, Martin Husemann wrote:
>Can you recompile a kernel? If not, what kernel would you need for
>testing?
>
>The code in question is in src/sys/dev/pci/rccide.c around line
>216:
>
>                 if ((atac->atac_cap & ATAC_CAP_UDMA) &&
>                     (drvp->drive_flags & DRIVE_UDMA)) {
>                         /* use Ultra/DMA, check for 80-pin cable */
>                         if (drvp->UDMA_mode > 2 &&
>                             (PCI_PRODUCT(pci_conf_read(sc->sc_pc, sc->sc_tag,
>                                                        PCI_SUBSYS_ID_REG))
>                              & (1 << (14 + channel))) == 0)
>                                 drvp->UDMA_mode = 2;
>
>You could try to comment out the
>
>         /* drvp->UDMA_mode = 2 */ ;
>
>and see how that kernel works.
>
>Martin

yes. I have built 2 kernels for this machine so far..so thats not a problem :)

IIRC, I had a very similar issue with OpenBSD and my Serverworks IDE 
chipset. It was incorrectly testing the 80wire and as such would slow 
down the IDE drive. I was given a few 'patches' to test with and when 
I was successful, I believe it was merged into src. I think it was 
the revision (93) of my Serverworks chipset that caused a 'misread' 
of the 80-wire test.

"ServerWorks CSB5 IDE" rev 0x93: DMA


Seeing your code above, gave me the reminder....


here is the chunk of code from pciide.c under openbsd 3.8:

         /* Per drive settings */
         for (drive = 0; drive < 2; drive++) {
                 drvp = &chp->ch_drive[drive];
                 /* If no drive, skip */
                 if ((drvp->drive_flags & DRIVE) == 0)
                         continue;
                 unit = drive + 2 * channel;
                 /* add timing values, setup DMA if needed */
                 pio_time |= pio_modes[drvp->PIO_mode] << (8 * (unit^1));
                 pio_mode |= drvp->PIO_mode << (4 * unit + 16);
                 if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&
                     (drvp->drive_flags & DRIVE_UDMA)) {
                         /* use Ultra/DMA, check for 80-pin cable */
                         if (sc->sc_rev <= 0x92 && drvp->UDMA_mode > 2 &&
                             (PCI_PRODUCT(pci_conf_read(sc->sc_pc, sc->sc_tag,
                             PCI_SUBSYS_ID_REG)) &
                             (1 << (14 + channel))) == 0) {
                                 WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire "
                                     "cable not detected\n", drvp->drive_name,
                                     sc->sc_wdcdev.sc_dev.dv_xname,
                                     channel, drive), DEBUG_PROBE);
                                 drvp->UDMA_mode = 2;
                         }
                         dma_time |= dma_modes[drvp->DMA_mode] << (8 
* (unit^1));
                         udma_mode |= drvp->UDMA_mode << (4 * unit + 16);
                         udma_mode |= 1 << unit;
                         idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
                 } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) &&
                     (drvp->drive_flags & DRIVE_DMA)) {
                         /* use Multiword DMA */
                         drvp->drive_flags &= ~DRIVE_UDMA;
                         dma_time |= dma_modes[drvp->DMA_mode] << (8 
* (unit^1));
                         idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
                 } else {
                         /* PIO only */
                         drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
                 }
         }


-JD