Blame view
drivers/ata/pata_hpt3x3.c
7.13 KB
669a5db41 [libata] Add a bu... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* * pata_hpt3x3 - HPT3x3 driver * (c) Copyright 2005-2006 Red Hat * * Was pata_hpt34x but the naming was confusing as it supported the * 343 and 363 so it has been renamed. * * Based on: * linux/drivers/ide/pci/hpt34x.c Version 0.40 Sept 10, 2002 * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * * May be copied or modified under the terms of the GNU General Public * License */ |
85cd7251b [libata #pata-dri... |
15 |
|
669a5db41 [libata] Add a bu... |
16 17 18 |
#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> |
669a5db41 [libata] Add a bu... |
19 20 21 22 23 24 |
#include <linux/blkdev.h> #include <linux/delay.h> #include <scsi/scsi_host.h> #include <linux/libata.h> #define DRV_NAME "pata_hpt3x3" |
978ff6db2 pata_hpt3x3: Work... |
25 |
#define DRV_VERSION "0.6.1" |
669a5db41 [libata] Add a bu... |
26 |
|
669a5db41 [libata] Add a bu... |
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
/** * hpt3x3_set_piomode - PIO setup * @ap: ATA interface * @adev: device on the interface * * Set our PIO requirements. This is fairly simple on the HPT3x3 as * all we have to do is clear the MWDMA and UDMA bits then load the * mode number. */ static void hpt3x3_set_piomode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 r1, r2; int dn = 2 * ap->port_no + adev->devno; pci_read_config_dword(pdev, 0x44, &r1); pci_read_config_dword(pdev, 0x48, &r2); /* Load the PIO timing number */ r1 &= ~(7 << (3 * dn)); r1 |= (adev->pio_mode - XFER_PIO_0) << (3 * dn); r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ pci_write_config_dword(pdev, 0x44, r1); pci_write_config_dword(pdev, 0x48, r2); } |
790956e7b pata_hpt3x3: fix ... |
53 |
#if defined(CONFIG_PATA_HPT3X3_DMA) |
669a5db41 [libata] Add a bu... |
54 55 56 57 58 59 60 |
/** * hpt3x3_set_dmamode - DMA timing setup * @ap: ATA interface * @adev: Device being configured * * Set up the channel for MWDMA or UDMA modes. Much the same as with * PIO, load the mode number and then set MWDMA or UDMA flag. |
66e7da4e3 pata_hpt3x3: majo... |
61 62 63 |
* * 0x44 : bit 0-2 master mode, 3-5 slave mode, etc * 0x48 : bit 4/0 DMA/UDMA bit 5/1 for slave etc |
669a5db41 [libata] Add a bu... |
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
*/ static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 r1, r2; int dn = 2 * ap->port_no + adev->devno; int mode_num = adev->dma_mode & 0x0F; pci_read_config_dword(pdev, 0x44, &r1); pci_read_config_dword(pdev, 0x48, &r2); /* Load the timing number */ r1 &= ~(7 << (3 * dn)); r1 |= (mode_num << (3 * dn)); r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */ if (adev->dma_mode >= XFER_UDMA_0) |
978ff6db2 pata_hpt3x3: Work... |
81 |
r2 |= (0x01 << dn); /* Ultra mode */ |
669a5db41 [libata] Add a bu... |
82 |
else |
978ff6db2 pata_hpt3x3: Work... |
83 |
r2 |= (0x10 << dn); /* MWDMA */ |
669a5db41 [libata] Add a bu... |
84 85 86 87 |
pci_write_config_dword(pdev, 0x44, r1); pci_write_config_dword(pdev, 0x48, r2); } |
978ff6db2 pata_hpt3x3: Work... |
88 89 90 91 92 93 94 95 |
/** * hpt3x3_freeze - DMA workaround * @ap: port to freeze * * When freezing an HPT3x3 we must stop any pending DMA before * writing to the control register or the chip will hang */ |
b63d39532 [libata] pata_hpt... |
96 |
static void hpt3x3_freeze(struct ata_port *ap) |
978ff6db2 pata_hpt3x3: Work... |
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
{ void __iomem *mmio = ap->ioaddr.bmdma_addr; iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ ATA_DMA_START, mmio + ATA_DMA_CMD); ata_sff_dma_pause(ap); ata_sff_freeze(ap); } /** * hpt3x3_bmdma_setup - DMA workaround * @qc: Queued command * * When issuing BMDMA we must clean up the error/active bits in * software on this device */ static void hpt3x3_bmdma_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; u8 r = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); r |= ATA_DMA_INTR | ATA_DMA_ERR; iowrite8(r, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); return ata_bmdma_setup(qc); } |
669a5db41 [libata] Add a bu... |
122 |
|
66e7da4e3 pata_hpt3x3: majo... |
123 124 125 126 127 128 129 130 131 132 133 |
/** * hpt3x3_atapi_dma - ATAPI DMA check * @qc: Queued command * * Just say no - we don't do ATAPI DMA */ static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc) { return 1; } |
978ff6db2 pata_hpt3x3: Work... |
134 |
#endif /* CONFIG_PATA_HPT3X3_DMA */ |
669a5db41 [libata] Add a bu... |
135 |
static struct scsi_host_template hpt3x3_sht = { |
68d1d07b5 libata: implement... |
136 |
ATA_BMDMA_SHT(DRV_NAME), |
669a5db41 [libata] Add a bu... |
137 138 139 |
}; static struct ata_port_operations hpt3x3_port_ops = { |
029cfd6b7 libata: implement... |
140 |
.inherits = &ata_bmdma_port_ops, |
029cfd6b7 libata: implement... |
141 |
.cable_detect = ata_cable_40wire, |
669a5db41 [libata] Add a bu... |
142 |
.set_piomode = hpt3x3_set_piomode, |
790956e7b pata_hpt3x3: fix ... |
143 144 |
#if defined(CONFIG_PATA_HPT3X3_DMA) .set_dmamode = hpt3x3_set_dmamode, |
978ff6db2 pata_hpt3x3: Work... |
145 146 147 |
.bmdma_setup = hpt3x3_bmdma_setup, .check_atapi_dma= hpt3x3_atapi_dma, .freeze = hpt3x3_freeze, |
790956e7b pata_hpt3x3: fix ... |
148 |
#endif |
4fca377f7 [libata] trivial:... |
149 |
|
669a5db41 [libata] Add a bu... |
150 151 152 |
}; /** |
aff0df059 [PATCH] pata_hpt3... |
153 154 155 156 157 |
* hpt3x3_init_chipset - chip setup * @dev: PCI device * * Perform the setup required at boot and on resume. */ |
f20b16ff7 [libata] trim tra... |
158 |
|
aff0df059 [PATCH] pata_hpt3... |
159 160 161 162 163 164 165 166 167 168 169 170 |
static void hpt3x3_init_chipset(struct pci_dev *dev) { u16 cmd; /* Initialize the board */ pci_write_config_word(dev, 0x80, 0x00); /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */ pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & PCI_COMMAND_MEMORY) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); else pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); } |
aff0df059 [PATCH] pata_hpt3... |
171 |
/** |
669a5db41 [libata] Add a bu... |
172 |
* hpt3x3_init_one - Initialise an HPT343/363 |
66e7da4e3 pata_hpt3x3: majo... |
173 |
* @pdev: PCI device |
669a5db41 [libata] Add a bu... |
174 175 |
* @id: Entry in match table * |
66e7da4e3 pata_hpt3x3: majo... |
176 |
* Perform basic initialisation. We set the device up so we access all |
3ad2f3fbb tree-wide: Assort... |
177 |
* ports via BAR4. This is necessary to work around errata. |
669a5db41 [libata] Add a bu... |
178 |
*/ |
66e7da4e3 pata_hpt3x3: majo... |
179 |
static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
669a5db41 [libata] Add a bu... |
180 |
{ |
1626aeb88 libata: clean up ... |
181 |
static const struct ata_port_info info = { |
1d2808fd3 [libata] PATA dri... |
182 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
183 |
.pio_mask = ATA_PIO4, |
66e7da4e3 pata_hpt3x3: majo... |
184 185 |
#if defined(CONFIG_PATA_HPT3X3_DMA) /* Further debug needed */ |
14bdef982 [libata] convert ... |
186 187 |
.mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, |
66e7da4e3 pata_hpt3x3: majo... |
188 |
#endif |
669a5db41 [libata] Add a bu... |
189 190 |
.port_ops = &hpt3x3_port_ops }; |
66e7da4e3 pata_hpt3x3: majo... |
191 192 193 |
/* Register offsets of taskfiles in BAR4 area */ static const u8 offset_cmd[2] = { 0x20, 0x28 }; static const u8 offset_ctl[2] = { 0x36, 0x3E }; |
1626aeb88 libata: clean up ... |
194 |
const struct ata_port_info *ppi[] = { &info, NULL }; |
66e7da4e3 pata_hpt3x3: majo... |
195 196 197 198 199 |
struct ata_host *host; int i, rc; void __iomem *base; hpt3x3_init_chipset(pdev); |
06296a1e6 ata: Add and use ... |
200 |
ata_print_version_once(&pdev->dev, DRV_VERSION); |
66e7da4e3 pata_hpt3x3: majo... |
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); if (!host) return -ENOMEM; /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; /* Everything is relative to BAR4 if we set up this way */ rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) return rc; host->iomap = pcim_iomap_table(pdev); |
b5e555561 libata: switch re... |
217 |
rc = dma_set_mask_and_coherent(&pdev->dev, ATA_DMA_MASK); |
66e7da4e3 pata_hpt3x3: majo... |
218 219 220 221 222 223 |
if (rc) return rc; base = host->iomap[4]; /* Bus mastering base */ for (i = 0; i < host->n_ports; i++) { |
cbcdd8759 libata: implement... |
224 225 |
struct ata_port *ap = host->ports[i]; struct ata_ioports *ioaddr = &ap->ioaddr; |
66e7da4e3 pata_hpt3x3: majo... |
226 227 228 229 230 |
ioaddr->cmd_addr = base + offset_cmd[i]; ioaddr->altstatus_addr = ioaddr->ctl_addr = base + offset_ctl[i]; ioaddr->scr_addr = NULL; |
9363c3825 libata: rename SF... |
231 |
ata_sff_std_ports(ioaddr); |
66e7da4e3 pata_hpt3x3: majo... |
232 |
ioaddr->bmdma_addr = base + 8 * i; |
cbcdd8759 libata: implement... |
233 234 235 |
ata_port_pbar_desc(ap, 4, -1, "ioport"); ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd"); |
66e7da4e3 pata_hpt3x3: majo... |
236 237 |
} pci_set_master(pdev); |
c3b288942 libata-sff: separ... |
238 |
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
9363c3825 libata: rename SF... |
239 |
IRQF_SHARED, &hpt3x3_sht); |
669a5db41 [libata] Add a bu... |
240 |
} |
58eb8cd56 ata: use CONFIG_P... |
241 |
#ifdef CONFIG_PM_SLEEP |
aff0df059 [PATCH] pata_hpt3... |
242 243 |
static int hpt3x3_reinit_one(struct pci_dev *dev) { |
0a86e1c85 ata: use pci_get_... |
244 |
struct ata_host *host = pci_get_drvdata(dev); |
391504446 pata_hpt3x3: Powe... |
245 246 247 248 249 |
int rc; rc = ata_pci_device_do_resume(dev); if (rc) return rc; |
aff0df059 [PATCH] pata_hpt3... |
250 |
hpt3x3_init_chipset(dev); |
391504446 pata_hpt3x3: Powe... |
251 252 253 |
ata_host_resume(host); return 0; |
aff0df059 [PATCH] pata_hpt3... |
254 |
} |
438ac6d5e libata: add missi... |
255 |
#endif |
aff0df059 [PATCH] pata_hpt3... |
256 |
|
2d2744fc8 [libata] PCI ID t... |
257 258 259 260 |
static const struct pci_device_id hpt3x3[] = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), }, { }, |
669a5db41 [libata] Add a bu... |
261 262 263 |
}; static struct pci_driver hpt3x3_pci_driver = { |
2d2744fc8 [libata] PCI ID t... |
264 |
.name = DRV_NAME, |
669a5db41 [libata] Add a bu... |
265 266 |
.id_table = hpt3x3, .probe = hpt3x3_init_one, |
aff0df059 [PATCH] pata_hpt3... |
267 |
.remove = ata_pci_remove_one, |
58eb8cd56 ata: use CONFIG_P... |
268 |
#ifdef CONFIG_PM_SLEEP |
aff0df059 [PATCH] pata_hpt3... |
269 270 |
.suspend = ata_pci_device_suspend, .resume = hpt3x3_reinit_one, |
438ac6d5e libata: add missi... |
271 |
#endif |
669a5db41 [libata] Add a bu... |
272 |
}; |
2fc75da0c ata: use module_p... |
273 |
module_pci_driver(hpt3x3_pci_driver); |
669a5db41 [libata] Add a bu... |
274 275 276 277 278 279 |
MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for the Highpoint HPT343/363"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, hpt3x3); MODULE_VERSION(DRV_VERSION); |