Blame view
drivers/ata/pata_sis.c
23.5 KB
669a5db41 [libata] Add a bu... |
1 2 3 |
/* * pata_sis.c - SiS ATA driver * |
ab7716300 ata: Switch all m... |
4 |
* (C) 2005 Red Hat |
750c7136e pata_sis: Power M... |
5 |
* (C) 2007,2009 Bartlomiej Zolnierkiewicz |
669a5db41 [libata] Add a bu... |
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
* * Based upon linux/drivers/ide/pci/sis5513.c * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> * SiS Taiwan : for direct support and hardware. * Daniela Engert : for initial ATA100 advices and numerous others. * John Fremlin, Manfred Spraul, Dave Morgan, Peter Kjellerstedt : * for checking code correctness, providing patches. * Original tests and design on the SiS620 chipset. * ATA100 tests and design on the SiS735 chipset. * ATA16/33 support from specs * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw> * * * TODO * Check MWDMA on drives that don't support MWDMA speed pio cycles ? * More Testing */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> |
669a5db41 [libata] Add a bu... |
29 30 31 32 33 34 |
#include <linux/blkdev.h> #include <linux/delay.h> #include <linux/device.h> #include <scsi/scsi_host.h> #include <linux/libata.h> #include <linux/ata.h> |
4bb64fb98 SiS warning fixes |
35 |
#include "sis.h" |
669a5db41 [libata] Add a bu... |
36 37 |
#define DRV_NAME "pata_sis" |
4761c06cb pata_sis: fix MWD... |
38 |
#define DRV_VERSION "0.5.2" |
669a5db41 [libata] Add a bu... |
39 40 |
struct sis_chipset { |
1626aeb88 libata: clean up ... |
41 42 |
u16 device; /* PCI host ID */ const struct ata_port_info *info; /* Info block */ |
669a5db41 [libata] Add a bu... |
43 44 45 |
/* Probably add family, cable detect type etc here to clean up code later */ }; |
7dcbc1f2c pata_sis: impleme... |
46 47 48 49 50 51 52 53 54 |
struct sis_laptop { u16 device; u16 subvendor; u16 subdevice; }; static const struct sis_laptop sis_laptop[] = { /* devid, subvendor, subdev */ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ |
4f2d47cfd pata_sis: Add the... |
55 |
{ 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ |
edc7d12ed pata_sis: code st... |
56 |
{ 0x5513, 0x1071, 0x8640 }, /* EasyNote K5305 */ |
7dcbc1f2c pata_sis: impleme... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
/* end marker */ { 0, } }; static int sis_short_ata40(struct pci_dev *dev) { const struct sis_laptop *lap = &sis_laptop[0]; while (lap->device) { if (lap->device == dev->device && lap->subvendor == dev->subsystem_vendor && lap->subdevice == dev->subsystem_device) return 1; lap++; } return 0; } |
669a5db41 [libata] Add a bu... |
75 |
/** |
edc7d12ed pata_sis: code st... |
76 |
* sis_old_port_base - return PCI configuration base for dev |
669a5db41 [libata] Add a bu... |
77 78 79 80 81 |
* @adev: device * * Returns the base of the PCI configuration registers for this port * number. */ |
dd668d150 pata_sis: Fix and... |
82 |
static int sis_old_port_base(struct ata_device *adev) |
669a5db41 [libata] Add a bu... |
83 |
{ |
edc7d12ed pata_sis: code st... |
84 |
return 0x40 + (4 * adev->link->ap->port_no) + (2 * adev->devno); |
669a5db41 [libata] Add a bu... |
85 86 87 |
} /** |
edc7d12ed pata_sis: code st... |
88 |
* sis_port_base - return PCI configuration base for dev |
023a0175a pata_sis: extract... |
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
* @adev: device * * Returns the base of the PCI configuration registers for this port * number. */ static int sis_port_base(struct ata_device *adev) { struct ata_port *ap = adev->link->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); int port = 0x40; u32 reg54; /* If bit 30 is set then the registers are mapped at 0x70 not 0x40 */ pci_read_config_dword(pdev, 0x54, ®54); if (reg54 & 0x40000000) port = 0x70; return port + (8 * ap->port_no) + (4 * adev->devno); } /** |
edc7d12ed pata_sis: code st... |
111 |
* sis_133_cable_detect - check for 40/80 pin |
669a5db41 [libata] Add a bu... |
112 |
* @ap: Port |
d4b2bab4f libata: add deadl... |
113 |
* @deadline: deadline jiffies for the operation |
669a5db41 [libata] Add a bu... |
114 115 116 117 |
* * Perform cable detection for the later UDMA133 capable * SiS chipset. */ |
2e413f510 pata_sis: Clean u... |
118 |
static int sis_133_cable_detect(struct ata_port *ap) |
669a5db41 [libata] Add a bu... |
119 |
{ |
669a5db41 [libata] Add a bu... |
120 121 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); u16 tmp; |
669a5db41 [libata] Add a bu... |
122 123 |
/* The top bit of this register is the cable detect bit */ pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp); |
7dcbc1f2c pata_sis: impleme... |
124 |
if ((tmp & 0x8000) && !sis_short_ata40(pdev)) |
2e413f510 pata_sis: Clean u... |
125 126 |
return ATA_CBL_PATA40; return ATA_CBL_PATA80; |
669a5db41 [libata] Add a bu... |
127 128 129 |
} /** |
edc7d12ed pata_sis: code st... |
130 |
* sis_66_cable_detect - check for 40/80 pin |
669a5db41 [libata] Add a bu... |
131 132 133 134 135 |
* @ap: Port * * Perform cable detection on the UDMA66, UDMA100 and early UDMA133 * SiS IDE controllers. */ |
2e413f510 pata_sis: Clean u... |
136 |
static int sis_66_cable_detect(struct ata_port *ap) |
669a5db41 [libata] Add a bu... |
137 |
{ |
669a5db41 [libata] Add a bu... |
138 139 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 tmp; |
669a5db41 [libata] Add a bu... |
140 141 142 |
/* Older chips keep cable detect in bits 4/5 of reg 0x48 */ pci_read_config_byte(pdev, 0x48, &tmp); tmp >>= ap->port_no; |
7dcbc1f2c pata_sis: impleme... |
143 |
if ((tmp & 0x10) && !sis_short_ata40(pdev)) |
2e413f510 pata_sis: Clean u... |
144 145 |
return ATA_CBL_PATA40; return ATA_CBL_PATA80; |
669a5db41 [libata] Add a bu... |
146 |
} |
669a5db41 [libata] Add a bu... |
147 148 |
/** |
edc7d12ed pata_sis: code st... |
149 |
* sis_pre_reset - probe begin |
cc0680a58 libata-link: link... |
150 |
* @link: ATA link |
d4b2bab4f libata: add deadl... |
151 |
* @deadline: deadline jiffies for the operation |
669a5db41 [libata] Add a bu... |
152 153 154 |
* * Set up cable type and use generic probe init */ |
cc0680a58 libata-link: link... |
155 |
static int sis_pre_reset(struct ata_link *link, unsigned long deadline) |
669a5db41 [libata] Add a bu... |
156 157 158 159 160 |
{ static const struct pci_bits sis_enable_bits[] = { { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ }; |
85cd7251b [libata #pata-dri... |
161 |
|
cc0680a58 libata-link: link... |
162 |
struct ata_port *ap = link->ap; |
669a5db41 [libata] Add a bu... |
163 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
2e413f510 pata_sis: Clean u... |
164 165 |
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) return -ENOENT; |
d4b2bab4f libata: add deadl... |
166 |
|
15ce09432 pata_sis: FIFO whack |
167 168 169 |
/* Clear the FIFO settings. We can't enable the FIFO until we know we are poking at a disk */ pci_write_config_byte(pdev, 0x4B, 0); |
9363c3825 libata: rename SF... |
170 |
return ata_sff_prereset(link, deadline); |
669a5db41 [libata] Add a bu... |
171 172 173 174 |
} /** |
edc7d12ed pata_sis: code st... |
175 |
* sis_set_fifo - Set RWP fifo bits for this device |
669a5db41 [libata] Add a bu... |
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 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 |
* @ap: Port * @adev: Device * * SIS chipsets implement prefetch/postwrite bits for each device * on both channels. This functionality is not ATAPI compatible and * must be configured according to the class of device present */ static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 fifoctrl; u8 mask = 0x11; mask <<= (2 * ap->port_no); mask <<= adev->devno; /* This holds various bits including the FIFO control */ pci_read_config_byte(pdev, 0x4B, &fifoctrl); fifoctrl &= ~mask; /* Enable for ATA (disk) only */ if (adev->class == ATA_DEV_ATA) fifoctrl |= mask; pci_write_config_byte(pdev, 0x4B, fifoctrl); } /** * sis_old_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring * @adev: Device we are configuring for. * * Set PIO mode for device, in host controller PCI config space. This * function handles PIO set up for all chips that are pre ATA100 and * also early ATA100 devices. * * LOCKING: * None (inherited from caller). */ static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
218 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
dd668d150 pata_sis: Fix and... |
219 |
int port = sis_old_port_base(adev); |
669a5db41 [libata] Add a bu... |
220 221 |
u8 t1, t2; int speed = adev->pio_mode - XFER_PIO_0; |
c03a476dd pata_sis: mark mo... |
222 223 |
static const u8 active[] = { 0x00, 0x07, 0x04, 0x03, 0x01 }; static const u8 recovery[] = { 0x00, 0x06, 0x04, 0x03, 0x03 }; |
669a5db41 [libata] Add a bu... |
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
sis_set_fifo(ap, adev); pci_read_config_byte(pdev, port, &t1); pci_read_config_byte(pdev, port + 1, &t2); t1 &= ~0x0F; /* Clear active/recovery timings */ t2 &= ~0x07; t1 |= active[speed]; t2 |= recovery[speed]; pci_write_config_byte(pdev, port, t1); pci_write_config_byte(pdev, port + 1, t2); } /** |
4761c06cb pata_sis: fix MWD... |
241 |
* sis_100_set_piomode - Initialize host controller PATA PIO timings |
669a5db41 [libata] Add a bu... |
242 243 244 245 246 247 248 249 250 251 252 253 |
* @ap: Port whose timings we are configuring * @adev: Device we are configuring for. * * Set PIO mode for device, in host controller PCI config space. This * function handles PIO set up for ATA100 devices and early ATA133. * * LOCKING: * None (inherited from caller). */ static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
254 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
dd668d150 pata_sis: Fix and... |
255 |
int port = sis_old_port_base(adev); |
669a5db41 [libata] Add a bu... |
256 |
int speed = adev->pio_mode - XFER_PIO_0; |
c03a476dd pata_sis: mark mo... |
257 |
static const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 }; |
669a5db41 [libata] Add a bu... |
258 259 260 261 262 263 264 |
sis_set_fifo(ap, adev); pci_write_config_byte(pdev, port, actrec[speed]); } /** |
1b52f2a41 Revert "pata_sis:... |
265 |
* sis_133_set_piomode - Initialize host controller PATA PIO timings |
669a5db41 [libata] Add a bu... |
266 267 268 269 |
* @ap: Port whose timings we are configuring * @adev: Device we are configuring for. * * Set PIO mode for device, in host controller PCI config space. This |
1b52f2a41 Revert "pata_sis:... |
270 |
* function handles PIO set up for the later ATA133 devices. |
669a5db41 [libata] Add a bu... |
271 272 273 274 |
* * LOCKING: * None (inherited from caller). */ |
1b52f2a41 Revert "pata_sis:... |
275 |
static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev) |
669a5db41 [libata] Add a bu... |
276 |
{ |
edc7d12ed pata_sis: code st... |
277 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
023a0175a pata_sis: extract... |
278 |
int port; |
669a5db41 [libata] Add a bu... |
279 |
u32 t1; |
1b52f2a41 Revert "pata_sis:... |
280 |
int speed = adev->pio_mode - XFER_PIO_0; |
669a5db41 [libata] Add a bu... |
281 |
|
c03a476dd pata_sis: mark mo... |
282 |
static const u32 timing133[] = { |
669a5db41 [libata] Add a bu... |
283 284 285 286 287 288 |
0x28269000, /* Recovery << 24 | Act << 16 | Ini << 12 */ 0x0C266000, 0x04263000, 0x0C0A3000, 0x05093000 }; |
c03a476dd pata_sis: mark mo... |
289 |
static const u32 timing100[] = { |
669a5db41 [libata] Add a bu... |
290 291 292 293 294 295 296 297 |
0x1E1C6000, /* Recovery << 24 | Act << 16 | Ini << 12 */ 0x091C4000, 0x031C2000, 0x09072000, 0x04062000 }; sis_set_fifo(ap, adev); |
023a0175a pata_sis: extract... |
298 |
port = sis_port_base(adev); |
669a5db41 [libata] Add a bu... |
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
pci_read_config_dword(pdev, port, &t1); t1 &= 0xC0C00FFF; /* Mask out timing */ if (t1 & 0x08) /* 100 or 133 ? */ t1 |= timing133[speed]; else t1 |= timing100[speed]; pci_write_config_byte(pdev, port, t1); } /** * sis_old_set_dmamode - Initialize host controller PATA DMA timings * @ap: Port whose timings we are configuring * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. * Handles pre UDMA and UDMA33 devices. Supports MWDMA as well unlike * the old ide/pci driver. * * LOCKING: * None (inherited from caller). */ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
324 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
669a5db41 [libata] Add a bu... |
325 |
int speed = adev->dma_mode - XFER_MW_DMA_0; |
dd668d150 pata_sis: Fix and... |
326 |
int drive_pci = sis_old_port_base(adev); |
669a5db41 [libata] Add a bu... |
327 |
u16 timing; |
c03a476dd pata_sis: mark mo... |
328 329 |
static const u16 mwdma_bits[] = { 0x008, 0x302, 0x301 }; static const u16 udma_bits[] = { 0xE000, 0xC000, 0xA000 }; |
669a5db41 [libata] Add a bu... |
330 331 332 333 334 |
pci_read_config_word(pdev, drive_pci, &timing); if (adev->dma_mode < XFER_UDMA_0) { /* bits 3-0 hold recovery timing bits 8-10 active timing and |
25985edce Fix common misspe... |
335 |
the higher bits are dependent on the device */ |
4761c06cb pata_sis: fix MWD... |
336 |
timing &= ~0x870F; |
669a5db41 [libata] Add a bu... |
337 |
timing |= mwdma_bits[speed]; |
669a5db41 [libata] Add a bu... |
338 339 340 341 342 343 |
} else { /* Bit 15 is UDMA on/off, bit 13-14 are cycle time */ speed = adev->dma_mode - XFER_UDMA_0; timing &= ~0x6000; timing |= udma_bits[speed]; } |
4761c06cb pata_sis: fix MWD... |
344 |
pci_write_config_word(pdev, drive_pci, timing); |
669a5db41 [libata] Add a bu... |
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
} /** * sis_66_set_dmamode - Initialize host controller PATA DMA timings * @ap: Port whose timings we are configuring * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. * Handles UDMA66 and early UDMA100 devices. Supports MWDMA as well unlike * the old ide/pci driver. * * LOCKING: * None (inherited from caller). */ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
362 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
669a5db41 [libata] Add a bu... |
363 |
int speed = adev->dma_mode - XFER_MW_DMA_0; |
dd668d150 pata_sis: Fix and... |
364 |
int drive_pci = sis_old_port_base(adev); |
669a5db41 [libata] Add a bu... |
365 |
u16 timing; |
edeb614c1 pata_sis: add mis... |
366 |
/* MWDMA 0-2 and UDMA 0-5 */ |
c03a476dd pata_sis: mark mo... |
367 368 |
static const u16 mwdma_bits[] = { 0x008, 0x302, 0x301 }; static const u16 udma_bits[] = { 0xF000, 0xD000, 0xB000, 0xA000, 0x9000, 0x8000 }; |
669a5db41 [libata] Add a bu... |
369 370 371 372 373 |
pci_read_config_word(pdev, drive_pci, &timing); if (adev->dma_mode < XFER_UDMA_0) { /* bits 3-0 hold recovery timing bits 8-10 active timing and |
25985edce Fix common misspe... |
374 |
the higher bits are dependent on the device, bit 15 udma */ |
dd668d150 pata_sis: Fix and... |
375 |
timing &= ~0x870F; |
669a5db41 [libata] Add a bu... |
376 377 378 379 |
timing |= mwdma_bits[speed]; } else { /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ speed = adev->dma_mode - XFER_UDMA_0; |
dd668d150 pata_sis: Fix and... |
380 |
timing &= ~0xF000; |
669a5db41 [libata] Add a bu... |
381 382 383 384 385 386 387 388 389 390 391 |
timing |= udma_bits[speed]; } pci_write_config_word(pdev, drive_pci, timing); } /** * sis_100_set_dmamode - Initialize host controller PATA DMA timings * @ap: Port whose timings we are configuring * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. |
1b52f2a41 Revert "pata_sis:... |
392 |
* Handles UDMA66 and early UDMA100 devices. |
669a5db41 [libata] Add a bu... |
393 394 395 396 397 398 399 |
* * LOCKING: * None (inherited from caller). */ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
400 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
669a5db41 [libata] Add a bu... |
401 |
int speed = adev->dma_mode - XFER_MW_DMA_0; |
dd668d150 pata_sis: Fix and... |
402 |
int drive_pci = sis_old_port_base(adev); |
1b52f2a41 Revert "pata_sis:... |
403 |
u8 timing; |
669a5db41 [libata] Add a bu... |
404 |
|
c03a476dd pata_sis: mark mo... |
405 |
static const u8 udma_bits[] = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81}; |
669a5db41 [libata] Add a bu... |
406 |
|
1b52f2a41 Revert "pata_sis:... |
407 |
pci_read_config_byte(pdev, drive_pci + 1, &timing); |
669a5db41 [libata] Add a bu... |
408 409 |
if (adev->dma_mode < XFER_UDMA_0) { |
1b52f2a41 Revert "pata_sis:... |
410 |
/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ |
669a5db41 [libata] Add a bu... |
411 |
} else { |
dd668d150 pata_sis: Fix and... |
412 |
/* Bit 7 is UDMA on/off, bit 0-3 are cycle time */ |
669a5db41 [libata] Add a bu... |
413 |
speed = adev->dma_mode - XFER_UDMA_0; |
1b52f2a41 Revert "pata_sis:... |
414 |
timing &= ~0x8F; |
669a5db41 [libata] Add a bu... |
415 416 |
timing |= udma_bits[speed]; } |
1b52f2a41 Revert "pata_sis:... |
417 |
pci_write_config_byte(pdev, drive_pci + 1, timing); |
669a5db41 [libata] Add a bu... |
418 419 420 421 422 423 424 425 |
} /** * sis_133_early_set_dmamode - Initialize host controller PATA DMA timings * @ap: Port whose timings we are configuring * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. |
4761c06cb pata_sis: fix MWD... |
426 |
* Handles early SiS 961 bridges. |
669a5db41 [libata] Add a bu... |
427 428 429 430 431 432 433 |
* * LOCKING: * None (inherited from caller). */ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
434 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
669a5db41 [libata] Add a bu... |
435 |
int speed = adev->dma_mode - XFER_MW_DMA_0; |
dd668d150 pata_sis: Fix and... |
436 |
int drive_pci = sis_old_port_base(adev); |
1b52f2a41 Revert "pata_sis:... |
437 438 439 |
u8 timing; /* Low 4 bits are timing */ static const u8 udma_bits[] = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81}; |
669a5db41 [libata] Add a bu... |
440 |
|
1b52f2a41 Revert "pata_sis:... |
441 |
pci_read_config_byte(pdev, drive_pci + 1, &timing); |
669a5db41 [libata] Add a bu... |
442 443 |
if (adev->dma_mode < XFER_UDMA_0) { |
1b52f2a41 Revert "pata_sis:... |
444 |
/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ |
669a5db41 [libata] Add a bu... |
445 |
} else { |
dd668d150 pata_sis: Fix and... |
446 |
/* Bit 7 is UDMA on/off, bit 0-3 are cycle time */ |
669a5db41 [libata] Add a bu... |
447 |
speed = adev->dma_mode - XFER_UDMA_0; |
1b52f2a41 Revert "pata_sis:... |
448 |
timing &= ~0x8F; |
669a5db41 [libata] Add a bu... |
449 450 |
timing |= udma_bits[speed]; } |
1b52f2a41 Revert "pata_sis:... |
451 |
pci_write_config_byte(pdev, drive_pci + 1, timing); |
669a5db41 [libata] Add a bu... |
452 453 454 455 456 457 458 459 |
} /** * sis_133_set_dmamode - Initialize host controller PATA DMA timings * @ap: Port whose timings we are configuring * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. |
669a5db41 [libata] Add a bu... |
460 461 462 463 464 465 466 |
* * LOCKING: * None (inherited from caller). */ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev) { |
edc7d12ed pata_sis: code st... |
467 |
struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
023a0175a pata_sis: extract... |
468 |
int port; |
669a5db41 [libata] Add a bu... |
469 |
u32 t1; |
669a5db41 [libata] Add a bu... |
470 |
|
023a0175a pata_sis: extract... |
471 |
port = sis_port_base(adev); |
669a5db41 [libata] Add a bu... |
472 473 474 |
pci_read_config_dword(pdev, port, &t1); if (adev->dma_mode < XFER_UDMA_0) { |
14004f044 pata_sis: enable ... |
475 476 477 478 479 480 481 |
/* Recovery << 24 | Act << 16 | Ini << 12, like PIO modes */ static const u32 timing_u100[] = { 0x19154000, 0x06072000, 0x04062000 }; static const u32 timing_u133[] = { 0x221C6000, 0x0C0A3000, 0x05093000 }; int speed = adev->dma_mode - XFER_MW_DMA_0; t1 &= 0xC0C00FFF; /* disable UDMA */ |
1b52f2a41 Revert "pata_sis:... |
482 |
t1 &= ~0x00000004; |
14004f044 pata_sis: enable ... |
483 484 485 486 |
if (t1 & 0x08) t1 |= timing_u133[speed]; else t1 |= timing_u100[speed]; |
669a5db41 [libata] Add a bu... |
487 |
} else { |
14004f044 pata_sis: enable ... |
488 489 490 |
/* bits 4- cycle time 8 - cvs time */ static const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 }; static const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 }; |
023a0175a pata_sis: extract... |
491 |
int speed = adev->dma_mode - XFER_UDMA_0; |
14004f044 pata_sis: enable ... |
492 |
|
669a5db41 [libata] Add a bu... |
493 |
t1 &= ~0x00000FF0; |
14004f044 pata_sis: enable ... |
494 |
/* enable UDMA */ |
669a5db41 [libata] Add a bu... |
495 496 497 498 499 500 501 502 |
t1 |= 0x00000004; if (t1 & 0x08) t1 |= timing_u133[speed]; else t1 |= timing_u100[speed]; } pci_write_config_dword(pdev, port, t1); } |
f30f9a5e7 pata_sis: add mod... |
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
/** * sis_133_mode_filter - mode selection filter * @adev: ATA device * * Block UDMA6 on devices that do not support it. */ static unsigned long sis_133_mode_filter(struct ata_device *adev, unsigned long mask) { struct ata_port *ap = adev->link->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); int port = sis_port_base(adev); u32 t1; pci_read_config_dword(pdev, port, &t1); /* if ATA133 is disabled, mask it out */ if (!(t1 & 0x08)) mask &= ~(0xC0 << ATA_SHIFT_UDMA); return mask; } |
669a5db41 [libata] Add a bu... |
523 |
static struct scsi_host_template sis_sht = { |
68d1d07b5 libata: implement... |
524 |
ATA_BMDMA_SHT(DRV_NAME), |
669a5db41 [libata] Add a bu... |
525 |
}; |
029cfd6b7 libata: implement... |
526 527 |
static struct ata_port_operations sis_133_for_sata_ops = { .inherits = &ata_bmdma_port_ops, |
669a5db41 [libata] Add a bu... |
528 529 |
.set_piomode = sis_133_set_piomode, .set_dmamode = sis_133_set_dmamode, |
2e413f510 pata_sis: Clean u... |
530 |
.cable_detect = sis_133_cable_detect, |
029cfd6b7 libata: implement... |
531 |
}; |
669a5db41 [libata] Add a bu... |
532 |
|
029cfd6b7 libata: implement... |
533 534 |
static struct ata_port_operations sis_base_ops = { .inherits = &ata_bmdma_port_ops, |
a1efdaba2 libata: make rese... |
535 |
.prereset = sis_pre_reset, |
669a5db41 [libata] Add a bu... |
536 |
}; |
029cfd6b7 libata: implement... |
537 538 |
static struct ata_port_operations sis_133_ops = { .inherits = &sis_base_ops, |
a3cabb271 libata: PATA-mode... |
539 540 |
.set_piomode = sis_133_set_piomode, .set_dmamode = sis_133_set_dmamode, |
a3cabb271 libata: PATA-mode... |
541 |
.cable_detect = sis_133_cable_detect, |
f30f9a5e7 pata_sis: add mod... |
542 |
.mode_filter = sis_133_mode_filter, |
a3cabb271 libata: PATA-mode... |
543 |
}; |
029cfd6b7 libata: implement... |
544 545 |
static struct ata_port_operations sis_133_early_ops = { .inherits = &sis_base_ops, |
669a5db41 [libata] Add a bu... |
546 547 |
.set_piomode = sis_100_set_piomode, .set_dmamode = sis_133_early_set_dmamode, |
2e413f510 pata_sis: Clean u... |
548 |
.cable_detect = sis_66_cable_detect, |
669a5db41 [libata] Add a bu... |
549 |
}; |
029cfd6b7 libata: implement... |
550 551 |
static struct ata_port_operations sis_100_ops = { .inherits = &sis_base_ops, |
669a5db41 [libata] Add a bu... |
552 553 |
.set_piomode = sis_100_set_piomode, .set_dmamode = sis_100_set_dmamode, |
2e413f510 pata_sis: Clean u... |
554 |
.cable_detect = sis_66_cable_detect, |
669a5db41 [libata] Add a bu... |
555 |
}; |
029cfd6b7 libata: implement... |
556 557 |
static struct ata_port_operations sis_66_ops = { .inherits = &sis_base_ops, |
669a5db41 [libata] Add a bu... |
558 559 |
.set_piomode = sis_old_set_piomode, .set_dmamode = sis_66_set_dmamode, |
2e413f510 pata_sis: Clean u... |
560 |
.cable_detect = sis_66_cable_detect, |
669a5db41 [libata] Add a bu... |
561 |
}; |
029cfd6b7 libata: implement... |
562 563 |
static struct ata_port_operations sis_old_ops = { .inherits = &sis_base_ops, |
669a5db41 [libata] Add a bu... |
564 565 |
.set_piomode = sis_old_set_piomode, .set_dmamode = sis_old_set_dmamode, |
2e413f510 pata_sis: Clean u... |
566 |
.cable_detect = ata_cable_40wire, |
669a5db41 [libata] Add a bu... |
567 |
}; |
1626aeb88 libata: clean up ... |
568 |
static const struct ata_port_info sis_info = { |
1d2808fd3 [libata] PATA dri... |
569 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
570 571 572 |
.pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, /* No UDMA */ |
669a5db41 [libata] Add a bu... |
573 574 |
.port_ops = &sis_old_ops, }; |
1626aeb88 libata: clean up ... |
575 |
static const struct ata_port_info sis_info33 = { |
1d2808fd3 [libata] PATA dri... |
576 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
577 578 579 |
.pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, |
669a5db41 [libata] Add a bu... |
580 581 |
.port_ops = &sis_old_ops, }; |
1626aeb88 libata: clean up ... |
582 |
static const struct ata_port_info sis_info66 = { |
1d2808fd3 [libata] PATA dri... |
583 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
584 585 586 |
.pio_mask = ATA_PIO4, /* No MWDMA */ .udma_mask = ATA_UDMA4, |
669a5db41 [libata] Add a bu... |
587 588 |
.port_ops = &sis_66_ops, }; |
1626aeb88 libata: clean up ... |
589 |
static const struct ata_port_info sis_info100 = { |
1d2808fd3 [libata] PATA dri... |
590 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
591 592 |
.pio_mask = ATA_PIO4, /* No MWDMA */ |
669a5db41 [libata] Add a bu... |
593 594 595 |
.udma_mask = ATA_UDMA5, .port_ops = &sis_100_ops, }; |
1626aeb88 libata: clean up ... |
596 |
static const struct ata_port_info sis_info100_early = { |
1d2808fd3 [libata] PATA dri... |
597 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
598 599 |
.pio_mask = ATA_PIO4, /* No MWDMA */ |
669a5db41 [libata] Add a bu... |
600 |
.udma_mask = ATA_UDMA5, |
669a5db41 [libata] Add a bu... |
601 602 |
.port_ops = &sis_66_ops, }; |
a3cabb271 libata: PATA-mode... |
603 |
static const struct ata_port_info sis_info133 = { |
1d2808fd3 [libata] PATA dri... |
604 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
605 |
.pio_mask = ATA_PIO4, |
14004f044 pata_sis: enable ... |
606 |
.mwdma_mask = ATA_MWDMA2, |
669a5db41 [libata] Add a bu... |
607 608 609 |
.udma_mask = ATA_UDMA6, .port_ops = &sis_133_ops, }; |
a3cabb271 libata: PATA-mode... |
610 |
const struct ata_port_info sis_info133_for_sata = { |
c10f97b9d libata: remove AT... |
611 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
612 613 |
.pio_mask = ATA_PIO4, /* No MWDMA */ |
a3cabb271 libata: PATA-mode... |
614 615 616 |
.udma_mask = ATA_UDMA6, .port_ops = &sis_133_for_sata_ops, }; |
1626aeb88 libata: clean up ... |
617 |
static const struct ata_port_info sis_info133_early = { |
1d2808fd3 [libata] PATA dri... |
618 |
.flags = ATA_FLAG_SLAVE_POSS, |
14bdef982 [libata] convert ... |
619 620 |
.pio_mask = ATA_PIO4, /* No MWDMA */ |
669a5db41 [libata] Add a bu... |
621 622 623 |
.udma_mask = ATA_UDMA6, .port_ops = &sis_133_early_ops, }; |
9b14dec5a sata_sis: Support... |
624 |
/* Privately shared with the SiS180 SATA driver, not for use elsewhere */ |
a3cabb271 libata: PATA-mode... |
625 |
EXPORT_SYMBOL_GPL(sis_info133_for_sata); |
669a5db41 [libata] Add a bu... |
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis) { u16 regw; u8 reg; if (sis->info == &sis_info133) { pci_read_config_word(pdev, 0x50, ®w); if (regw & 0x08) pci_write_config_word(pdev, 0x50, regw & ~0x08); pci_read_config_word(pdev, 0x52, ®w); if (regw & 0x08) pci_write_config_word(pdev, 0x52, regw & ~0x08); return; } if (sis->info == &sis_info133_early || sis->info == &sis_info100) { /* Fix up latency */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); /* Set compatibility bit */ pci_read_config_byte(pdev, 0x49, ®); if (!(reg & 0x01)) pci_write_config_byte(pdev, 0x49, reg | 0x01); return; } if (sis->info == &sis_info66 || sis->info == &sis_info100_early) { /* Fix up latency */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80); /* Set compatibility bit */ pci_read_config_byte(pdev, 0x52, ®); if (!(reg & 0x04)) pci_write_config_byte(pdev, 0x52, reg | 0x04); return; } if (sis->info == &sis_info33) { pci_read_config_byte(pdev, PCI_CLASS_PROG, ®); if (( reg & 0x0F ) != 0x00) pci_write_config_byte(pdev, PCI_CLASS_PROG, reg & 0xF0); /* Fall through to ATA16 fixup below */ } if (sis->info == &sis_info || sis->info == &sis_info33) { /* force per drive recovery and active timings needed on ATA_33 and below chips */ pci_read_config_byte(pdev, 0x52, ®); if (!(reg & 0x08)) pci_write_config_byte(pdev, 0x52, reg|0x08); return; } BUG(); } /** * sis_init_one - Register SiS ATA PCI device with kernel services * @pdev: PCI device to register * @ent: Entry in sis_pci_tbl matching with @pdev * |
edc7d12ed pata_sis: code st... |
686 |
* Called from kernel PCI layer. We probe for combined mode (sigh), |
669a5db41 [libata] Add a bu... |
687 688 689 690 691 692 693 694 695 696 697 |
* and then hand over control to libata, for it to do the rest. * * LOCKING: * Inherited from PCI layer (may sleep). * * RETURNS: * Zero on success, or -ERRNO value. */ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { |
887125e37 libata: stop over... |
698 |
const struct ata_port_info *ppi[] = { NULL, NULL }; |
669a5db41 [libata] Add a bu... |
699 700 |
struct pci_dev *host = NULL; struct sis_chipset *chipset = NULL; |
f3769e9db pata_sis: Fix oop... |
701 |
struct sis_chipset *sets; |
f08048e94 libata: PCI devic... |
702 |
int rc; |
669a5db41 [libata] Add a bu... |
703 704 |
static struct sis_chipset sis_chipsets[] = { |
f20b16ff7 [libata] trim tra... |
705 |
|
af323a2fb [PATCH] Update Si... |
706 707 708 |
{ 0x0968, &sis_info133 }, { 0x0966, &sis_info133 }, { 0x0965, &sis_info133 }, |
669a5db41 [libata] Add a bu... |
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 |
{ 0x0745, &sis_info100 }, { 0x0735, &sis_info100 }, { 0x0733, &sis_info100 }, { 0x0635, &sis_info100 }, { 0x0633, &sis_info100 }, { 0x0730, &sis_info100_early }, /* 100 with ATA 66 layout */ { 0x0550, &sis_info100_early }, /* 100 with ATA 66 layout */ { 0x0640, &sis_info66 }, { 0x0630, &sis_info66 }, { 0x0620, &sis_info66 }, { 0x0540, &sis_info66 }, { 0x0530, &sis_info66 }, { 0x5600, &sis_info33 }, { 0x5598, &sis_info33 }, { 0x5597, &sis_info33 }, { 0x5591, &sis_info33 }, { 0x5582, &sis_info33 }, { 0x5581, &sis_info33 }, { 0x5596, &sis_info }, { 0x5571, &sis_info }, { 0x5517, &sis_info }, { 0x5511, &sis_info }, {0} }; static struct sis_chipset sis133_early = { 0x0, &sis_info133_early }; static struct sis_chipset sis133 = { 0x0, &sis_info133 }; static struct sis_chipset sis100_early = { 0x0, &sis_info100_early }; static struct sis_chipset sis100 = { 0x0, &sis_info100 }; |
06296a1e6 ata: Add and use ... |
750 |
ata_print_version_once(&pdev->dev, DRV_VERSION); |
669a5db41 [libata] Add a bu... |
751 |
|
f08048e94 libata: PCI devic... |
752 753 754 |
rc = pcim_enable_device(pdev); if (rc) return rc; |
669a5db41 [libata] Add a bu... |
755 |
|
f08048e94 libata: PCI devic... |
756 |
/* We have to find the bridge first */ |
f3769e9db pata_sis: Fix oop... |
757 758 |
for (sets = &sis_chipsets[0]; sets->device; sets++) { host = pci_get_device(PCI_VENDOR_ID_SI, sets->device, NULL); |
669a5db41 [libata] Add a bu... |
759 |
if (host != NULL) { |
f3769e9db pata_sis: Fix oop... |
760 761 |
chipset = sets; /* Match found */ if (sets->device == 0x630) { /* SIS630 */ |
44c10138f PCI: Change all d... |
762 |
if (host->revision >= 0x30) /* 630 ET */ |
669a5db41 [libata] Add a bu... |
763 764 765 766 767 768 769 |
chipset = &sis100_early; } break; } } /* Look for concealed bridges */ |
f3769e9db pata_sis: Fix oop... |
770 |
if (chipset == NULL) { |
669a5db41 [libata] Add a bu... |
771 772 773 774 775 776 777 778 779 780 781 782 783 784 |
/* Second check */ u32 idemisc; u16 trueid; /* Disable ID masking and register remapping then see what the real ID is */ pci_read_config_dword(pdev, 0x54, &idemisc); pci_write_config_dword(pdev, 0x54, idemisc & 0x7fffffff); pci_read_config_word(pdev, PCI_DEVICE_ID, &trueid); pci_write_config_dword(pdev, 0x54, idemisc); switch(trueid) { case 0x5518: /* SIS 962/963 */ |
f30f9a5e7 pata_sis: add mod... |
785 786 787 |
dev_info(&pdev->dev, "SiS 962/963 MuTIOL IDE UDMA133 controller "); |
669a5db41 [libata] Add a bu... |
788 789 790 |
chipset = &sis133; if ((idemisc & 0x40000000) == 0) { pci_write_config_dword(pdev, 0x54, idemisc | 0x40000000); |
f30f9a5e7 pata_sis: add mod... |
791 792 793 |
dev_info(&pdev->dev, "Switching to 5513 register mapping "); |
669a5db41 [libata] Add a bu... |
794 795 796 |
} break; case 0x0180: /* SIS 965/965L */ |
edc7d12ed pata_sis: code st... |
797 |
chipset = &sis133; |
669a5db41 [libata] Add a bu... |
798 799 |
break; case 0x1180: /* SIS 966/966L */ |
edc7d12ed pata_sis: code st... |
800 |
chipset = &sis133; |
669a5db41 [libata] Add a bu... |
801 802 803 804 805 806 807 808 809 810 |
break; } } /* Further check */ if (chipset == NULL) { struct pci_dev *lpc_bridge; u16 trueid; u8 prefctl; u8 idecfg; |
669a5db41 [libata] Add a bu... |
811 812 813 814 815 816 817 818 819 820 821 822 |
/* Try the second unmasking technique */ pci_read_config_byte(pdev, 0x4a, &idecfg); pci_write_config_byte(pdev, 0x4a, idecfg | 0x10); pci_read_config_word(pdev, PCI_DEVICE_ID, &trueid); pci_write_config_byte(pdev, 0x4a, idecfg); switch(trueid) { case 0x5517: lpc_bridge = pci_get_slot(pdev->bus, 0x10); /* Bus 0 Dev 2 Fn 0 */ if (lpc_bridge == NULL) break; |
669a5db41 [libata] Add a bu... |
823 824 |
pci_read_config_byte(pdev, 0x49, &prefctl); pci_dev_put(lpc_bridge); |
44c10138f PCI: Change all d... |
825 |
if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) { |
669a5db41 [libata] Add a bu... |
826 827 828 829 830 831 832 833 834 835 836 837 |
chipset = &sis133_early; break; } chipset = &sis100; break; } } pci_dev_put(host); /* No chipset info, no support */ if (chipset == NULL) return -ENODEV; |
887125e37 libata: stop over... |
838 |
ppi[0] = chipset->info; |
669a5db41 [libata] Add a bu... |
839 840 |
sis_fixup(pdev, chipset); |
1c5afdf7a libata-sff: separ... |
841 |
return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset, 0); |
669a5db41 [libata] Add a bu... |
842 |
} |
58eb8cd56 ata: use CONFIG_P... |
843 |
#ifdef CONFIG_PM_SLEEP |
750c7136e pata_sis: Power M... |
844 845 |
static int sis_reinit_one(struct pci_dev *pdev) { |
0a86e1c85 ata: use pci_get_... |
846 |
struct ata_host *host = pci_get_drvdata(pdev); |
750c7136e pata_sis: Power M... |
847 848 849 850 851 852 853 854 855 856 857 858 |
int rc; rc = ata_pci_device_do_resume(pdev); if (rc) return rc; sis_fixup(pdev, host->private_data); ata_host_resume(host); return 0; } #endif |
669a5db41 [libata] Add a bu... |
859 |
static const struct pci_device_id sis_pci_tbl[] = { |
2d2744fc8 [libata] PCI ID t... |
860 861 |
{ PCI_VDEVICE(SI, 0x5513), }, /* SiS 5513 */ { PCI_VDEVICE(SI, 0x5518), }, /* SiS 5518 */ |
a3cabb271 libata: PATA-mode... |
862 |
{ PCI_VDEVICE(SI, 0x1180), }, /* SiS 1180 */ |
2d2744fc8 [libata] PCI ID t... |
863 |
|
669a5db41 [libata] Add a bu... |
864 865 866 867 868 869 870 871 |
{ } }; static struct pci_driver sis_pci_driver = { .name = DRV_NAME, .id_table = sis_pci_tbl, .probe = sis_init_one, .remove = ata_pci_remove_one, |
58eb8cd56 ata: use CONFIG_P... |
872 |
#ifdef CONFIG_PM_SLEEP |
62d64ae0e [PATCH] pata : mo... |
873 |
.suspend = ata_pci_device_suspend, |
750c7136e pata_sis: Power M... |
874 |
.resume = sis_reinit_one, |
438ac6d5e libata: add missi... |
875 |
#endif |
669a5db41 [libata] Add a bu... |
876 |
}; |
2fc75da0c ata: use module_p... |
877 |
module_pci_driver(sis_pci_driver); |
669a5db41 [libata] Add a bu... |
878 879 880 881 882 883 |
MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("SCSI low-level driver for SiS ATA"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sis_pci_tbl); MODULE_VERSION(DRV_VERSION); |