aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_hpt3x3.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-01-09 03:39:43 -0500
committerLen Brown <len.brown@intel.com>2009-01-09 03:39:43 -0500
commitb2576e1d4408e134e2188c967b1f28af39cd79d4 (patch)
tree004f3c82faab760f304ce031d6d2f572e7746a50 /drivers/ata/pata_hpt3x3.c
parent3cc8a5f4ba91f67bbdb81a43a99281a26aab8d77 (diff)
parent2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (diff)
Merge branch 'linus' into release
Diffstat (limited to 'drivers/ata/pata_hpt3x3.c')
-rw-r--r--drivers/ata/pata_hpt3x3.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index f11a320337c0..f19cc645881a 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -23,7 +23,7 @@
23#include <linux/libata.h> 23#include <linux/libata.h>
24 24
25#define DRV_NAME "pata_hpt3x3" 25#define DRV_NAME "pata_hpt3x3"
26#define DRV_VERSION "0.5.3" 26#define DRV_VERSION "0.6.1"
27 27
28/** 28/**
29 * hpt3x3_set_piomode - PIO setup 29 * hpt3x3_set_piomode - PIO setup
@@ -80,14 +80,48 @@ static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
80 r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ 80 r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */
81 81
82 if (adev->dma_mode >= XFER_UDMA_0) 82 if (adev->dma_mode >= XFER_UDMA_0)
83 r2 |= (0x10 << dn); /* Ultra mode */ 83 r2 |= (0x01 << dn); /* Ultra mode */
84 else 84 else
85 r2 |= (0x01 << dn); /* MWDMA */ 85 r2 |= (0x10 << dn); /* MWDMA */
86 86
87 pci_write_config_dword(pdev, 0x44, r1); 87 pci_write_config_dword(pdev, 0x44, r1);
88 pci_write_config_dword(pdev, 0x48, r2); 88 pci_write_config_dword(pdev, 0x48, r2);
89} 89}
90#endif /* CONFIG_PATA_HPT3X3_DMA */ 90
91/**
92 * hpt3x3_freeze - DMA workaround
93 * @ap: port to freeze
94 *
95 * When freezing an HPT3x3 we must stop any pending DMA before
96 * writing to the control register or the chip will hang
97 */
98
99static void hpt3x3_freeze(struct ata_port *ap)
100{
101 void __iomem *mmio = ap->ioaddr.bmdma_addr;
102
103 iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ ATA_DMA_START,
104 mmio + ATA_DMA_CMD);
105 ata_sff_dma_pause(ap);
106 ata_sff_freeze(ap);
107}
108
109/**
110 * hpt3x3_bmdma_setup - DMA workaround
111 * @qc: Queued command
112 *
113 * When issuing BMDMA we must clean up the error/active bits in
114 * software on this device
115 */
116
117static void hpt3x3_bmdma_setup(struct ata_queued_cmd *qc)
118{
119 struct ata_port *ap = qc->ap;
120 u8 r = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
121 r |= ATA_DMA_INTR | ATA_DMA_ERR;
122 iowrite8(r, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
123 return ata_bmdma_setup(qc);
124}
91 125
92/** 126/**
93 * hpt3x3_atapi_dma - ATAPI DMA check 127 * hpt3x3_atapi_dma - ATAPI DMA check
@@ -101,18 +135,23 @@ static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc)
101 return 1; 135 return 1;
102} 136}
103 137
138#endif /* CONFIG_PATA_HPT3X3_DMA */
139
104static struct scsi_host_template hpt3x3_sht = { 140static struct scsi_host_template hpt3x3_sht = {
105 ATA_BMDMA_SHT(DRV_NAME), 141 ATA_BMDMA_SHT(DRV_NAME),
106}; 142};
107 143
108static struct ata_port_operations hpt3x3_port_ops = { 144static struct ata_port_operations hpt3x3_port_ops = {
109 .inherits = &ata_bmdma_port_ops, 145 .inherits = &ata_bmdma_port_ops,
110 .check_atapi_dma= hpt3x3_atapi_dma,
111 .cable_detect = ata_cable_40wire, 146 .cable_detect = ata_cable_40wire,
112 .set_piomode = hpt3x3_set_piomode, 147 .set_piomode = hpt3x3_set_piomode,
113#if defined(CONFIG_PATA_HPT3X3_DMA) 148#if defined(CONFIG_PATA_HPT3X3_DMA)
114 .set_dmamode = hpt3x3_set_dmamode, 149 .set_dmamode = hpt3x3_set_dmamode,
150 .bmdma_setup = hpt3x3_bmdma_setup,
151 .check_atapi_dma= hpt3x3_atapi_dma,
152 .freeze = hpt3x3_freeze,
115#endif 153#endif
154
116}; 155};
117 156
118/** 157/**