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
This commit is contained in:
Linus Torvalds 2008-10-31 07:47:57 -07:00
commit f73aaf10ae
4 changed files with 152 additions and 16 deletions

View 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.

View 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.

View File

@ -44,11 +44,16 @@
#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);

View 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 */