diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-03-08 23:21:04 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-03-08 23:21:04 +0300 |
commit | 988addf82e4c03739375279de73929580a2d4a6a (patch) | |
tree | 989ae1cd4e264bbad80c65f04480486246e7b9f3 /drivers/ata/sata_via.c | |
parent | 004c1c7096659d352b83047a7593e91d8a30e3c5 (diff) | |
parent | 25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff) | |
download | linux-988addf82e4c03739375279de73929580a2d4a6a.tar.xz |
Merge branch 'origin' into devel-stable
Conflicts:
arch/arm/mach-mx2/devices.c
arch/arm/mach-mx2/devices.h
sound/soc/pxa/pxa-ssp.c
Diffstat (limited to 'drivers/ata/sata_via.c')
-rw-r--r-- | drivers/ata/sata_via.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 02efd9a83d26..08f65492cc81 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -40,11 +40,13 @@ #include <linux/blkdev.h> #include <linux/delay.h> #include <linux/device.h> +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> #include <linux/libata.h> #define DRV_NAME "sata_via" -#define DRV_VERSION "2.4" +#define DRV_VERSION "2.6" /* * vt8251 is different from other sata controllers of VIA. It has two @@ -80,6 +82,7 @@ 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); +static void vt6420_bmdma_start(struct ata_queued_cmd *qc); static int vt6421_pata_cable_detect(struct ata_port *ap); static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev); static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); @@ -121,6 +124,7 @@ static struct ata_port_operations vt6420_sata_ops = { .inherits = &svia_base_ops, .freeze = svia_noop_freeze, .prereset = vt6420_prereset, + .bmdma_start = vt6420_bmdma_start, }; static struct ata_port_operations vt6421_pata_ops = { @@ -377,6 +381,17 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline) return 0; } +static void vt6420_bmdma_start(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + if ((qc->tf.command == ATA_CMD_PACKET) && + (qc->scsicmd->sc_data_direction == DMA_TO_DEVICE)) { + /* Prevents corruption on some ATAPI burners */ + ata_sff_pause(ap); + } + ata_bmdma_start(qc); +} + static int vt6421_pata_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); @@ -392,14 +407,16 @@ static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 }; - pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]); + pci_write_config_byte(pdev, PATA_PIO_TIMING - adev->devno, + pio_bits[adev->pio_mode - XFER_PIO_0]); } static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 }; - pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->dma_mode - XFER_UDMA_0]); + pci_write_config_byte(pdev, PATA_UDMA_TIMING - adev->devno, + udma_bits[adev->dma_mode - XFER_UDMA_0]); } static const unsigned int svia_bar_sizes[] = { |