]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 Oct 2008 14:47:57 +0000 (07:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 Oct 2008 14:47:57 +0000 (07:47 -0700)
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  libata: add whitelist for devices with known good pata-sata bridges
  sata_via: fix support for 5287
  libata: Avoid overflow in ata_tf_to_lba48() when tf->hba_lbal > 127
  ATA: remove excess kernel-doc notation

drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/sata_via.c
include/linux/libata.h

index 52dc2d8b8f2217f8acad714409c005efed8f2d1d..8e37be19bbf520b1b8e9d8409d9874846ee868f4 100644 (file)
@@ -738,7 +738,6 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
  *     do_pata_set_dmamode - Initialize host controller PATA PIO timings
  *     @ap: Port whose timings we are configuring
  *     @adev: Drive in question
- *     @udma: udma mode, 0 - 6
  *     @isich: set if the chip is an ICH device
  *
  *     Set UDMA mode for device, in host controller PCI config space.
index 2ff633c119e23b5d9ac604dce9485169825123e3..82af7011f2ddd137e2a601ae95c704a4219ada9e 100644 (file)
@@ -1268,7 +1268,7 @@ u64 ata_tf_to_lba48(const struct ata_taskfile *tf)
 
        sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
        sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
-       sectors |= (tf->hob_lbal & 0xff) << 24;
+       sectors |= ((u64)(tf->hob_lbal & 0xff)) << 24;
        sectors |= (tf->lbah & 0xff) << 16;
        sectors |= (tf->lbam & 0xff) << 8;
        sectors |= (tf->lbal & 0xff);
@@ -1602,7 +1602,6 @@ unsigned long ata_id_xfermask(const u16 *id)
 /**
  *     ata_pio_queue_task - Queue port_task
  *     @ap: The ata_port to queue port_task for
- *     @fn: workqueue function to be scheduled
  *     @data: data for @fn to use
  *     @delay: delay time in msecs for workqueue function
  *
@@ -2159,6 +2158,10 @@ retry:
 static inline u8 ata_dev_knobble(struct ata_device *dev)
 {
        struct ata_port *ap = dev->link->ap;
+
+       if (ata_dev_blacklisted(dev) & ATA_HORKAGE_BRIDGE_OK)
+               return 0;
+
        return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
 }
 
@@ -4063,6 +4066,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "TSSTcorp CDDVDW SH-S202N", "SB00",     ATA_HORKAGE_IVB, },
        { "TSSTcorp CDDVDW SH-S202N", "SB01",     ATA_HORKAGE_IVB, },
 
+       /* Devices that do not need bridging limits applied */
+       { "MTRON MSP-SATA*",            NULL,   ATA_HORKAGE_BRIDGE_OK, },
+
        /* End Marker */
        { }
 };
@@ -4648,7 +4654,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
 /**
  *     ata_qc_complete - Complete an active ATA command
  *     @qc: Command to complete
- *     @err_mask: ATA Status register contents
  *
  *     Indicate to the mid and upper layers that an ATA
  *     command has completed, with either an ok or not-ok status.
index 5b72e734300a19ff9bbc5554c46e80cc7f5edde7..62367fe4d5dc2f6e9cf6d77c327f64eb8407ce12 100644 (file)
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_via"
-#define DRV_VERSION    "2.3"
+#define DRV_VERSION    "2.4"
 
+/*
+ * vt8251 is different from other sata controllers of VIA.  It has two
+ * channels, each channel has both Master and Slave slot.
+ */
 enum board_ids_enum {
        vt6420,
        vt6421,
+       vt8251,
 };
 
 enum {
@@ -70,6 +75,8 @@ enum {
 static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
 static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
+static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val);
+static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val);
 static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
 static void svia_noop_freeze(struct ata_port *ap);
 static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
@@ -79,12 +86,12 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
 
 static const struct pci_device_id svia_pci_tbl[] = {
        { PCI_VDEVICE(VIA, 0x5337), vt6420 },
-       { PCI_VDEVICE(VIA, 0x0591), vt6420 },
-       { PCI_VDEVICE(VIA, 0x3149), vt6420 },
-       { PCI_VDEVICE(VIA, 0x3249), vt6421 },
-       { PCI_VDEVICE(VIA, 0x5287), vt6420 },
+       { PCI_VDEVICE(VIA, 0x0591), vt6420 }, /* 2 sata chnls (Master) */
+       { PCI_VDEVICE(VIA, 0x3149), vt6420 }, /* 2 sata chnls (Master) */
+       { PCI_VDEVICE(VIA, 0x3249), vt6421 }, /* 2 sata chnls, 1 pata chnl */
        { PCI_VDEVICE(VIA, 0x5372), vt6420 },
        { PCI_VDEVICE(VIA, 0x7372), vt6420 },
+       { PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */
 
        { }     /* terminate list */
 };
@@ -128,6 +135,13 @@ static struct ata_port_operations vt6421_sata_ops = {
        .scr_write              = svia_scr_write,
 };
 
+static struct ata_port_operations vt8251_ops = {
+       .inherits               = &svia_base_ops,
+       .hardreset              = sata_std_hardreset,
+       .scr_read               = vt8251_scr_read,
+       .scr_write              = vt8251_scr_write,
+};
+
 static const struct ata_port_info vt6420_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
@@ -152,6 +166,15 @@ static struct ata_port_info vt6421_pport_info = {
        .port_ops       = &vt6421_pata_ops,
 };
 
+static struct ata_port_info vt8251_port_info = {
+       .flags          = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS |
+                         ATA_FLAG_NO_LEGACY,
+       .pio_mask       = 0x1f,
+       .mwdma_mask     = 0x07,
+       .udma_mask      = ATA_UDMA6,
+       .port_ops       = &vt8251_ops,
+};
+
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
 MODULE_LICENSE("GPL");
@@ -174,6 +197,83 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
        return 0;
 }
 
