Blame view
drivers/ata/sata_via.c
17.8 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
af36d7f0d [libata] license ... |
2 3 4 5 |
* sata_via.c - VIA Serial ATA controllers * * Maintained by: Jeff Garzik <jgarzik@pobox.com> * Please ALWAYS copy linux-ide@vger.kernel.org |
5796d1c4c [libata] Address ... |
6 |
* on emails. |
af36d7f0d [libata] license ... |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
* * Copyright 2003-2004 Red Hat, Inc. All rights reserved. * Copyright 2003-2004 Jeff Garzik * * * 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. * * |
af36d7f0d [libata] license ... |
33 |
* |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 38 39 40 41 |
*/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/blkdev.h> #include <linux/delay.h> |
a9524a76f [libata] use dev_... |
42 |
#include <linux/device.h> |
a55ab496e sata_via: Delay o... |
43 44 |
#include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> |
1da177e4c Linux-2.6.12-rc2 |
45 46 |
#include <scsi/scsi_host.h> #include <linux/libata.h> |
1da177e4c Linux-2.6.12-rc2 |
47 48 |
#define DRV_NAME "sata_via" |
a55ab496e sata_via: Delay o... |
49 |
#define DRV_VERSION "2.6" |
1da177e4c Linux-2.6.12-rc2 |
50 |
|
b9d5b89b4 sata_via: fix sup... |
51 52 53 54 |
/* * vt8251 is different from other sata controllers of VIA. It has two * channels, each channel has both Master and Slave slot. */ |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 |
enum board_ids_enum { vt6420, vt6421, |
b9d5b89b4 sata_via: fix sup... |
58 |
vt8251, |
1da177e4c Linux-2.6.12-rc2 |
59 60 61 62 63 64 |
}; enum { SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ SATA_INT_GATE = 0x41, /* SATA interrupt gating */ SATA_NATIVE_MODE = 0x42, /* Native mode enable */ |
d73f30e1c sata_via: PATA su... |
65 66 |
PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ PATA_PIO_TIMING = 0xAB, /* PATA timing register */ |
a84471fe2 [libata] Trim tra... |
67 |
|
1da177e4c Linux-2.6.12-rc2 |
68 69 70 |
PORT0 = (1 << 1), PORT1 = (1 << 0), ALL_PORTS = PORT0 | PORT1, |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 |
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */ |
1da177e4c Linux-2.6.12-rc2 |
75 |
}; |
5796d1c4c [libata] Address ... |
76 |
static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
82ef04fb4 libata: make SCR ... |
77 78 |
static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
b9d5b89b4 sata_via: fix sup... |
79 80 |
static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val); static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val); |
b78152e9d sata_via: load DE... |
81 |
static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); |
17234246e sata_via: don't d... |
82 |
static void svia_noop_freeze(struct ata_port *ap); |
a1efdaba2 libata: make rese... |
83 |
static int vt6420_prereset(struct ata_link *link, unsigned long deadline); |
a55ab496e sata_via: Delay o... |
84 |
static void vt6420_bmdma_start(struct ata_queued_cmd *qc); |
a0fcdc025 [libata] Update s... |
85 |
static int vt6421_pata_cable_detect(struct ata_port *ap); |
d73f30e1c sata_via: PATA su... |
86 87 |
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); |
1da177e4c Linux-2.6.12-rc2 |
88 |
|
3b7d697df [libata] constify... |
89 |
static const struct pci_device_id svia_pci_tbl[] = { |
96bc103f4 sata_via: add PCI... |
90 |
{ PCI_VDEVICE(VIA, 0x5337), vt6420 }, |
b9d5b89b4 sata_via: fix sup... |
91 92 93 |
{ PCI_VDEVICE(VIA, 0x0591), vt6420 }, /* 2 sata chnls (Master) */ { PCI_VDEVICE(VIA, 0x3149), vt6420 }, /* 2 sata chnls (Master) */ { PCI_VDEVICE(VIA, 0x3249), vt6421 }, /* 2 sata chnls, 1 pata chnl */ |
52df0ee07 [libata] sata_via... |
94 95 |
{ PCI_VDEVICE(VIA, 0x5372), vt6420 }, { PCI_VDEVICE(VIA, 0x7372), vt6420 }, |
b9d5b89b4 sata_via: fix sup... |
96 |
{ PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */ |
681395202 sata_via: Add VT8... |
97 |
{ PCI_VDEVICE(VIA, 0x9000), vt8251 }, |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 101 102 103 104 105 |
{ } /* terminate list */ }; static struct pci_driver svia_pci_driver = { .name = DRV_NAME, .id_table = svia_pci_tbl, .probe = svia_init_one, |
e1e143cf9 sata_via: add mis... |
106 107 108 109 |
#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, #endif |
1da177e4c Linux-2.6.12-rc2 |
110 111 |
.remove = ata_pci_remove_one, }; |
193515d51 [libata] eliminat... |
112 |
static struct scsi_host_template svia_sht = { |
68d1d07b5 libata: implement... |
113 |
ATA_BMDMA_SHT(DRV_NAME), |
1da177e4c Linux-2.6.12-rc2 |
114 |
}; |
b78152e9d sata_via: load DE... |
115 |
static struct ata_port_operations svia_base_ops = { |
029cfd6b7 libata: implement... |
116 |
.inherits = &ata_bmdma_port_ops, |
b78152e9d sata_via: load DE... |
117 118 119 120 121 |
.sff_tf_load = svia_tf_load, }; static struct ata_port_operations vt6420_sata_ops = { .inherits = &svia_base_ops, |
17234246e sata_via: don't d... |
122 |
.freeze = svia_noop_freeze, |
a1efdaba2 libata: make rese... |
123 |
.prereset = vt6420_prereset, |
a55ab496e sata_via: Delay o... |
124 |
.bmdma_start = vt6420_bmdma_start, |
ac2164d5e [PATCH] sata_via:... |
125 |
}; |
029cfd6b7 libata: implement... |
126 |
static struct ata_port_operations vt6421_pata_ops = { |
b78152e9d sata_via: load DE... |
127 |
.inherits = &svia_base_ops, |
029cfd6b7 libata: implement... |
128 |
.cable_detect = vt6421_pata_cable_detect, |
d73f30e1c sata_via: PATA su... |
129 130 |
.set_piomode = vt6421_set_pio_mode, .set_dmamode = vt6421_set_dma_mode, |
d73f30e1c sata_via: PATA su... |
131 |
}; |
029cfd6b7 libata: implement... |
132 |
static struct ata_port_operations vt6421_sata_ops = { |
b78152e9d sata_via: load DE... |
133 |
.inherits = &svia_base_ops, |
1da177e4c Linux-2.6.12-rc2 |
134 135 |
.scr_read = svia_scr_read, .scr_write = svia_scr_write, |
1da177e4c Linux-2.6.12-rc2 |
136 |
}; |
b9d5b89b4 sata_via: fix sup... |
137 138 139 140 141 142 |
static struct ata_port_operations vt8251_ops = { .inherits = &svia_base_ops, .hardreset = sata_std_hardreset, .scr_read = vt8251_scr_read, .scr_write = vt8251_scr_write, }; |
eca25dca1 libata: convert d... |
143 |
static const struct ata_port_info vt6420_port_info = { |
9cbe056f6 libata: remove AT... |
144 |
.flags = ATA_FLAG_SATA, |
14bdef982 [libata] convert ... |
145 146 |
.pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, |
bf6263a85 [libata] Use ATA_... |
147 |
.udma_mask = ATA_UDMA6, |
ac2164d5e [PATCH] sata_via:... |
148 |
.port_ops = &vt6420_sata_ops, |
1da177e4c Linux-2.6.12-rc2 |
149 |
}; |
eca25dca1 libata: convert d... |
150 |
static struct ata_port_info vt6421_sport_info = { |
9cbe056f6 libata: remove AT... |
151 |
.flags = ATA_FLAG_SATA, |
14bdef982 [libata] convert ... |
152 153 |
.pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, |
bf6263a85 [libata] Use ATA_... |
154 |
.udma_mask = ATA_UDMA6, |
eca25dca1 libata: convert d... |
155 156 157 158 |
.port_ops = &vt6421_sata_ops, }; static struct ata_port_info vt6421_pport_info = { |
9cbe056f6 libata: remove AT... |
159 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
160 161 |
.pio_mask = ATA_PIO4, /* No MWDMA */ |
bf6263a85 [libata] Use ATA_... |
162 |
.udma_mask = ATA_UDMA6, |
eca25dca1 libata: convert d... |
163 164 |
.port_ops = &vt6421_pata_ops, }; |
b9d5b89b4 sata_via: fix sup... |
165 |
static struct ata_port_info vt8251_port_info = { |
9cbe056f6 libata: remove AT... |
166 |
.flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
167 168 |
.pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, |
b9d5b89b4 sata_via: fix sup... |
169 170 171 |
.udma_mask = ATA_UDMA6, .port_ops = &vt8251_ops, }; |
1da177e4c Linux-2.6.12-rc2 |
172 173 174 175 176 |
MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, svia_pci_tbl); MODULE_VERSION(DRV_VERSION); |
82ef04fb4 libata: make SCR ... |
177 |
static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) |
1da177e4c Linux-2.6.12-rc2 |
178 179 |
{ if (sc_reg > SCR_CONTROL) |
da3dbb17a libata: make ->sc... |
180 |
return -EINVAL; |
82ef04fb4 libata: make SCR ... |
181 |
*val = ioread32(link->ap->ioaddr.scr_addr + (4 * sc_reg)); |
da3dbb17a libata: make ->sc... |
182 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
183 |
} |
82ef04fb4 libata: make SCR ... |
184 |
static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) |
1da177e4c Linux-2.6.12-rc2 |
185 186 |
{ if (sc_reg > SCR_CONTROL) |
da3dbb17a libata: make ->sc... |
187 |
return -EINVAL; |
82ef04fb4 libata: make SCR ... |
188 |
iowrite32(val, link->ap->ioaddr.scr_addr + (4 * sc_reg)); |
da3dbb17a libata: make ->sc... |
189 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
190 |
} |
b9d5b89b4 sata_via: fix sup... |
191 192 193 194 195 196 197 198 199 200 201 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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val) { static const u8 ipm_tbl[] = { 1, 2, 6, 0 }; struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); int slot = 2 * link->ap->port_no + link->pmp; u32 v = 0; u8 raw; switch (scr) { case SCR_STATUS: pci_read_config_byte(pdev, 0xA0 + slot, &raw); /* read the DET field, bit0 and 1 of the config byte */ v |= raw & 0x03; /* read the SPD field, bit4 of the configure byte */ if (raw & (1 << 4)) v |= 0x02 << 4; else v |= 0x01 << 4; /* read the IPM field, bit2 and 3 of the config byte */ v |= ipm_tbl[(raw >> 2) & 0x3]; break; case SCR_ERROR: /* devices other than 5287 uses 0xA8 as base */ WARN_ON(pdev->device != 0x5287); pci_read_config_dword(pdev, 0xB0 + slot * 4, &v); break; case SCR_CONTROL: pci_read_config_byte(pdev, 0xA4 + slot, &raw); /* read the DET field, bit0 and bit1 */ v |= ((raw & 0x02) << 1) | (raw & 0x01); /* read the IPM field, bit2 and bit3 */ v |= ((raw >> 2) & 0x03) << 8; break; default: return -EINVAL; } *val = v; return 0; } static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val) { struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); int slot = 2 * link->ap->port_no + link->pmp; u32 v = 0; switch (scr) { case SCR_ERROR: /* devices other than 5287 uses 0xA8 as base */ WARN_ON(pdev->device != 0x5287); pci_write_config_dword(pdev, 0xB0 + slot * 4, val); return 0; case SCR_CONTROL: /* set the DET field */ v |= ((val & 0x4) >> 1) | (val & 0x1); /* set the IPM field */ v |= ((val >> 8) & 0x3) << 2; pci_write_config_byte(pdev, 0xA4 + slot, v); return 0; default: return -EINVAL; } } |
b78152e9d sata_via: load DE... |
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
/** * svia_tf_load - send taskfile registers to host controller * @ap: Port to which output is sent * @tf: ATA taskfile register set * * Outputs ATA taskfile to standard ATA host controller. * * This is to fix the internal bug of via chipsets, which will * reset the device register after changing the IEN bit on ctl * register. */ static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { struct ata_taskfile ttf; if (tf->ctl != ap->last_ctl) { ttf = *tf; ttf.flags |= ATA_TFLAG_DEVICE; tf = &ttf; } ata_sff_tf_load(ap, tf); } |
17234246e sata_via: don't d... |
289 290 291 292 293 |
static void svia_noop_freeze(struct ata_port *ap) { /* Some VIA controllers choke if ATA_NIEN is manipulated in * certain way. Leave it alone and just clear pending IRQ. */ |
5682ed33a libata: rename SF... |
294 |
ap->ops->sff_check_status(ap); |
37f65b8bc libata-sff: ata_s... |
295 |
ata_bmdma_irq_clear(ap); |
17234246e sata_via: don't d... |
296 |
} |
ac2164d5e [PATCH] sata_via:... |
297 298 |
/** * vt6420_prereset - prereset for vt6420 |
cc0680a58 libata-link: link... |
299 |
* @link: target ATA link |
d4b2bab4f libata: add deadl... |
300 |
* @deadline: deadline jiffies for the operation |
ac2164d5e [PATCH] sata_via:... |
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
* * SCR registers on vt6420 are pieces of shit and may hang the * whole machine completely if accessed with the wrong timing. * To avoid such catastrophe, vt6420 doesn't provide generic SCR * access operations, but uses SStatus and SControl only during * boot probing in controlled way. * * As the old (pre EH update) probing code is proven to work, we * strictly follow the access pattern. * * LOCKING: * Kernel thread context (may sleep) * * RETURNS: * 0 on success, -errno otherwise. */ |
cc0680a58 libata-link: link... |
317 |
static int vt6420_prereset(struct ata_link *link, unsigned long deadline) |
ac2164d5e [PATCH] sata_via:... |
318 |
{ |
cc0680a58 libata-link: link... |
319 |
struct ata_port *ap = link->ap; |
9af5c9c97 libata-link: intr... |
320 |
struct ata_eh_context *ehc = &ap->link.eh_context; |
ac2164d5e [PATCH] sata_via:... |
321 322 323 324 325 |
unsigned long timeout = jiffies + (HZ * 5); u32 sstatus, scontrol; int online; /* don't do any SCR stuff if we're not loading */ |
68ff6e8e0 [libata] sata_via... |
326 |
if (!(ap->pflags & ATA_PFLAG_LOADING)) |
ac2164d5e [PATCH] sata_via:... |
327 |
goto skip_scr; |
a09060ffe [libata] sata_sx4... |
328 |
/* Resume phy. This is the old SATA resume sequence */ |
82ef04fb4 libata: make SCR ... |
329 330 |
svia_scr_write(link, SCR_CONTROL, 0x300); svia_scr_read(link, SCR_CONTROL, &scontrol); /* flush */ |
ac2164d5e [PATCH] sata_via:... |
331 332 333 |
/* wait for phy to become ready, if necessary */ do { |
97750cebb libata: add @ap t... |
334 |
ata_msleep(link->ap, 200); |
82ef04fb4 libata: make SCR ... |
335 |
svia_scr_read(link, SCR_STATUS, &sstatus); |
da3dbb17a libata: make ->sc... |
336 |
if ((sstatus & 0xf) != 1) |
ac2164d5e [PATCH] sata_via:... |
337 338 339 340 |
break; } while (time_before(jiffies, timeout)); /* open code sata_print_link_status() */ |
82ef04fb4 libata: make SCR ... |
341 342 |
svia_scr_read(link, SCR_STATUS, &sstatus); svia_scr_read(link, SCR_CONTROL, &scontrol); |
ac2164d5e [PATCH] sata_via:... |
343 344 |
online = (sstatus & 0xf) == 0x3; |
a9a79dfec ata: Convert ata_... |
345 346 347 348 |
ata_port_info(ap, "SATA link %s 1.5 Gbps (SStatus %X SControl %X) ", online ? "up" : "down", sstatus, scontrol); |
ac2164d5e [PATCH] sata_via:... |
349 350 |
/* SStatus is read one more time */ |
82ef04fb4 libata: make SCR ... |
351 |
svia_scr_read(link, SCR_STATUS, &sstatus); |
ac2164d5e [PATCH] sata_via:... |
352 353 354 |
if (!online) { /* tell EH to bail */ |
cf4806265 libata: prefer ha... |
355 |
ehc->i.action &= ~ATA_EH_RESET; |
ac2164d5e [PATCH] sata_via:... |
356 357 358 359 360 |
return 0; } skip_scr: /* wait for !BSY */ |
705e76beb libata: restructu... |
361 |
ata_sff_wait_ready(link, deadline); |
ac2164d5e [PATCH] sata_via:... |
362 363 364 |
return 0; } |
a55ab496e sata_via: Delay o... |
365 366 367 368 369 370 371 372 373 374 |
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); } |
a0fcdc025 [libata] Update s... |
375 |
static int vt6421_pata_cable_detect(struct ata_port *ap) |
d73f30e1c sata_via: PATA su... |
376 377 378 379 380 381 |
{ struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 tmp; pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp); if (tmp & 0x10) |
a0fcdc025 [libata] Update s... |
382 383 |
return ATA_CBL_PATA40; return ATA_CBL_PATA80; |
d73f30e1c sata_via: PATA su... |
384 385 386 387 388 389 |
} 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 }; |
02d1d6160 sata_via: Correct... |
390 391 |
pci_write_config_byte(pdev, PATA_PIO_TIMING - adev->devno, pio_bits[adev->pio_mode - XFER_PIO_0]); |
d73f30e1c sata_via: PATA su... |
392 393 394 395 396 397 |
} 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 }; |
02d1d6160 sata_via: Correct... |
398 399 |
pci_write_config_byte(pdev, PATA_UDMA_TIMING - adev->devno, udma_bits[adev->dma_mode - XFER_UDMA_0]); |
d73f30e1c sata_via: PATA su... |
400 |
} |
1da177e4c Linux-2.6.12-rc2 |
401 402 403 404 405 406 407 |
static const unsigned int svia_bar_sizes[] = { 8, 4, 8, 4, 16, 256 }; static const unsigned int vt6421_bar_sizes[] = { 16, 16, 16, 16, 32, 128 }; |
5796d1c4c [libata] Address ... |
408 |
static void __iomem *svia_scr_addr(void __iomem *addr, unsigned int port) |
1da177e4c Linux-2.6.12-rc2 |
409 410 411 |
{ return addr + (port * 128); } |
5796d1c4c [libata] Address ... |
412 |
static void __iomem *vt6421_scr_addr(void __iomem *addr, unsigned int port) |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 |
{ return addr + (port * 64); } |
eca25dca1 libata: convert d... |
416 |
static void vt6421_init_addrs(struct ata_port *ap) |
1da177e4c Linux-2.6.12-rc2 |
417 |
{ |
eca25dca1 libata: convert d... |
418 419 420 421 422 423 424 425 |
void __iomem * const * iomap = ap->host->iomap; void __iomem *reg_addr = iomap[ap->port_no]; void __iomem *bmdma_addr = iomap[4] + (ap->port_no * 8); struct ata_ioports *ioaddr = &ap->ioaddr; ioaddr->cmd_addr = reg_addr; ioaddr->altstatus_addr = ioaddr->ctl_addr = (void __iomem *) |
0d5ff5667 libata: convert t... |
426 |
((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS); |
eca25dca1 libata: convert d... |
427 428 |
ioaddr->bmdma_addr = bmdma_addr; ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no); |
1da177e4c Linux-2.6.12-rc2 |
429 |
|
9363c3825 libata: rename SF... |
430 |
ata_sff_std_ports(ioaddr); |
cbcdd8759 libata: implement... |
431 432 433 |
ata_port_pbar_desc(ap, ap->port_no, -1, "port"); ata_port_pbar_desc(ap, 4, ap->port_no * 8, "bmdma"); |
1da177e4c Linux-2.6.12-rc2 |
434 |
} |
eca25dca1 libata: convert d... |
435 |
static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) |
1da177e4c Linux-2.6.12-rc2 |
436 |
{ |
eca25dca1 libata: convert d... |
437 438 439 |
const struct ata_port_info *ppi[] = { &vt6420_port_info, NULL }; struct ata_host *host; int rc; |
f20b16ff7 [libata] trim tra... |
440 |
|
1c5afdf7a libata-sff: separ... |
441 |
rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
eca25dca1 libata: convert d... |
442 443 444 |
if (rc) return rc; *r_host = host; |
1da177e4c Linux-2.6.12-rc2 |
445 |
|
eca25dca1 libata: convert d... |
446 447 |
rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); if (rc) { |
a44fec1fc ata: Convert dev_... |
448 449 |
dev_err(&pdev->dev, "failed to iomap PCI BAR 5 "); |
eca25dca1 libata: convert d... |
450 |
return rc; |
e1be5d73e sata_via: fix res... |
451 |
} |
eca25dca1 libata: convert d... |
452 453 |
host->ports[0]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 0); host->ports[1]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 1); |
1da177e4c Linux-2.6.12-rc2 |
454 |
|
eca25dca1 libata: convert d... |
455 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
456 |
} |
eca25dca1 libata: convert d... |
457 |
static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) |
1da177e4c Linux-2.6.12-rc2 |
458 |
{ |
eca25dca1 libata: convert d... |
459 460 461 462 463 464 465 |
const struct ata_port_info *ppi[] = { &vt6421_sport_info, &vt6421_sport_info, &vt6421_pport_info }; struct ata_host *host; int i, rc; *r_host = host = ata_host_alloc_pinfo(&pdev->dev, ppi, ARRAY_SIZE(ppi)); if (!host) { |
a44fec1fc ata: Convert dev_... |
466 467 |
dev_err(&pdev->dev, "failed to allocate host "); |
eca25dca1 libata: convert d... |
468 469 |
return -ENOMEM; } |
1da177e4c Linux-2.6.12-rc2 |
470 |
|
8fd7d1b16 sata_via: pcim_io... |
471 |
rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME); |
eca25dca1 libata: convert d... |
472 |
if (rc) { |
a44fec1fc ata: Convert dev_... |
473 474 475 |
dev_err(&pdev->dev, "failed to request/iomap PCI BARs (errno=%d) ", rc); |
eca25dca1 libata: convert d... |
476 477 478 |
return rc; } host->iomap = pcim_iomap_table(pdev); |
e1be5d73e sata_via: fix res... |
479 |
|
eca25dca1 libata: convert d... |
480 481 |
for (i = 0; i < host->n_ports; i++) vt6421_init_addrs(host->ports[i]); |
1da177e4c Linux-2.6.12-rc2 |
482 |
|
eca25dca1 libata: convert d... |
483 484 485 486 487 488 489 490 |
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; return 0; |
1da177e4c Linux-2.6.12-rc2 |
491 |
} |
b9d5b89b4 sata_via: fix sup... |
492 493 494 495 496 |
static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) { const struct ata_port_info *ppi[] = { &vt8251_port_info, NULL }; struct ata_host *host; int i, rc; |
1c5afdf7a libata-sff: separ... |
497 |
rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
b9d5b89b4 sata_via: fix sup... |
498 499 500 501 502 503 |
if (rc) return rc; *r_host = host; rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); if (rc) { |
a44fec1fc ata: Convert dev_... |
504 505 |
dev_err(&pdev->dev, "failed to iomap PCI BAR 5 "); |
b9d5b89b4 sata_via: fix sup... |
506 507 508 509 510 511 512 513 514 |
return rc; } /* 8251 hosts four sata ports as M/S of the two channels */ for (i = 0; i < host->n_ports; i++) ata_slave_link_init(host->ports[i]); return 0; } |
b1353e4f4 sata_via: apply m... |
515 |
static void svia_configure(struct pci_dev *pdev, int board_id) |
1da177e4c Linux-2.6.12-rc2 |
516 517 518 519 |
{ u8 tmp8; pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8); |
a44fec1fc ata: Convert dev_... |
520 521 522 |
dev_info(&pdev->dev, "routed to hard irq line %d ", (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f); |
1da177e4c Linux-2.6.12-rc2 |
523 524 525 526 |
/* make sure SATA channels are enabled */ pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8); if ((tmp8 & ALL_PORTS) != ALL_PORTS) { |
5b933e634 ata: sata_via: Us... |
527 528 529 |
dev_dbg(&pdev->dev, "enabling SATA channels (0x%x) ", (int)tmp8); |
1da177e4c Linux-2.6.12-rc2 |
530 531 532 533 534 535 536 |
tmp8 |= ALL_PORTS; pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8); } /* make sure interrupts for each channel sent to us */ pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8); if ((tmp8 & ALL_PORTS) != ALL_PORTS) { |
5b933e634 ata: sata_via: Us... |
537 538 539 |
dev_dbg(&pdev->dev, "enabling SATA channel interrupts (0x%x) ", (int) tmp8); |
1da177e4c Linux-2.6.12-rc2 |
540 541 542 543 544 545 546 |
tmp8 |= ALL_PORTS; pci_write_config_byte(pdev, SATA_INT_GATE, tmp8); } /* make sure native mode is enabled */ pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8); if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) { |
5b933e634 ata: sata_via: Us... |
547 548 549 550 |
dev_dbg(&pdev->dev, "enabling SATA channel native mode (0x%x) ", (int) tmp8); |
1da177e4c Linux-2.6.12-rc2 |
551 552 553 |
tmp8 |= NATIVE_MODE_ALL; pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); } |
8b27ff4cf sata_via: magic v... |
554 555 |
/* |
b1353e4f4 sata_via: apply m... |
556 |
* vt6420/1 has problems talking to some drives. The following |
b475a3b83 sata_via: explain... |
557 558 559 560 561 |
* is the fix from Joseph Chan <JosephChan@via.com.tw>. * * When host issues HOLD, device may send up to 20DW of data * before acknowledging it with HOLDA and the host should be * able to buffer them in FIFO. Unfortunately, some WD drives |
25985edce Fix common misspe... |
562 |
* send up to 40DW before acknowledging HOLD and, in the |
b475a3b83 sata_via: explain... |
563 564 565 566 567 568 569 570 571 |
* default configuration, this ends up overflowing vt6421's * FIFO, making the controller abort the transaction with * R_ERR. * * Rx52[2] is the internal 128DW FIFO Flow control watermark * adjusting mechanism enable bit and the default value 0 * means host will issue HOLD to device when the left FIFO * size goes below 32DW. Setting it to 1 makes the watermark * 64DW. |
8b27ff4cf sata_via: magic v... |
572 573 |
* * https://bugzilla.kernel.org/show_bug.cgi?id=15173 |
b475a3b83 sata_via: explain... |
574 |
* http://article.gmane.org/gmane.linux.ide/46352 |
b1353e4f4 sata_via: apply m... |
575 |
* http://thread.gmane.org/gmane.linux.kernel/1062139 |
8b27ff4cf sata_via: magic v... |
576 |
*/ |
b1353e4f4 sata_via: apply m... |
577 |
if (board_id == vt6420 || board_id == vt6421) { |
8b27ff4cf sata_via: magic v... |
578 579 580 581 |
pci_read_config_byte(pdev, 0x52, &tmp8); tmp8 |= 1 << 2; pci_write_config_byte(pdev, 0x52, tmp8); } |
1da177e4c Linux-2.6.12-rc2 |
582 |
} |
5796d1c4c [libata] Address ... |
583 |
static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1da177e4c Linux-2.6.12-rc2 |
584 |
{ |
1da177e4c Linux-2.6.12-rc2 |
585 586 |
unsigned int i; int rc; |
f1c22943e [libata] sata_via... |
587 |
struct ata_host *host = NULL; |
1da177e4c Linux-2.6.12-rc2 |
588 |
int board_id = (int) ent->driver_data; |
b4482a4b2 more trivial sign... |
589 |
const unsigned *bar_sizes; |
1da177e4c Linux-2.6.12-rc2 |
590 |
|
06296a1e6 ata: Add and use ... |
591 |
ata_print_version_once(&pdev->dev, DRV_VERSION); |
1da177e4c Linux-2.6.12-rc2 |
592 |
|
24dc5f33e libata: update li... |
593 |
rc = pcim_enable_device(pdev); |
1da177e4c Linux-2.6.12-rc2 |
594 595 |
if (rc) return rc; |
b9d5b89b4 sata_via: fix sup... |
596 |
if (board_id == vt6421) |
1da177e4c Linux-2.6.12-rc2 |
597 |
bar_sizes = &vt6421_bar_sizes[0]; |
b9d5b89b4 sata_via: fix sup... |
598 599 |
else bar_sizes = &svia_bar_sizes[0]; |
1da177e4c Linux-2.6.12-rc2 |
600 601 602 603 |
for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) if ((pci_resource_start(pdev, i) == 0) || (pci_resource_len(pdev, i) < bar_sizes[i])) { |
a44fec1fc ata: Convert dev_... |
604 |
dev_err(&pdev->dev, |
e29419fff [PATCH] 64bit res... |
605 606 607 |
"invalid PCI BAR %u (sz 0x%llx, val 0x%llx) ", i, |
5796d1c4c [libata] Address ... |
608 609 |
(unsigned long long)pci_resource_start(pdev, i), (unsigned long long)pci_resource_len(pdev, i)); |
24dc5f33e libata: update li... |
610 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
611 |
} |
b9d5b89b4 sata_via: fix sup... |
612 613 |
switch (board_id) { case vt6420: |
eca25dca1 libata: convert d... |
614 |
rc = vt6420_prepare_host(pdev, &host); |
b9d5b89b4 sata_via: fix sup... |
615 616 |
break; case vt6421: |
eca25dca1 libata: convert d... |
617 |
rc = vt6421_prepare_host(pdev, &host); |
b9d5b89b4 sata_via: fix sup... |
618 619 620 621 622 |
break; case vt8251: rc = vt8251_prepare_host(pdev, &host); break; default: |
554d491de sata_via: restore... |
623 |
rc = -EINVAL; |
b9d5b89b4 sata_via: fix sup... |
624 |
} |
554d491de sata_via: restore... |
625 626 |
if (rc) return rc; |
1da177e4c Linux-2.6.12-rc2 |
627 |
|
b1353e4f4 sata_via: apply m... |
628 |
svia_configure(pdev, board_id); |
1da177e4c Linux-2.6.12-rc2 |
629 630 |
pci_set_master(pdev); |
c3b288942 libata-sff: separ... |
631 |
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
9363c3825 libata: rename SF... |
632 |
IRQF_SHARED, &svia_sht); |
1da177e4c Linux-2.6.12-rc2 |
633 634 635 636 |
} static int __init svia_init(void) { |
b7887196e [PATCH] libata: r... |
637 |
return pci_register_driver(&svia_pci_driver); |
1da177e4c Linux-2.6.12-rc2 |
638 639 640 641 642 643 644 645 646 |
} static void __exit svia_exit(void) { pci_unregister_driver(&svia_pci_driver); } module_init(svia_init); module_exit(svia_exit); |