Blame view
drivers/ata/pata_hpt3x3.c
7.39 KB
669a5db41
|
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
|
15 |
|
669a5db41
|
16 17 18 19 20 21 22 23 24 25 |
#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <scsi/scsi_host.h> #include <linux/libata.h> #define DRV_NAME "pata_hpt3x3" |
978ff6db2
|
26 |
#define DRV_VERSION "0.6.1" |
669a5db41
|
27 |
|
669a5db41
|
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 53 |
/** * 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
|
54 |
#if defined(CONFIG_PATA_HPT3X3_DMA) |
669a5db41
|
55 56 57 58 59 60 61 |
/** * 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
|
62 63 64 |
* * 0x44 : bit 0-2 master mode, 3-5 slave mode, etc * 0x48 : bit 4/0 DMA/UDMA bit 5/1 for slave etc |
669a5db41
|
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
*/ 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
|
82 |
r2 |= (0x01 << dn); /* Ultra mode */ |
669a5db41
|
83 |
else |
978ff6db2
|
84 |
r2 |= (0x10 << dn); /* MWDMA */ |
669a5db41
|
85 86 87 88 |
pci_write_config_dword(pdev, 0x44, r1); pci_write_config_dword(pdev, 0x48, r2); } |
978ff6db2
|
89 90 91 92 93 94 95 96 |
/** * 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
|
97 |
static void hpt3x3_freeze(struct ata_port *ap) |
978ff6db2
|
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
{ 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
|
123 |
|
66e7da4e3
|
124 125 126 127 128 129 130 131 132 133 134 |
/** * 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
|
135 |
#endif /* CONFIG_PATA_HPT3X3_DMA */ |
669a5db41
|
136 |
static struct scsi_host_template hpt3x3_sht = { |
68d1d07b5
|
137 |
ATA_BMDMA_SHT(DRV_NAME), |
669a5db41
|
138 139 140 |
}; static struct ata_port_operations hpt3x3_port_ops = { |
029cfd6b7
|
141 |
.inherits = &ata_bmdma_port_ops, |
029cfd6b7
|
142 |
.cable_detect = ata_cable_40wire, |
669a5db41
|
143 |
.set_piomode = hpt3x3_set_piomode, |
790956e7b
|
144 145 |
#if defined(CONFIG_PATA_HPT3X3_DMA) .set_dmamode = hpt3x3_set_dmamode, |
978ff6db2
|
146 147 148 |
.bmdma_setup = hpt3x3_bmdma_setup, .check_atapi_dma= hpt3x3_atapi_dma, .freeze = hpt3x3_freeze, |
790956e7b
|
149 |
#endif |
4fca377f7
|
150 |
|
669a5db41
|
151 152 153 |
}; /** |
aff0df059
|
154 155 156 157 158 |
* hpt3x3_init_chipset - chip setup * @dev: PCI device * * Perform the setup required at boot and on resume. */ |
f20b16ff7
|
159 |
|
aff0df059
|
160 161 162 163 164 165 166 167 168 169 170 171 |
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
|
172 |
/** |
669a5db41
|
173 |
* hpt3x3_init_one - Initialise an HPT343/363 |
66e7da4e3
|
174 |
* @pdev: PCI device |
669a5db41
|
175 176 |
* @id: Entry in match table * |
66e7da4e3
|
177 |
* Perform basic initialisation. We set the device up so we access all |
3ad2f3fbb
|
178 |
* ports via BAR4. This is necessary to work around errata. |
669a5db41
|
179 |
*/ |
66e7da4e3
|
180 |
static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
669a5db41
|
181 |
{ |
1626aeb88
|
182 |
static const struct ata_port_info info = { |
1d2808fd3
|
183 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982
|
184 |
.pio_mask = ATA_PIO4, |
66e7da4e3
|
185 186 |
#if defined(CONFIG_PATA_HPT3X3_DMA) /* Further debug needed */ |
14bdef982
|
187 188 |
.mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, |
66e7da4e3
|
189 |
#endif |
669a5db41
|
190 191 |
.port_ops = &hpt3x3_port_ops }; |
66e7da4e3
|
192 193 194 |
/* Register offsets of taskfiles in BAR4 area */ static const u8 offset_cmd[2] = { 0x20, 0x28 }; static const u8 offset_ctl[2] = { 0x36, 0x3E }; |
1626aeb88
|
195 |
const struct ata_port_info *ppi[] = { &info, NULL }; |
66e7da4e3
|
196 197 198 199 200 |
struct ata_host *host; int i, rc; void __iomem *base; hpt3x3_init_chipset(pdev); |
06296a1e6
|
201 |
ata_print_version_once(&pdev->dev, DRV_VERSION); |
66e7da4e3
|
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
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); rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) return rc; rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); if (rc) return rc; base = host->iomap[4]; /* Bus mastering base */ for (i = 0; i < host->n_ports; i++) { |
cbcdd8759
|
228 229 |
struct ata_port *ap = host->ports[i]; struct ata_ioports *ioaddr = &ap->ioaddr; |
66e7da4e3
|
230 231 232 233 234 |
ioaddr->cmd_addr = base + offset_cmd[i]; ioaddr->altstatus_addr = ioaddr->ctl_addr = base + offset_ctl[i]; ioaddr->scr_addr = NULL; |
9363c3825
|
235 |
ata_sff_std_ports(ioaddr); |
66e7da4e3
|
236 |
ioaddr->bmdma_addr = base + 8 * i; |
cbcdd8759
|
237 238 239 |
ata_port_pbar_desc(ap, 4, -1, "ioport"); ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd"); |
66e7da4e3
|
240 241 |
} pci_set_master(pdev); |
c3b288942
|
242 |
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
9363c3825
|
243 |
IRQF_SHARED, &hpt3x3_sht); |
669a5db41
|
244 |
} |
438ac6d5e
|
245 |
#ifdef CONFIG_PM |
aff0df059
|
246 247 |
static int hpt3x3_reinit_one(struct pci_dev *dev) { |
391504446
|
248 249 250 251 252 253 |
struct ata_host *host = dev_get_drvdata(&dev->dev); int rc; rc = ata_pci_device_do_resume(dev); if (rc) return rc; |
aff0df059
|
254 |
hpt3x3_init_chipset(dev); |
391504446
|
255 256 257 |
ata_host_resume(host); return 0; |
aff0df059
|
258 |
} |
438ac6d5e
|
259 |
#endif |
aff0df059
|
260 |
|
2d2744fc8
|
261 262 263 264 |
static const struct pci_device_id hpt3x3[] = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), }, { }, |
669a5db41
|
265 266 267 |
}; static struct pci_driver hpt3x3_pci_driver = { |
2d2744fc8
|
268 |
.name = DRV_NAME, |
669a5db41
|
269 270 |
.id_table = hpt3x3, .probe = hpt3x3_init_one, |
aff0df059
|
271 |
.remove = ata_pci_remove_one, |
438ac6d5e
|
272 |
#ifdef CONFIG_PM |
aff0df059
|
273 274 |
.suspend = ata_pci_device_suspend, .resume = hpt3x3_reinit_one, |
438ac6d5e
|
275 |
#endif |
669a5db41
|
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
}; static int __init hpt3x3_init(void) { return pci_register_driver(&hpt3x3_pci_driver); } static void __exit hpt3x3_exit(void) { pci_unregister_driver(&hpt3x3_pci_driver); } 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); module_init(hpt3x3_init); |
b63d39532
|
297 |
module_exit(hpt3x3_exit); |