Blame view
drivers/ata/sata_sis.c
8.18 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 |
/* * sata_sis.c - Silicon Integrated Systems SATA * * Maintained by: Uwe Koziolek * Please ALWAYS copy linux-ide@vger.kernel.org * on emails. * * Copyright 2004 Uwe Koziolek * |
af36d7f0d [libata] license ... |
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * * libata documentation is available via 'make {ps|pdf}docs', * as Documentation/DocBook/libata.* * * Hardware documentation available under NDA. |
1da177e4c Linux-2.6.12-rc2 |
30 31 |
* */ |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 |
#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 <linux/interrupt.h> |
a9524a76f [libata] use dev_... |
39 |
#include <linux/device.h> |
1da177e4c Linux-2.6.12-rc2 |
40 41 |
#include <scsi/scsi_host.h> #include <linux/libata.h> |
4bb64fb98 SiS warning fixes |
42 |
#include "sis.h" |
1da177e4c Linux-2.6.12-rc2 |
43 44 |
#define DRV_NAME "sata_sis" |
2a3103ce4 [libata] Bump dri... |
45 |
#define DRV_VERSION "1.0" |
1da177e4c Linux-2.6.12-rc2 |
46 47 48 49 50 51 52 53 |
enum { sis_180 = 0, SIS_SCR_PCI_BAR = 5, /* PCI configuration registers */ SIS_GENCTL = 0x54, /* IDE General Control register */ SIS_SCR_BASE = 0xc0, /* sata0 phy SCR registers */ |
f2c853bca [PATCH] sata_sis:... |
54 55 56 |
SIS180_SATA1_OFS = 0x10, /* offset from sata0->sata1 phy regs */ SIS182_SATA1_OFS = 0x20, /* offset from sata0->sata1 phy regs */ SIS_PMR = 0x90, /* port mapping register */ |
8add78857 [libata] minor fixes |
57 |
SIS_PMR_COMBINED = 0x30, |
1da177e4c Linux-2.6.12-rc2 |
58 59 60 61 62 63 |
/* random bits */ SIS_FLAG_CFGSCR = (1 << 30), /* host flag: SCRs via PCI cfg */ GENCTL_IOMAPPED_SCR = (1 << 26), /* if set, SCRs are in IO space */ }; |
5796d1c4c [libata] Address ... |
64 |
static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
82ef04fb4 libata: make SCR ... |
65 66 |
static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
1da177e4c Linux-2.6.12-rc2 |
67 |
|
3b7d697df [libata] constify... |
68 |
static const struct pci_device_id sis_pci_tbl[] = { |
5796d1c4c [libata] Address ... |
69 70 71 72 73 74 |
{ PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ { PCI_VDEVICE(SI, 0x0181), sis_180 }, /* SiS 964/180 */ { PCI_VDEVICE(SI, 0x0182), sis_180 }, /* SiS 965/965L */ { PCI_VDEVICE(SI, 0x0183), sis_180 }, /* SiS 965/965L */ { PCI_VDEVICE(SI, 0x1182), sis_180 }, /* SiS 966/680 */ { PCI_VDEVICE(SI, 0x1183), sis_180 }, /* SiS 966/966L/968/680 */ |
2d2744fc8 [libata] PCI ID t... |
75 |
|
1da177e4c Linux-2.6.12-rc2 |
76 77 |
{ } /* terminate list */ }; |
1da177e4c Linux-2.6.12-rc2 |
78 79 80 81 82 83 |
static struct pci_driver sis_pci_driver = { .name = DRV_NAME, .id_table = sis_pci_tbl, .probe = sis_init_one, .remove = ata_pci_remove_one, }; |
193515d51 [libata] eliminat... |
84 |
static struct scsi_host_template sis_sht = { |
68d1d07b5 libata: implement... |
85 |
ATA_BMDMA_SHT(DRV_NAME), |
1da177e4c Linux-2.6.12-rc2 |
86 |
}; |
029cfd6b7 libata: implement... |
87 88 |
static struct ata_port_operations sis_ops = { .inherits = &ata_bmdma_port_ops, |
1da177e4c Linux-2.6.12-rc2 |
89 90 |
.scr_read = sis_scr_read, .scr_write = sis_scr_write, |
1da177e4c Linux-2.6.12-rc2 |
91 |
}; |
1626aeb88 libata: clean up ... |
92 |
static const struct ata_port_info sis_port_info = { |
9cbe056f6 libata: remove AT... |
93 |
.flags = ATA_FLAG_SATA, |
14bdef982 [libata] convert ... |
94 95 |
.pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, |
bf6263a85 [libata] Use ATA_... |
96 |
.udma_mask = ATA_UDMA6, |
1da177e4c Linux-2.6.12-rc2 |
97 98 |
.port_ops = &sis_ops, }; |
1da177e4c Linux-2.6.12-rc2 |
99 |
MODULE_AUTHOR("Uwe Koziolek"); |
142924cf4 sata_sis.c: trivi... |
100 |
MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller"); |
1da177e4c Linux-2.6.12-rc2 |
101 102 103 |
MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sis_pci_tbl); MODULE_VERSION(DRV_VERSION); |
72fee3823 sata_sis: convert... |
104 |
static unsigned int get_scr_cfg_addr(struct ata_link *link, unsigned int sc_reg) |
1da177e4c Linux-2.6.12-rc2 |
105 |
{ |
72fee3823 sata_sis: convert... |
106 |
struct ata_port *ap = link->ap; |
9b14dec5a sata_sis: Support... |
107 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
1da177e4c Linux-2.6.12-rc2 |
108 |
unsigned int addr = SIS_SCR_BASE + (4 * sc_reg); |
9b14dec5a sata_sis: Support... |
109 |
u8 pmr; |
1da177e4c Linux-2.6.12-rc2 |
110 |
|
9b14dec5a sata_sis: Support... |
111 |
if (ap->port_no) { |
3f3e7313e [PATCH] sata_sis:... |
112 |
switch (pdev->device) { |
5796d1c4c [libata] Address ... |
113 114 115 116 117 118 119 120 121 122 123 124 |
case 0x0180: case 0x0181: pci_read_config_byte(pdev, SIS_PMR, &pmr); if ((pmr & SIS_PMR_COMBINED) == 0) addr += SIS180_SATA1_OFS; break; case 0x0182: case 0x0183: case 0x1182: addr += SIS182_SATA1_OFS; break; |
3f3e7313e [PATCH] sata_sis:... |
125 |
} |
8add78857 [libata] minor fixes |
126 |
} |
72fee3823 sata_sis: convert... |
127 128 |
if (link->pmp) addr += 0x10; |
1da177e4c Linux-2.6.12-rc2 |
129 130 |
return addr; } |
82ef04fb4 libata: make SCR ... |
131 132 |
static u32 sis_scr_cfg_read(struct ata_link *link, unsigned int sc_reg, u32 *val) |
1da177e4c Linux-2.6.12-rc2 |
133 |
{ |
82ef04fb4 libata: make SCR ... |
134 |
struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); |
72fee3823 sata_sis: convert... |
135 |
unsigned int cfg_addr = get_scr_cfg_addr(link, sc_reg); |
1da177e4c Linux-2.6.12-rc2 |
136 137 |
if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ |
8e5443a09 sata_sis: SCR acc... |
138 |
return -EINVAL; |
f2c853bca [PATCH] sata_sis:... |
139 |
|
aaa092a11 sata_sis: fix SCR... |
140 |
pci_read_config_dword(pdev, cfg_addr, val); |
aaa092a11 sata_sis: fix SCR... |
141 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
142 |
} |
82ef04fb4 libata: make SCR ... |
143 144 |
static int sis_scr_cfg_write(struct ata_link *link, unsigned int sc_reg, u32 val) |
1da177e4c Linux-2.6.12-rc2 |
145 |
{ |
82ef04fb4 libata: make SCR ... |
146 |
struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); |
72fee3823 sata_sis: convert... |
147 |
unsigned int cfg_addr = get_scr_cfg_addr(link, sc_reg); |
8add78857 [libata] minor fixes |
148 |
|
1da177e4c Linux-2.6.12-rc2 |
149 |
pci_write_config_dword(pdev, cfg_addr, val); |
8e5443a09 sata_sis: SCR acc... |
150 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
151 |
} |
82ef04fb4 libata: make SCR ... |
152 |
static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) |
1da177e4c Linux-2.6.12-rc2 |
153 |
{ |
82ef04fb4 libata: make SCR ... |
154 |
struct ata_port *ap = link->ap; |
72fee3823 sata_sis: convert... |
155 |
void __iomem *base = ap->ioaddr.scr_addr + link->pmp * 0x10; |
f2c853bca [PATCH] sata_sis:... |
156 |
|
1da177e4c Linux-2.6.12-rc2 |
157 |
if (sc_reg > SCR_CONTROL) |
da3dbb17a libata: make ->sc... |
158 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
159 160 |
if (ap->flags & SIS_FLAG_CFGSCR) |
82ef04fb4 libata: make SCR ... |
161 |
return sis_scr_cfg_read(link, sc_reg, val); |
f2c853bca [PATCH] sata_sis:... |
162 |
|
72fee3823 sata_sis: convert... |
163 |
*val = ioread32(base + sc_reg * 4); |
da3dbb17a libata: make ->sc... |
164 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
165 |
} |
82ef04fb4 libata: make SCR ... |
166 |
static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) |
1da177e4c Linux-2.6.12-rc2 |
167 |
{ |
82ef04fb4 libata: make SCR ... |
168 |
struct ata_port *ap = link->ap; |
72fee3823 sata_sis: convert... |
169 |
void __iomem *base = ap->ioaddr.scr_addr + link->pmp * 0x10; |
f2c853bca [PATCH] sata_sis:... |
170 |
|
1da177e4c Linux-2.6.12-rc2 |
171 |
if (sc_reg > SCR_CONTROL) |
da3dbb17a libata: make ->sc... |
172 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
173 174 |
if (ap->flags & SIS_FLAG_CFGSCR) |
82ef04fb4 libata: make SCR ... |
175 |
return sis_scr_cfg_write(link, sc_reg, val); |
72fee3823 sata_sis: convert... |
176 177 178 |
iowrite32(val, base + (sc_reg * 4)); return 0; |
1da177e4c Linux-2.6.12-rc2 |
179 |
} |
5796d1c4c [libata] Address ... |
180 |
static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1da177e4c Linux-2.6.12-rc2 |
181 |
{ |
9a829ccfc libata: convert a... |
182 |
struct ata_port_info pi = sis_port_info; |
ddfc87a09 libata: sata_sis ... |
183 |
const struct ata_port_info *ppi[] = { &pi, &pi }; |
9a829ccfc libata: convert a... |
184 |
struct ata_host *host; |
4adccf6f4 [PATCH] sata_sis:... |
185 |
u32 genctl, val; |
f2c853bca [PATCH] sata_sis:... |
186 |
u8 pmr; |
3f3e7313e [PATCH] sata_sis:... |
187 |
u8 port2_start = 0x20; |
72fee3823 sata_sis: convert... |
188 |
int i, rc; |
1da177e4c Linux-2.6.12-rc2 |
189 |
|
06296a1e6 ata: Add and use ... |
190 |
ata_print_version_once(&pdev->dev, DRV_VERSION); |
a9524a76f [libata] use dev_... |
191 |
|
24dc5f33e libata: update li... |
192 |
rc = pcim_enable_device(pdev); |
1da177e4c Linux-2.6.12-rc2 |
193 194 |
if (rc) return rc; |
1da177e4c Linux-2.6.12-rc2 |
195 196 197 |
/* check and see if the SCRs are in IO space or PCI cfg space */ pci_read_config_dword(pdev, SIS_GENCTL, &genctl); if ((genctl & GENCTL_IOMAPPED_SCR) == 0) |
cf0e812f0 [PATCH] sata_sis:... |
198 |
pi.flags |= SIS_FLAG_CFGSCR; |
8a60a0712 libata: trim trai... |
199 |
|
1da177e4c Linux-2.6.12-rc2 |
200 201 202 |
/* if hardware thinks SCRs are in IO space, but there are * no IO resources assigned, change to PCI cfg space. */ |
cf0e812f0 [PATCH] sata_sis:... |
203 |
if ((!(pi.flags & SIS_FLAG_CFGSCR)) && |
1da177e4c Linux-2.6.12-rc2 |
204 205 206 207 |
((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { genctl &= ~GENCTL_IOMAPPED_SCR; pci_write_config_dword(pdev, SIS_GENCTL, genctl); |
cf0e812f0 [PATCH] sata_sis:... |
208 |
pi.flags |= SIS_FLAG_CFGSCR; |
1da177e4c Linux-2.6.12-rc2 |
209 |
} |
f2c853bca [PATCH] sata_sis:... |
210 |
pci_read_config_byte(pdev, SIS_PMR, &pmr); |
3f3e7313e [PATCH] sata_sis:... |
211 212 213 |
switch (ent->device) { case 0x0180: case 0x0181: |
9b14dec5a sata_sis: Support... |
214 215 216 217 |
/* The PATA-handling is provided by pata_sis */ switch (pmr & 0x30) { case 0x10: |
a3cabb271 libata: PATA-mode... |
218 |
ppi[1] = &sis_info133_for_sata; |
9b14dec5a sata_sis: Support... |
219 |
break; |
a84471fe2 [libata] Trim tra... |
220 |
|
9b14dec5a sata_sis: Support... |
221 |
case 0x30: |
a3cabb271 libata: PATA-mode... |
222 |
ppi[0] = &sis_info133_for_sata; |
9b14dec5a sata_sis: Support... |
223 224 |
break; } |
f2c853bca [PATCH] sata_sis:... |
225 |
if ((pmr & SIS_PMR_COMBINED) == 0) { |
a44fec1fc ata: Convert dev_... |
226 227 228 |
dev_info(&pdev->dev, "Detected SiS 180/181/964 chipset in SATA mode "); |
39eb936c7 [PATCH] sata_sis:... |
229 |
port2_start = 64; |
3f3e7313e [PATCH] sata_sis:... |
230 |
} else { |
a44fec1fc ata: Convert dev_... |
231 232 233 |
dev_info(&pdev->dev, "Detected SiS 180/181 chipset in combined mode "); |
5796d1c4c [libata] Address ... |
234 |
port2_start = 0; |
4adccf6f4 [PATCH] sata_sis:... |
235 |
pi.flags |= ATA_FLAG_SLAVE_POSS; |
f2c853bca [PATCH] sata_sis:... |
236 |
} |
3f3e7313e [PATCH] sata_sis:... |
237 |
break; |
f20b16ff7 [libata] trim tra... |
238 |
|
3f3e7313e [PATCH] sata_sis:... |
239 240 |
case 0x0182: case 0x0183: |
5796d1c4c [libata] Address ... |
241 |
pci_read_config_dword(pdev, 0x6C, &val); |
4adccf6f4 [PATCH] sata_sis:... |
242 |
if (val & (1L << 31)) { |
a44fec1fc ata: Convert dev_... |
243 244 |
dev_info(&pdev->dev, "Detected SiS 182/965 chipset "); |
4adccf6f4 [PATCH] sata_sis:... |
245 |
pi.flags |= ATA_FLAG_SLAVE_POSS; |
3f3e7313e [PATCH] sata_sis:... |
246 |
} else { |
a44fec1fc ata: Convert dev_... |
247 248 |
dev_info(&pdev->dev, "Detected SiS 182/965L chipset "); |
3f3e7313e [PATCH] sata_sis:... |
249 250 251 252 |
} break; case 0x1182: |
a44fec1fc ata: Convert dev_... |
253 254 255 |
dev_info(&pdev->dev, "Detected SiS 1182/966/680 SATA controller "); |
a3cabb271 libata: PATA-mode... |
256 257 |
pi.flags |= ATA_FLAG_SLAVE_POSS; break; |
3f3e7313e [PATCH] sata_sis:... |
258 |
case 0x1183: |
a44fec1fc ata: Convert dev_... |
259 260 261 |
dev_info(&pdev->dev, "Detected SiS 1183/966/966L/968/680 controller in PATA mode "); |
a3cabb271 libata: PATA-mode... |
262 263 |
ppi[0] = &sis_info133_for_sata; ppi[1] = &sis_info133_for_sata; |
3f3e7313e [PATCH] sata_sis:... |
264 |
break; |
f2c853bca [PATCH] sata_sis:... |
265 |
} |
1c5afdf7a libata-sff: separ... |
266 |
rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
9a829ccfc libata: convert a... |
267 268 |
if (rc) return rc; |
cf0e812f0 [PATCH] sata_sis:... |
269 |
|
72fee3823 sata_sis: convert... |
270 271 272 273 274 275 276 277 278 279 |
for (i = 0; i < 2; i++) { struct ata_port *ap = host->ports[i]; if (ap->flags & ATA_FLAG_SATA && ap->flags & ATA_FLAG_SLAVE_POSS) { rc = ata_slave_link_init(ap); if (rc) return rc; } } |
9a829ccfc libata: convert a... |
280 |
if (!(pi.flags & SIS_FLAG_CFGSCR)) { |
edceec3d6 [PATCH] trivial A... |
281 |
void __iomem *mmio; |
0d5ff5667 libata: convert t... |
282 |
|
9a829ccfc libata: convert a... |
283 284 285 286 |
rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME); if (rc) return rc; mmio = host->iomap[SIS_SCR_PCI_BAR]; |
0d5ff5667 libata: convert t... |
287 |
|
9a829ccfc libata: convert a... |
288 289 |
host->ports[0]->ioaddr.scr_addr = mmio; host->ports[1]->ioaddr.scr_addr = mmio + port2_start; |
1da177e4c Linux-2.6.12-rc2 |
290 291 292 |
} pci_set_master(pdev); |
a04ce0ffc [PATCH] PCI/libat... |
293 |
pci_intx(pdev, 1); |
c3b288942 libata-sff: separ... |
294 |
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
9363c3825 libata: rename SF... |
295 |
IRQF_SHARED, &sis_sht); |
1da177e4c Linux-2.6.12-rc2 |
296 297 298 299 |
} static int __init sis_init(void) { |
b7887196e [PATCH] libata: r... |
300 |
return pci_register_driver(&sis_pci_driver); |
1da177e4c Linux-2.6.12-rc2 |
301 302 303 304 305 306 307 308 309 |
} static void __exit sis_exit(void) { pci_unregister_driver(&sis_pci_driver); } module_init(sis_init); module_exit(sis_exit); |