All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
To: Jeff Garzik <jeff@garzik.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
	akpm@osdl.org, linux-ide@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] pata_cmd640: CMD640 PCI support
Date: Sat, 03 Mar 2007 20:12:11 +0300	[thread overview]
Message-ID: <45E9AC6B.50701@ru.mvista.com> (raw)
In-Reply-To: <45E8B28D.7030500@garzik.org>

Hello.

Jeff Garzik wrote:

>> +    /* The second channel has shared timings and the setup timing is
>> +       messy to switch to merge it for worst case */
>> +    if (ap->port_no && pair) {
>> +        struct ata_timing p;
>> +        ata_timing_compute(pair, pair->pio_mode, &p, T, 1);
>> +        ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP);
>> +    }
>> +
>> +    /* Make the timings fit */
>> +    if (t.recover > 16) {
>> +        t.active += t.recover - 16;
>> +        t.recover = 16;
>> +    }

    This code makes perfect sense in any driver, BTW... but I'm not sure any 
other drivers have anything alike -- what they do seem to just clamp clock 
count at its maximum...

>> +    if (t.active > 16)
>> +        t.active = 16;

    Erm, clamping active time is not a right thing to do. Right thing to do 
was to bail out. I didn't do it in the legacy driver rewrite though...

>> +
>> +    /* Now convert the clocks into values we can actually stuff into
>> +       the chip */
>> +
>> +    if (t.recover > 1)
>> +        t.recover--;    /* 640B only */
>> +    else
>> +        t.recover = 15;
>> +
>> +    if (t.setup > 4)
>> +        t.setup = 0xC0;
>> +    else
>> +        t.setup = setup_data[t.setup];
>> +
>> +    if (ap->port_no == 0) {
>> +        t.active &= 0x0F;    /* 0 = 16 */
>> +
>> +        /* Load setup timing */
>> +        pci_read_config_byte(pdev, arttim, &reg);
>> +        reg &= 0x3F;
>> +        reg |= t.setup;
>> +        pci_write_config_byte(pdev, arttim, reg);
>> +
>> +        /* Load active/recovery */
>> +        pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | 
>> t.recover);
>> +    } else {
>> +        /* Save the shared timings for channel, they will be loaded
>> +           by qc_issue_prot. Reloading the setup time is expensive 
>> +           so we keep a merged one loaded */
>> +        pci_read_config_byte(pdev, ARTIM23, &reg);

    It's not even expensive, it may be just unsafe.

>> +        reg &= 0x3F;
>> +        reg |= t.setup;
>> +        pci_write_config_byte(pdev, ARTIM23, reg);
>> +        timing->reg58[adev->devno] = (t.active << 4) | t.recover;
>> +    }
>> +}

>> +static int cmd640_init_one(struct pci_dev *pdev, const struct 
>> pci_device_id *id)
>> +{
>> +    u8 r;
>> +    u8 ctrl;
>> +   
>> +    static struct ata_port_info info = {
>> +        .sht = &cmd640_sht,
>> +        .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
>> +        .pio_mask = 0x1f,

> I-dont-know-the-hardware question:  does this h/w have no DMA support?

    Exactly. :-) The legacy driver used to support PIO5 though.

>> +    static struct ata_port_info *port_info[2] = { &info, &info };
>> +
>> +    /* CMD640 detected, commiserations */
>> +    pci_write_config_byte(pdev, 0x5C, 0x00);

> magic number

   Indeed, completely undocumented. And I don't even see it in the legacy 
driver...

>> +    /* Get version info */
>> +    pci_read_config_byte(pdev, CFR, &r);
>> +    /* PIO0 command cycles */
>> +    pci_write_config_byte(pdev, CMDTIM, 0);
>> +    /* 512 byte bursts (sector) */
>> +    pci_write_config_byte(pdev, BRST, 0x40);
>> +    /* +     * A reporter a long time ago
>> +     * Had problems with the data fifo
>> +     * So don't run the risk
>> +     * Of putting crap on the disk
>> +     * For its better just to go slow
>> +     */
>> +    /* Do channel 0 */
>> +    pci_read_config_byte(pdev, CNTRL, &ctrl);
>> +    pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0);
>> +    /* Ditto for channel 1 */
>> +    pci_read_config_byte(pdev, ARTIM23, &ctrl);
>> +    ctrl |= 0x0C;
>> +    pci_write_config_byte(pdev, ARTIM23, ctrl);

    It's used to be a well known fact (soon after Intel put that chip on their 
motherboards :-) that PCI0640 may return bad data on command block reads if 
another channel has data port I/O going on. That's why the interrupts needed 
to be disabled during PIO in the legacy driver (and the channels serialized).

MBR, Sergei

  parent reply	other threads:[~2007-03-03 17:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-02 15:03 [PATCH] pata_cmd640: CMD640 PCI support Alan Cox
2007-03-02 23:26 ` Jeff Garzik
2007-03-03  0:52   ` Alan Cox
2007-03-03 17:12   ` Sergei Shtylyov [this message]
2007-03-03 20:33     ` Alan Cox
2007-03-03 19:38       ` Sergei Shtylyov

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=45E9AC6B.50701@ru.mvista.com \
    --to=sshtylyov@ru.mvista.com \
    --cc=akpm@osdl.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=jeff@garzik.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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.