+static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
+{
+       static const u8 ipm_tbl[] = { 1, 2, 6, 0 };
+       struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+       int slot = 2 * link->ap->port_no + link->pmp;
+       u32 v = 0;
+       u8 raw;
+
+       switch (scr) {
+       case SCR_STATUS:
+               pci_read_config_byte(pdev, 0xA0 + slot, &raw);
+
+               /* read the DET field, bit0 and 1 of the config byte */
+               v |= raw & 0x03;
+
+               /* read the SPD field, bit4 of the configure byte */
+               if (raw & (1 << 4))
+                       v |= 0x02 << 4;
+               else
+                       v |= 0x01 << 4;
+
+               /* read the IPM field, bit2 and 3 of the config byte */
+               v |= ipm_tbl[(raw >> 2) & 0x3];
+               break;
+
+       case SCR_ERROR:
+               /* devices other than 5287 uses 0xA8 as base */
+               WARN_ON(pdev->device != 0x5287);
+               pci_read_config_dword(pdev, 0xB0 + slot * 4, &v);
+               break;
+
+       case SCR_CONTROL:
+               pci_read_config_byte(pdev, 0xA4 + slot, &raw);
+
+               /* read the DET field, bit0 and bit1 */
+               v |= ((raw & 0x02) << 1) | (raw & 0x01);
+
+               /* read the IPM field, bit2 and bit3 */
+               v |= ((raw >> 2) & 0x03) << 8;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       *val = v;
+       return 0;
+}
+
+static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val)
+{
+       struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+       int slot = 2 * link->ap->port_no + link->pmp;
+       u32 v = 0;
+
+       switch (scr) {
+       case SCR_ERROR:
+               /* devices other than 5287 uses 0xA8 as base */
+               WARN_ON(pdev->device != 0x5287);
+               pci_write_config_dword(pdev, 0xB0 + slot * 4, val);
+               return 0;
+
+       case SCR_CONTROL:
+               /* set the DET field */
+               v |= ((val & 0x4) >> 1) | (val & 0x1);
+
+               /* set the IPM field */
+               v |= ((val >> 8) & 0x3) << 2;
+
+               pci_write_config_byte(pdev, 0xA4 + slot, v);
+               return 0;
+
+       default:
+               return -EINVAL;
+       }
+}
+
 /**
  *     svia_tf_load - send taskfile registers to host controller
  *     @ap: Port to which output is sent
@@ -396,6 +496,30 @@ static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        return 0;
 }
 
+static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
+{
+       const struct ata_port_info *ppi[] = { &vt8251_port_info, NULL };
+       struct ata_host *host;
+       int i, rc;
+
+       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       if (rc)
+               return rc;
+       *r_host = host;
+
+       rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+       if (rc) {
+               dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n");
+               return rc;
+       }
+
+       /* 8251 hosts four sata ports as M/S of the two channels */
+       for (i = 0; i < host->n_ports; i++)
+               ata_slave_link_init(host->ports[i]);
+
+       return 0;
+}
+
 static void svia_configure(struct pci_dev *pdev)
 {
        u8 tmp8;
@@ -451,10 +575,10 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       if (board_id == vt6420)
-               bar_sizes = &svia_bar_sizes[0];
-       else
+       if (board_id == vt6421)
                bar_sizes = &vt6421_bar_sizes[0];
+       else
+               bar_sizes = &svia_bar_sizes[0];
 
        for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
                if ((pci_resource_start(pdev, i) == 0) ||
@@ -467,12 +591,19 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                        return -ENODEV;
                }
 
-       if (board_id == vt6420)
+       switch (board_id) {
+       case vt6420:
                rc = vt6420_prepare_host(pdev, &host);
-       else
+               break;
+       case vt6421:
                rc = vt6421_prepare_host(pdev, &host);
-       if (rc)
-               return rc;
+               break;
+       case vt8251:
+               rc = vt8251_prepare_host(pdev, &host);
+               break;
+       default:
+               return -EINVAL;
+       }
 
        svia_configure(pdev);
 
index 507f53ef8038a7a7ffcbc8fb8a9655055553ec4c..f5441edee55f647be39b6432edb30f83bc81bb13 100644 (file)
@@ -372,6 +372,7 @@ enum {
        ATA_HORKAGE_IPM         = (1 << 7),     /* Link PM problems */
        ATA_HORKAGE_IVB         = (1 << 8),     /* cbl det validity bit bugs */
        ATA_HORKAGE_STUCK_ERR   = (1 << 9),     /* stuck ERR on next PACKET */
+       ATA_HORKAGE_BRIDGE_OK   = (1 << 10),    /* no bridge limits */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */