Commit f73aaf10 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev

* '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
parents 721d5dfe 9ce8e307
...@@ -738,7 +738,6 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -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 * do_pata_set_dmamode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring * @ap: Port whose timings we are configuring
* @adev: Drive in question * @adev: Drive in question
* @udma: udma mode, 0 - 6
* @isich: set if the chip is an ICH device * @isich: set if the chip is an ICH device
* *
* Set UDMA mode for device, in host controller PCI config space. * Set UDMA mode for device, in host controller PCI config space.
......
...@@ -1268,7 +1268,7 @@ u64 ata_tf_to_lba48(const struct ata_taskfile *tf) ...@@ -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_lbah & 0xff)) << 40;
sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32; 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->lbah & 0xff) << 16;
sectors |= (tf->lbam & 0xff) << 8; sectors |= (tf->lbam & 0xff) << 8;
sectors |= (tf->lbal & 0xff); sectors |= (tf->lbal & 0xff);
...@@ -1602,7 +1602,6 @@ unsigned long ata_id_xfermask(const u16 *id) ...@@ -1602,7 +1602,6 @@ unsigned long ata_id_xfermask(const u16 *id)
/** /**
* ata_pio_queue_task - Queue port_task * ata_pio_queue_task - Queue port_task
* @ap: The ata_port to queue port_task for * @ap: The ata_port to queue port_task for
* @fn: workqueue function to be scheduled
* @data: data for @fn to use * @data: data for @fn to use
* @delay: delay time in msecs for workqueue function * @delay: delay time in msecs for workqueue function
* *
...@@ -2159,6 +2158,10 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -2159,6 +2158,10 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
static inline u8 ata_dev_knobble(struct ata_device *dev) static inline u8 ata_dev_knobble(struct ata_device *dev)
{ {
struct ata_port *ap = dev->link->ap; 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))); 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 [] = { ...@@ -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", "SB00", ATA_HORKAGE_IVB, },
{ "TSSTcorp CDDVDW SH-S202N", "SB01", 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 */ /* End Marker */
{ } { }
}; };
...@@ -4648,7 +4654,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) ...@@ -4648,7 +4654,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
/** /**
* ata_qc_complete - Complete an active ATA command * ata_qc_complete - Complete an active ATA command
* @qc: Command to complete * @qc: Command to complete
* @err_mask: ATA Status register contents
* *
* Indicate to the mid and upper layers that an ATA * Indicate to the mid and upper layers that an ATA
* command has completed, with either an ok or not-ok status. * command has completed, with either an ok or not-ok status.
......
...@@ -44,11 +44,16 @@ ...@@ -44,11 +44,16 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "sata_via" #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 { enum board_ids_enum {
vt6420, vt6420,
vt6421, vt6421,
vt8251,
}; };
enum { enum {
...@@ -70,6 +75,8 @@ enum { ...@@ -70,6 +75,8 @@ enum {
static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 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_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 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_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
static void svia_noop_freeze(struct ata_port *ap); static void svia_noop_freeze(struct ata_port *ap);
static int vt6420_prereset(struct ata_link *link, unsigned long deadline); 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); ...@@ -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[] = { static const struct pci_device_id svia_pci_tbl[] = {
{ PCI_VDEVICE(VIA, 0x5337), vt6420 }, { PCI_VDEVICE(VIA, 0x5337), vt6420 },
{ PCI_VDEVICE(VIA, 0x0591), vt6420 }, { PCI_VDEVICE(VIA, 0x0591), vt6420 }, /* 2 sata chnls (Master) */
{ PCI_VDEVICE(VIA, 0x3149), vt6420 }, { PCI_VDEVICE(VIA, 0x3149), vt6420 }, /* 2 sata chnls (Master) */
{ PCI_VDEVICE(VIA, 0x3249), vt6421 }, { PCI_VDEVICE(VIA, 0x3249), vt6421 }, /* 2 sata chnls, 1 pata chnl */
{ PCI_VDEVICE(VIA, 0x5287), vt6420 },
{ PCI_VDEVICE(VIA, 0x5372), vt6420 }, { PCI_VDEVICE(VIA, 0x5372), vt6420 },
{ PCI_VDEVICE(VIA, 0x7372), vt6420 }, { PCI_VDEVICE(VIA, 0x7372), vt6420 },
{ PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */
{ } /* terminate list */ { } /* terminate list */
}; };
...@@ -128,6 +135,13 @@ static struct ata_port_operations vt6421_sata_ops = { ...@@ -128,6 +135,13 @@ static struct ata_port_operations vt6421_sata_ops = {
.scr_write = svia_scr_write, .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 = { static const struct ata_port_info vt6420_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f, .pio_mask = 0x1f,
...@@ -152,6 +166,15 @@ static struct ata_port_info vt6421_pport_info = { ...@@ -152,6 +166,15 @@ static struct ata_port_info vt6421_pport_info = {
.port_ops = &vt6421_pata_ops, .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_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers"); MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -174,6 +197,83 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) ...@@ -174,6 +197,83 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
return 0; 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 * svia_tf_load - send taskfile registers to host controller
* @ap: Port to which output is sent * @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) ...@@ -396,6 +496,30 @@ static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
return 0; 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) static void svia_configure(struct pci_dev *pdev)
{ {
u8 tmp8; u8 tmp8;
...@@ -451,10 +575,10 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -451,10 +575,10 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) if (rc)
return rc; return rc;
if (board_id == vt6420) if (board_id == vt6421)
bar_sizes = &svia_bar_sizes[0];
else
bar_sizes = &vt6421_bar_sizes[0]; bar_sizes = &vt6421_bar_sizes[0];
else
bar_sizes = &svia_bar_sizes[0];
for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
if ((pci_resource_start(pdev, i) == 0) || 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) ...@@ -467,12 +591,19 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV; return -ENODEV;
} }
if (board_id == vt6420) switch (board_id) {
case vt6420:
rc = vt6420_prepare_host(pdev, &host); rc = vt6420_prepare_host(pdev, &host);
else break;
case vt6421:
rc = vt6421_prepare_host(pdev, &host); rc = vt6421_prepare_host(pdev, &host);
if (rc) break;
return rc; case vt8251:
rc = vt8251_prepare_host(pdev, &host);
break;
default:
return -EINVAL;
}
svia_configure(pdev); svia_configure(pdev);
......
...@@ -372,6 +372,7 @@ enum { ...@@ -372,6 +372,7 @@ enum {
ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */
ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */
ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ 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 /* DMA mask for user DMA control: User visible values; DO NOT
renumber */ renumber */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment