Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=28e21c8c0d44cd63bad4c62f94ef0c5a1cb8402c
Commit:     28e21c8c0d44cd63bad4c62f94ef0c5a1cb8402c
Parent:     bd1d5ec64fff579e624b7c50c8a737da112efe5f
Author:     Alan Cox <[EMAIL PROTECTED]>
AuthorDate: Thu Apr 26 00:19:25 2007 -0700
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Sat Apr 28 15:16:39 2007 -0400

    pata_hpt3x2n: Add HPT371N support and other bits
    
    Yes its no longer 3x2n but 3xxn, I can rename it if you want Jeff
    
    - Don't reset both ports each time (Sergei)
    - If we can't get a DPLL then abort entirely
    - Use ioport access for clock (from drivers/ide)
    - Add HPT371N support (from drivers/ide)
    
    Signed-off-by: Alan Cox <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/ata/pata_hpt3x2n.c |   45 +++++++++++++++++++++++++++++++++++++------
 1 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 7832392..6a34521 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -8,10 +8,10 @@
  * Copyright (C) 1999-2003             Andre Hedrick <[EMAIL PROTECTED]>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
+ * Portions Copyright (C) 2005-2006    MontaVista Software, Inc.
  *
  *
  * TODO
- *     371N
  *     Work out best PLL policy
  */
 
@@ -142,6 +142,7 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)
 /**
  *     hpt3x2n_pre_reset       -       reset the hpt3x2n bus
  *     @ap: ATA port to reset
+ *     @deadline: deadline jiffies for the operation
  *
  *     Perform the initial reset handling for the 3x2n series controllers.
  *     Reset the hardware and state machine,
@@ -151,8 +152,7 @@ static int hpt3xn_pre_reset(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        /* Reset the state machine */
-       pci_write_config_byte(pdev, 0x50, 0x37);
-       pci_write_config_byte(pdev, 0x54, 0x37);
+       pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
        udelay(100);
        return ata_std_prereset(ap);
 }
@@ -433,8 +433,9 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
 {
        unsigned long freq;
        u32 fcnt;
+       unsigned long iobase = pci_resource_start(pdev, 4);
 
-       pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt);
+       fcnt = inl(iobase + 0x90);      /* Not PCI readable for some chips */
        if ((fcnt >> 12) != 0xABCDE) {
                printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n");
                return 33;      /* Not BIOS set */
@@ -503,6 +504,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const 
struct pci_device_id *id)
        unsigned int pci_mhz;
        unsigned int f_low, f_high;
        int adjust;
+       unsigned long iobase = pci_resource_start(dev, 4);
 
        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
        class_rev &= 0xFF;
@@ -512,6 +514,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const 
struct pci_device_id *id)
                        if (class_rev < 6)
                                return -ENODEV;
                        break;
+               case PCI_DEVICE_ID_TTI_HPT371:
+                       if (class_rev < 2)
+                               return -ENODEV;
+                       /* 371N if rev > 1 */
+                       break;
                case PCI_DEVICE_ID_TTI_HPT372:
                        /* 372N if rev >= 1*/
                        if (class_rev == 0)
@@ -539,6 +546,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const 
struct pci_device_id *id)
        irqmask &= ~0x10;
        pci_write_config_byte(dev, 0x5a, irqmask);
 
+       /*
+        * HPT371 chips physically have only one channel, the secondary one,
+        * but the primary channel registers do exist!  Go figure...
+        * So,  we manually disable the non-existing channel here
+        * (if the BIOS hasn't done this already).
+        */
+       if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
+               u8 mcr1;
+               pci_read_config_byte(dev, 0x50, &mcr1);
+               mcr1 &= ~0x04;
+               pci_write_config_byte(dev, 0x50, mcr1);
+       }
+
        /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or
           50 for UDMA100. Right now we always use 66 */
 
@@ -557,14 +577,24 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const 
struct pci_device_id *id)
                        break;
                pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
        }
-       if (adjust == 8)
-               printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n");
+       if (adjust == 8) {
+               printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n");
+               return -ENODEV;
+       }
 
        /* Set our private data up. We only need a few flags so we use
           it directly */
        port->private_data = NULL;
-       if (pci_mhz > 60)
+       if (pci_mhz > 60) {
                port->private_data = (void *)PCI66;
+               /*
+                * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
+                * the MISC. register to stretch the UltraDMA Tss timing.
+                * NOTE: This register is only writeable via I/O space.
+                */
+               if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
+                       outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
+       }
 
        /* Now kick off ATA set up */
        port_info[0] = port_info[1] = port;
@@ -573,6 +603,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const 
struct pci_device_id *id)
 
 static const struct pci_device_id hpt3x2n[] = {
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to