On 2011-03-31 17:20, Allen Weiner wrote:
On Wed, 2011-03-16 at 17:18 -0400, Chris Knadle wrote:
On Wednesday, March 16, 2011 15:38:47 Allen Weiner wrote:
Linux (both Fedora 14 and Ubuntu 10.10) is limiting my UDMA/133 PATA HDD
(my main system drive) to UDMA/33:

1.861688] ata7.00: ATA-7: Maxtor 6Y080L0, YAR41BW0, max UDMA/133
[    1.861928] ata7.00: 156250000 sectors, multi 0: LBA
[    1.862181] ata7.00: limited to UDMA/33 due to 40-wire cable
[    1.868673] ata7.00: configured for UDMA/33

... <trimming>

Chris, thanks for your reply. This Maxtor HDD doesn't have the option of
being configured for "single mode".

For hard disks that don't have a separate single mode jumper setting, you can use "master" to do the same thing. However in this case I don't think that the fact that you're using "cable select" is related to this problem. The problem with "cable select" relates to misdetection of whether a device should be "master" or "slave" and thus whether it shows up or conflicts with another device on the same cable -- not what TX/RX speed the interface is.

I posted this problem to the mailing list "linux-ide" at kernel.org. I
was surprised to learn that in addition to the
"linux-kernel-mailing-list", kernel.org sponsors several dozen
special-topic mailing lists such as linux-ide, linux-scsi, linux-acpi.

That's good to know -- thanks for reporting that.

I got this reply from the maintainer of module pata-via:

=========================================================================================================


My 133 MB/s PATA HDD is being configured for 33 MB/s due to incorrect
detection of a 40-wire cable.

You can force this (See Documentation)

Forcing it may be the easiest option.

Q1: Is this problem most likely a faulty cable (I don't currently have
a second cable to try a substitution), a BIOS bug, or a Linux bug?

It's probably some weird combination of things. The board seems to have
a real mix of devices and it's possible that in the case of a VIA PATA
> add on chip on an ATI chipset the rules are different somewhere.

Q2: What additional steps can I take to debug this problem?

Adding debug to drivers/ata/pata_via:via_cable_detect to see which path
it takes might be instructive. (I assume the disk is on the VIA
controller).

Cable clearly is ok as the BIOS detects both states properly.

================================================================================================================================

I would like to follow-up on his recommendation to my Q2, ie. add debug
to drivers/ata/pata_via:via_cable_detect. It is slightly beyond my
capabilities, but with help from this list, it is doable.

My guess is that I should add some printk statements to
via_cable_detect. (This outputs to /var/log/messages?).

Generally printk statements first go to the kernel ringbuffer which is available via 'dmesg' and usually in /var/log/dmesg as well.

Where do I get a makefile?

The various makefiles for the kernel are distributed with the kernel. The one you're looking for is probably in a sub-directory near where this source code is. However the kernel also needs configuration, as what these makefiles actually do varies with the configuration AFAIK.

> Here is the source for via_cable_detect:

/**
  *     via_cable_detect        -       cable detection
  *     @ap: ATA port
  *
  *     Perform cable detection. Actually for the VIA case the BIOS
  *     already did this for us. We read the values provided by the
  *     BIOS.

In the back of your mind keep in mind that sometimes the BIOS lies, which is why there is often a lot of discussion on LKML concerning actually testing for hardware rather than relying on the BIOS.

If you are using an 8235 in a non-PC configuration you
  *     may need to update this code.
  *
  *     Hotplug also impacts on this.
  */

static int via_cable_detect(struct ata_port *ap) {
        const struct via_isa_bridge *config = ap->host->private_data;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u32 ata66;

        if (via_cable_override(pdev))
                return ATA_CBL_PATA40_SHORT;

        if ((config->flags&  VIA_SATA_PATA)&&  ap->port_no == 0)
                return ATA_CBL_SATA;

        /* Early chips are 40 wire */
        if (config->udma_mask<  ATA_UDMA4)
                return ATA_CBL_PATA40;

I think right might be where the 40-pin cable misdetection is happening, which from the comment of what this does sounds like it's dependent on VIA chip version, which seems to be detected elsewhere. Right at this point it could help you debug if you output what the udma_mask is. Might also be interesting to find where the via_isa_bridge->udma_mask struct member gets set.

Note that I think the actual test is: (config->udma_mask < ATA_UDMA4) i.e. it's a "is it less than" test. The -> means dereferencing a struct that was passed in as an address. Off the top of my head I don't know what the actual underlying data types these parameters are.

Another thing you could try here would be to hard-code what you wanted to be returned knowing your own hardware.

        /* UDMA 66 chips have only drive side logic */
        else if (config->udma_mask<  ATA_UDMA5)
                return ATA_CBL_PATA_UNK;
        /* UDMA 100 or later */
        pci_read_config_dword(pdev, 0x50,&ata66);
        /* Check both the drive cable reporting bits, we might not have
           two drives */
        if (ata66&  (0x10100000>>  (16 * ap->port_no)))
                return ATA_CBL_PATA80;
        /* Check with ACPI so we can spot BIOS reported SATA bridges */
        if (ata_acpi_init_gtm(ap)&&
        ata_acpi_cbl_80wire(ap, ata_acpi_init_gtm(ap)))
                return ATA_CBL_PATA80;
        return ATA_CBL_PATA40;

Also note this last line above: it means that the DEFAULT if all of the other tests fall through is to return ATA_CBL_PATA40. Right at this point you could also try hard-coding what you wanted returned instead to change the "undetected" default.



Now, when it comes to actually BUILDING the code for this, if this is not a separate module then it means building the entire kernel after you've made alterations to the source. That isn't as horrible as it sounds; if you get the source via git then you can make your own branch, make some changes and commit them to that branch, and thus at any point you can go back to the mainline stable by checking out "master" and getting back to your own version via checking out your branch again.

If it /is/ something that can be built as a module, then it's possible to only build the one module -- but to be perfectly honest I'm not as familiar with how to do that.

--
  -- Chris

--
Chris Knadle
[email protected]
_______________________________________________
Mid-Hudson Valley Linux Users Group                  http://mhvlug.org
http://mhvlug.org/cgi-bin/mailman/listinfo/mhvlug

Upcoming Meetings (6pm - 8pm)                         MHVLS Auditorium
 Apr 6 - Introduction to IPv6
 May 4 - Inkscape
 Jun 1 - Zimbra

Reply via email to