Blame view

drivers/ata/pata_sis.c 23.5 KB
669a5db41   Jeff Garzik   [libata] Add a bu...
1
2
3
  /*
   *    pata_sis.c - SiS ATA driver
   *
ab7716300   Alan Cox   ata: Switch all m...
4
   *	(C) 2005 Red Hat
750c7136e   Bartlomiej Zolnierkiewicz   pata_sis: Power M...
5
   *	(C) 2007,2009 Bartlomiej Zolnierkiewicz
669a5db41   Jeff Garzik   [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   Jeff Garzik   [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   Alan Cox   SiS warning fixes
35
  #include "sis.h"
669a5db41   Jeff Garzik   [libata] Add a bu...
36
37
  
  #define DRV_NAME	"pata_sis"
4761c06cb   Bartlomiej Zolnierkiewicz   pata_sis: fix MWD...
38
  #define DRV_VERSION	"0.5.2"
669a5db41   Jeff Garzik   [libata] Add a bu...
39
40
  
  struct sis_chipset {
1626aeb88   Tejun Heo   libata: clean up ...
41
42
  	u16 device;				/* PCI host ID */
  	const struct ata_port_info *info;	/* Info block */
669a5db41   Jeff Garzik   [libata] Add a bu...
43
44
45
  	/* Probably add family, cable detect type etc here to clean
  	   up code later */
  };
7dcbc1f2c   Jakub W. Jozwicki J   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   Alan Cox   pata_sis: Add the...
55
  	{ 0x5513, 0x1734, 0x105F },	/* FSC Amilo A1630 */
edc7d12ed   Dan McGee   pata_sis: code st...
56
  	{ 0x5513, 0x1071, 0x8640 },	/* EasyNote K5305 */
7dcbc1f2c   Jakub W. Jozwicki J   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   Jeff Garzik   [libata] Add a bu...
75
  /**
edc7d12ed   Dan McGee   pata_sis: code st...
76
   *	sis_old_port_base - return PCI configuration base for dev
669a5db41   Jeff Garzik   [libata] Add a bu...
77
78
79
80
81
   *	@adev: device
   *
   *	Returns the base of the PCI configuration registers for this port
   *	number.
   */
dd668d150   Alan Cox   pata_sis: Fix and...
82
  static int sis_old_port_base(struct ata_device *adev)
669a5db41   Jeff Garzik   [libata] Add a bu...
83
  {
edc7d12ed   Dan McGee   pata_sis: code st...
84
  	return 0x40 + (4 * adev->link->ap->port_no) + (2 * adev->devno);
669a5db41   Jeff Garzik   [libata] Add a bu...
85
86
87
  }
  
  /**
edc7d12ed   Dan McGee   pata_sis: code st...
88
   *	sis_port_base - return PCI configuration base for dev
023a0175a   Dan McGee   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, &reg54);
  	if (reg54 & 0x40000000)
  		port = 0x70;
  
  	return port + (8 * ap->port_no) + (4 * adev->devno);
  }
  
  /**
edc7d12ed   Dan McGee   pata_sis: code st...
111
   *	sis_133_cable_detect - check for 40/80 pin
669a5db41   Jeff Garzik   [libata] Add a bu...
112
   *	@ap: Port
d4b2bab4f   Tejun Heo   libata: add deadl...
113
   *	@deadline: deadline jiffies for the operation
669a5db41   Jeff Garzik   [libata] Add a bu...
114
115
116
117
   *
   *	Perform cable detection for the later UDMA133 capable
   *	SiS chipset.
   */
2e413f510   Alan Cox   pata_sis: Clean u...
118
  static int sis_133_cable_detect(struct ata_port *ap)
669a5db41   Jeff Garzik   [libata] Add a bu...
119
  {
669a5db41   Jeff Garzik   [libata] Add a bu...
120
121
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	u16 tmp;
669a5db41   Jeff Garzik   [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   Jakub W. Jozwicki J   pata_sis: impleme...
124
  	if ((tmp & 0x8000) && !sis_short_ata40(pdev))
2e413f510   Alan Cox   pata_sis: Clean u...
125
126
  		return ATA_CBL_PATA40;
  	return ATA_CBL_PATA80;
669a5db41   Jeff Garzik   [libata] Add a bu...
127
128
129
  }
  
  /**
edc7d12ed   Dan McGee   pata_sis: code st...
130
   *	sis_66_cable_detect - check for 40/80 pin
669a5db41   Jeff Garzik   [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   Alan Cox   pata_sis: Clean u...
136
  static int sis_66_cable_detect(struct ata_port *ap)
669a5db41   Jeff Garzik   [libata] Add a bu...
137
  {
669a5db41   Jeff Garzik   [libata] Add a bu...
138
139
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  	u8 tmp;
669a5db41   Jeff Garzik   [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   Jakub W. Jozwicki J   pata_sis: impleme...
143
  	if ((tmp & 0x10) && !sis_short_ata40(pdev))
2e413f510   Alan Cox   pata_sis: Clean u...
144
145
  		return ATA_CBL_PATA40;
  	return ATA_CBL_PATA80;
669a5db41   Jeff Garzik   [libata] Add a bu...
146
  }
669a5db41   Jeff Garzik   [libata] Add a bu...
147
148
  
  /**
edc7d12ed   Dan McGee   pata_sis: code st...
149
   *	sis_pre_reset - probe begin
cc0680a58   Tejun Heo   libata-link: link...
150
   *	@link: ATA link
d4b2bab4f   Tejun Heo   libata: add deadl...
151
   *	@deadline: deadline jiffies for the operation
669a5db41   Jeff Garzik   [libata] Add a bu...
152
153
154
   *
   *	Set up cable type and use generic probe init
   */
cc0680a58   Tejun Heo   libata-link: link...
155
  static int sis_pre_reset(struct ata_link *link, unsigned long deadline)
669a5db41   Jeff Garzik   [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   Jeff Garzik   [libata #pata-dri...
161

cc0680a58   Tejun Heo   libata-link: link...
162
  	struct ata_port *ap = link->ap;
669a5db41   Jeff Garzik   [libata] Add a bu...
163
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
2e413f510   Alan Cox   pata_sis: Clean u...
164
165
  	if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
  		return -ENOENT;
d4b2bab4f   Tejun Heo   libata: add deadl...
166

15ce09432   Alan Cox   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   Tejun Heo   libata: rename SF...
170
  	return ata_sff_prereset(link, deadline);
669a5db41   Jeff Garzik   [libata] Add a bu...
171
172
173
174
  }
  
  
  /**
edc7d12ed   Dan McGee   pata_sis: code st...
175
   *	sis_set_fifo - Set RWP fifo bits for this device
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
218
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
dd668d150   Alan Cox   pata_sis: Fix and...
219
  	int port = sis_old_port_base(adev);
669a5db41   Jeff Garzik   [libata] Add a bu...
220
221
  	u8 t1, t2;
  	int speed = adev->pio_mode - XFER_PIO_0;
c03a476dd   Dan McGee   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   Jeff Garzik   [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   Bartlomiej Zolnierkiewicz   pata_sis: fix MWD...
241
   *	sis_100_set_piomode - Initialize host controller PATA PIO timings
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
254
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
dd668d150   Alan Cox   pata_sis: Fix and...
255
  	int port = sis_old_port_base(adev);
669a5db41   Jeff Garzik   [libata] Add a bu...
256
  	int speed = adev->pio_mode - XFER_PIO_0;
c03a476dd   Dan McGee   pata_sis: mark mo...
257
  	static const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
669a5db41   Jeff Garzik   [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   Jeff Garzik   Revert "pata_sis:...
265
   *	sis_133_set_piomode - Initialize host controller PATA PIO timings
669a5db41   Jeff Garzik   [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   Jeff Garzik   Revert "pata_sis:...
270
   *	function handles PIO set up for the later ATA133 devices.
669a5db41   Jeff Garzik   [libata] Add a bu...
271
272
273
274
   *
   *	LOCKING:
   *	None (inherited from caller).
   */
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
275
  static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev)
669a5db41   Jeff Garzik   [libata] Add a bu...
276
  {
edc7d12ed   Dan McGee   pata_sis: code st...
277
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
023a0175a   Dan McGee   pata_sis: extract...
278
  	int port;
669a5db41   Jeff Garzik   [libata] Add a bu...
279
  	u32 t1;
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
280
  	int speed = adev->pio_mode - XFER_PIO_0;
669a5db41   Jeff Garzik   [libata] Add a bu...
281

c03a476dd   Dan McGee   pata_sis: mark mo...
282
  	static const u32 timing133[] = {
669a5db41   Jeff Garzik   [libata] Add a bu...
283
284
285
286
287
288
  		0x28269000,	/* Recovery << 24 | Act << 16 | Ini << 12 */
  		0x0C266000,
  		0x04263000,
  		0x0C0A3000,
  		0x05093000
  	};
c03a476dd   Dan McGee   pata_sis: mark mo...
289
  	static const u32 timing100[] = {
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: extract...
298
  	port = sis_port_base(adev);
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
324
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
669a5db41   Jeff Garzik   [libata] Add a bu...
325
  	int speed = adev->dma_mode - XFER_MW_DMA_0;
dd668d150   Alan Cox   pata_sis: Fix and...
326
  	int drive_pci = sis_old_port_base(adev);
669a5db41   Jeff Garzik   [libata] Add a bu...
327
  	u16 timing;
c03a476dd   Dan McGee   pata_sis: mark mo...
328
329
  	static const u16 mwdma_bits[] = { 0x008, 0x302, 0x301 };
  	static const u16 udma_bits[]  = { 0xE000, 0xC000, 0xA000 };
669a5db41   Jeff Garzik   [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   Lucas De Marchi   Fix common misspe...
335
  		   the higher bits are dependent on the device */
4761c06cb   Bartlomiej Zolnierkiewicz   pata_sis: fix MWD...
336
  		timing &= ~0x870F;
669a5db41   Jeff Garzik   [libata] Add a bu...
337
  		timing |= mwdma_bits[speed];
669a5db41   Jeff Garzik   [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   Bartlomiej Zolnierkiewicz   pata_sis: fix MWD...
344
  	pci_write_config_word(pdev, drive_pci, timing);
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
362
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
669a5db41   Jeff Garzik   [libata] Add a bu...
363
  	int speed = adev->dma_mode - XFER_MW_DMA_0;
dd668d150   Alan Cox   pata_sis: Fix and...
364
  	int drive_pci = sis_old_port_base(adev);
669a5db41   Jeff Garzik   [libata] Add a bu...
365
  	u16 timing;
edeb614c1   Tejun Heo   pata_sis: add mis...
366
  	/* MWDMA 0-2 and UDMA 0-5 */
c03a476dd   Dan McGee   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   Jeff Garzik   [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   Lucas De Marchi   Fix common misspe...
374
  		   the higher bits are dependent on the device, bit 15 udma */
dd668d150   Alan Cox   pata_sis: Fix and...
375
  		timing &= ~0x870F;
669a5db41   Jeff Garzik   [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   Alan Cox   pata_sis: Fix and...
380
  		timing &= ~0xF000;
669a5db41   Jeff Garzik   [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   Jeff Garzik   Revert "pata_sis:...
392
   *	Handles UDMA66 and early UDMA100 devices.
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
400
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
669a5db41   Jeff Garzik   [libata] Add a bu...
401
  	int speed = adev->dma_mode - XFER_MW_DMA_0;
dd668d150   Alan Cox   pata_sis: Fix and...
402
  	int drive_pci = sis_old_port_base(adev);
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
403
  	u8 timing;
669a5db41   Jeff Garzik   [libata] Add a bu...
404

c03a476dd   Dan McGee   pata_sis: mark mo...
405
  	static const u8 udma_bits[]  = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81};
669a5db41   Jeff Garzik   [libata] Add a bu...
406

1b52f2a41   Jeff Garzik   Revert "pata_sis:...
407
  	pci_read_config_byte(pdev, drive_pci + 1, &timing);
669a5db41   Jeff Garzik   [libata] Add a bu...
408
409
  
  	if (adev->dma_mode < XFER_UDMA_0) {
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
410
  		/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
669a5db41   Jeff Garzik   [libata] Add a bu...
411
  	} else {
dd668d150   Alan Cox   pata_sis: Fix and...
412
  		/* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
669a5db41   Jeff Garzik   [libata] Add a bu...
413
  		speed = adev->dma_mode - XFER_UDMA_0;
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
414
  		timing &= ~0x8F;
669a5db41   Jeff Garzik   [libata] Add a bu...
415
416
  		timing |= udma_bits[speed];
  	}
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
417
  	pci_write_config_byte(pdev, drive_pci + 1, timing);
669a5db41   Jeff Garzik   [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   Bartlomiej Zolnierkiewicz   pata_sis: fix MWD...
426
   *	Handles early SiS 961 bridges.
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
434
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
669a5db41   Jeff Garzik   [libata] Add a bu...
435
  	int speed = adev->dma_mode - XFER_MW_DMA_0;
dd668d150   Alan Cox   pata_sis: Fix and...
436
  	int drive_pci = sis_old_port_base(adev);
1b52f2a41   Jeff Garzik   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   Jeff Garzik   [libata] Add a bu...
440

1b52f2a41   Jeff Garzik   Revert "pata_sis:...
441
  	pci_read_config_byte(pdev, drive_pci + 1, &timing);
669a5db41   Jeff Garzik   [libata] Add a bu...
442
443
  
  	if (adev->dma_mode < XFER_UDMA_0) {
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
444
  		/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
669a5db41   Jeff Garzik   [libata] Add a bu...
445
  	} else {
dd668d150   Alan Cox   pata_sis: Fix and...
446
  		/* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
669a5db41   Jeff Garzik   [libata] Add a bu...
447
  		speed = adev->dma_mode - XFER_UDMA_0;
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
448
  		timing &= ~0x8F;
669a5db41   Jeff Garzik   [libata] Add a bu...
449
450
  		timing |= udma_bits[speed];
  	}
1b52f2a41   Jeff Garzik   Revert "pata_sis:...
451
  	pci_write_config_byte(pdev, drive_pci + 1, timing);
669a5db41   Jeff Garzik   [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   Jeff Garzik   [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   Dan McGee   pata_sis: code st...
467
  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
023a0175a   Dan McGee   pata_sis: extract...
468
  	int port;
669a5db41   Jeff Garzik   [libata] Add a bu...
469
  	u32 t1;
669a5db41   Jeff Garzik   [libata] Add a bu...
470

023a0175a   Dan McGee   pata_sis: extract...
471
  	port = sis_port_base(adev);
669a5db41   Jeff Garzik   [libata] Add a bu...
472
473
474
  	pci_read_config_dword(pdev, port, &t1);
  
  	if (adev->dma_mode < XFER_UDMA_0) {
14004f044   Dan McGee   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   Jeff Garzik   Revert "pata_sis:...
482
  		t1 &= ~0x00000004;
14004f044   Dan McGee   pata_sis: enable ...
483
484
485
486
  		if (t1 & 0x08)
  			t1 |= timing_u133[speed];
  		else
  			t1 |= timing_u100[speed];
669a5db41   Jeff Garzik   [libata] Add a bu...
487
  	} else {
14004f044   Dan McGee   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   Dan McGee   pata_sis: extract...
491
  		int speed = adev->dma_mode - XFER_UDMA_0;
14004f044   Dan McGee   pata_sis: enable ...
492

669a5db41   Jeff Garzik   [libata] Add a bu...
493
  		t1 &= ~0x00000FF0;
14004f044   Dan McGee   pata_sis: enable ...
494
  		/* enable UDMA */
669a5db41   Jeff Garzik   [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   Dan McGee   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   Jeff Garzik   [libata] Add a bu...
523
  static struct scsi_host_template sis_sht = {
68d1d07b5   Tejun Heo   libata: implement...
524
  	ATA_BMDMA_SHT(DRV_NAME),
669a5db41   Jeff Garzik   [libata] Add a bu...
525
  };
029cfd6b7   Tejun Heo   libata: implement...
526
527
  static struct ata_port_operations sis_133_for_sata_ops = {
  	.inherits		= &ata_bmdma_port_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
528
529
  	.set_piomode		= sis_133_set_piomode,
  	.set_dmamode		= sis_133_set_dmamode,
2e413f510   Alan Cox   pata_sis: Clean u...
530
  	.cable_detect		= sis_133_cable_detect,
029cfd6b7   Tejun Heo   libata: implement...
531
  };
669a5db41   Jeff Garzik   [libata] Add a bu...
532

029cfd6b7   Tejun Heo   libata: implement...
533
534
  static struct ata_port_operations sis_base_ops = {
  	.inherits		= &ata_bmdma_port_ops,
a1efdaba2   Tejun Heo   libata: make rese...
535
  	.prereset		= sis_pre_reset,
669a5db41   Jeff Garzik   [libata] Add a bu...
536
  };
029cfd6b7   Tejun Heo   libata: implement...
537
538
  static struct ata_port_operations sis_133_ops = {
  	.inherits		= &sis_base_ops,
a3cabb271   Uwe Koziolek   libata: PATA-mode...
539
540
  	.set_piomode		= sis_133_set_piomode,
  	.set_dmamode		= sis_133_set_dmamode,
a3cabb271   Uwe Koziolek   libata: PATA-mode...
541
  	.cable_detect		= sis_133_cable_detect,
f30f9a5e7   Dan McGee   pata_sis: add mod...
542
  	.mode_filter		= sis_133_mode_filter,
a3cabb271   Uwe Koziolek   libata: PATA-mode...
543
  };
029cfd6b7   Tejun Heo   libata: implement...
544
545
  static struct ata_port_operations sis_133_early_ops = {
  	.inherits		= &sis_base_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
546
547
  	.set_piomode		= sis_100_set_piomode,
  	.set_dmamode		= sis_133_early_set_dmamode,
2e413f510   Alan Cox   pata_sis: Clean u...
548
  	.cable_detect		= sis_66_cable_detect,
669a5db41   Jeff Garzik   [libata] Add a bu...
549
  };
029cfd6b7   Tejun Heo   libata: implement...
550
551
  static struct ata_port_operations sis_100_ops = {
  	.inherits		= &sis_base_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
552
553
  	.set_piomode		= sis_100_set_piomode,
  	.set_dmamode		= sis_100_set_dmamode,
2e413f510   Alan Cox   pata_sis: Clean u...
554
  	.cable_detect		= sis_66_cable_detect,
669a5db41   Jeff Garzik   [libata] Add a bu...
555
  };
029cfd6b7   Tejun Heo   libata: implement...
556
557
  static struct ata_port_operations sis_66_ops = {
  	.inherits		= &sis_base_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
558
559
  	.set_piomode		= sis_old_set_piomode,
  	.set_dmamode		= sis_66_set_dmamode,
2e413f510   Alan Cox   pata_sis: Clean u...
560
  	.cable_detect		= sis_66_cable_detect,
669a5db41   Jeff Garzik   [libata] Add a bu...
561
  };
029cfd6b7   Tejun Heo   libata: implement...
562
563
  static struct ata_port_operations sis_old_ops = {
  	.inherits		= &sis_base_ops,
669a5db41   Jeff Garzik   [libata] Add a bu...
564
565
  	.set_piomode		= sis_old_set_piomode,
  	.set_dmamode		= sis_old_set_dmamode,
2e413f510   Alan Cox   pata_sis: Clean u...
566
  	.cable_detect		= ata_cable_40wire,
669a5db41   Jeff Garzik   [libata] Add a bu...
567
  };
1626aeb88   Tejun Heo   libata: clean up ...
568
  static const struct ata_port_info sis_info = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
569
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
570
571
572
  	.pio_mask	= ATA_PIO4,
  	.mwdma_mask	= ATA_MWDMA2,
  	/* No UDMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
573
574
  	.port_ops	= &sis_old_ops,
  };
1626aeb88   Tejun Heo   libata: clean up ...
575
  static const struct ata_port_info sis_info33 = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
576
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
577
578
579
  	.pio_mask	= ATA_PIO4,
  	.mwdma_mask	= ATA_MWDMA2,
  	.udma_mask	= ATA_UDMA2,
669a5db41   Jeff Garzik   [libata] Add a bu...
580
581
  	.port_ops	= &sis_old_ops,
  };
1626aeb88   Tejun Heo   libata: clean up ...
582
  static const struct ata_port_info sis_info66 = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
583
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
584
585
586
  	.pio_mask	= ATA_PIO4,
  	/* No MWDMA */
  	.udma_mask	= ATA_UDMA4,
669a5db41   Jeff Garzik   [libata] Add a bu...
587
588
  	.port_ops	= &sis_66_ops,
  };
1626aeb88   Tejun Heo   libata: clean up ...
589
  static const struct ata_port_info sis_info100 = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
590
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
591
592
  	.pio_mask	= ATA_PIO4,
  	/* No MWDMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
593
594
595
  	.udma_mask	= ATA_UDMA5,
  	.port_ops	= &sis_100_ops,
  };
1626aeb88   Tejun Heo   libata: clean up ...
596
  static const struct ata_port_info sis_info100_early = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
597
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
598
599
  	.pio_mask	= ATA_PIO4,
  	/* No MWDMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
600
  	.udma_mask	= ATA_UDMA5,
669a5db41   Jeff Garzik   [libata] Add a bu...
601
602
  	.port_ops	= &sis_66_ops,
  };
a3cabb271   Uwe Koziolek   libata: PATA-mode...
603
  static const struct ata_port_info sis_info133 = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
604
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
605
  	.pio_mask	= ATA_PIO4,
14004f044   Dan McGee   pata_sis: enable ...
606
  	.mwdma_mask	= ATA_MWDMA2,
669a5db41   Jeff Garzik   [libata] Add a bu...
607
608
609
  	.udma_mask	= ATA_UDMA6,
  	.port_ops	= &sis_133_ops,
  };
a3cabb271   Uwe Koziolek   libata: PATA-mode...
610
  const struct ata_port_info sis_info133_for_sata = {
c10f97b9d   Sergei Shtylyov   libata: remove AT...
611
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
612
613
  	.pio_mask	= ATA_PIO4,
  	/* No MWDMA */
a3cabb271   Uwe Koziolek   libata: PATA-mode...
614
615
616
  	.udma_mask	= ATA_UDMA6,
  	.port_ops	= &sis_133_for_sata_ops,
  };
1626aeb88   Tejun Heo   libata: clean up ...
617
  static const struct ata_port_info sis_info133_early = {
1d2808fd3   Jeff Garzik   [libata] PATA dri...
618
  	.flags		= ATA_FLAG_SLAVE_POSS,
14bdef982   Erik Inge Bolsø   [libata] convert ...
619
620
  	.pio_mask	= ATA_PIO4,
  	/* No MWDMA */
669a5db41   Jeff Garzik   [libata] Add a bu...
621
622
623
  	.udma_mask	= ATA_UDMA6,
  	.port_ops	= &sis_133_early_ops,
  };
9b14dec5a   Alan Cox   sata_sis: Support...
624
  /* Privately shared with the SiS180 SATA driver, not for use elsewhere */
a3cabb271   Uwe Koziolek   libata: PATA-mode...
625
  EXPORT_SYMBOL_GPL(sis_info133_for_sata);
669a5db41   Jeff Garzik   [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, &regw);
  		if (regw & 0x08)
  			pci_write_config_word(pdev, 0x50, regw & ~0x08);
  		pci_read_config_word(pdev, 0x52, &regw);
  		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, &reg);
  		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, &reg);
  		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, &reg);
  		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, &reg);
  		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   Dan McGee   pata_sis: code st...
686
   *	Called from kernel PCI layer. We probe for combined mode (sigh),
669a5db41   Jeff Garzik   [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   Tejun Heo   libata: stop over...
698
  	const struct ata_port_info *ppi[] = { NULL, NULL };
669a5db41   Jeff Garzik   [libata] Add a bu...
699
700
  	struct pci_dev *host = NULL;
  	struct sis_chipset *chipset = NULL;
f3769e9db   Alan Cox   pata_sis: Fix oop...
701
  	struct sis_chipset *sets;
f08048e94   Tejun Heo   libata: PCI devic...
702
  	int rc;
669a5db41   Jeff Garzik   [libata] Add a bu...
703
704
  
  	static struct sis_chipset sis_chipsets[] = {
f20b16ff7   Jeff Garzik   [libata] trim tra...
705

af323a2fb   Alan Cox   [PATCH] Update Si...
706
707
708
  		{ 0x0968, &sis_info133 },
  		{ 0x0966, &sis_info133 },
  		{ 0x0965, &sis_info133 },
669a5db41   Jeff Garzik   [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   Joe Perches   ata: Add and use ...
750
  	ata_print_version_once(&pdev->dev, DRV_VERSION);
669a5db41   Jeff Garzik   [libata] Add a bu...
751

f08048e94   Tejun Heo   libata: PCI devic...
752
753
754
  	rc = pcim_enable_device(pdev);
  	if (rc)
  		return rc;
669a5db41   Jeff Garzik   [libata] Add a bu...
755

f08048e94   Tejun Heo   libata: PCI devic...
756
  	/* We have to find the bridge first */
f3769e9db   Alan Cox   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   Jeff Garzik   [libata] Add a bu...
759
  		if (host != NULL) {
f3769e9db   Alan Cox   pata_sis: Fix oop...
760
761
  			chipset = sets;			/* Match found */
  			if (sets->device == 0x630) {	/* SIS630 */
44c10138f   Auke Kok   PCI: Change all d...
762
  				if (host->revision >= 0x30)	/* 630 ET */
669a5db41   Jeff Garzik   [libata] Add a bu...
763
764
765
766
767
768
769
  					chipset = &sis100_early;
  			}
  			break;
  		}
  	}
  
  	/* Look for concealed bridges */
f3769e9db   Alan Cox   pata_sis: Fix oop...
770
  	if (chipset == NULL) {
669a5db41   Jeff Garzik   [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   Dan McGee   pata_sis: add mod...
785
786
787
  			dev_info(&pdev->dev,
  				 "SiS 962/963 MuTIOL IDE UDMA133 controller
  ");
669a5db41   Jeff Garzik   [libata] Add a bu...
788
789
790
  			chipset = &sis133;
  			if ((idemisc & 0x40000000) == 0) {
  				pci_write_config_dword(pdev, 0x54, idemisc | 0x40000000);
f30f9a5e7   Dan McGee   pata_sis: add mod...
791
792
793
  				dev_info(&pdev->dev,
  					 "Switching to 5513 register mapping
  ");
669a5db41   Jeff Garzik   [libata] Add a bu...
794
795
796
  			}
  			break;
  		case 0x0180:	/* SIS 965/965L */
edc7d12ed   Dan McGee   pata_sis: code st...
797
  			chipset = &sis133;
669a5db41   Jeff Garzik   [libata] Add a bu...
798
799
  			break;
  		case 0x1180:	/* SIS 966/966L */
edc7d12ed   Dan McGee   pata_sis: code st...
800
  			chipset = &sis133;
669a5db41   Jeff Garzik   [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   Jeff Garzik   [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   Jeff Garzik   [libata] Add a bu...
823
824
  			pci_read_config_byte(pdev, 0x49, &prefctl);
  			pci_dev_put(lpc_bridge);
44c10138f   Auke Kok   PCI: Change all d...
825
  			if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) {
669a5db41   Jeff Garzik   [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   Tejun Heo   libata: stop over...
838
  	ppi[0] = chipset->info;
669a5db41   Jeff Garzik   [libata] Add a bu...
839
840
  
  	sis_fixup(pdev, chipset);
1c5afdf7a   Tejun Heo   libata-sff: separ...
841
  	return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset, 0);
669a5db41   Jeff Garzik   [libata] Add a bu...
842
  }
58eb8cd56   Bartlomiej Zolnierkiewicz   ata: use CONFIG_P...
843
  #ifdef CONFIG_PM_SLEEP
750c7136e   Bartlomiej Zolnierkiewicz   pata_sis: Power M...
844
845
  static int sis_reinit_one(struct pci_dev *pdev)
  {
0a86e1c85   Jingoo Han   ata: use pci_get_...
846
  	struct ata_host *host = pci_get_drvdata(pdev);
750c7136e   Bartlomiej Zolnierkiewicz   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   Jeff Garzik   [libata] Add a bu...
859
  static const struct pci_device_id sis_pci_tbl[] = {
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
860
861
  	{ PCI_VDEVICE(SI, 0x5513), },	/* SiS 5513 */
  	{ PCI_VDEVICE(SI, 0x5518), },	/* SiS 5518 */
a3cabb271   Uwe Koziolek   libata: PATA-mode...
862
  	{ PCI_VDEVICE(SI, 0x1180), },	/* SiS 1180 */
2d2744fc8   Jeff Garzik   [libata] PCI ID t...
863

669a5db41   Jeff Garzik   [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   Bartlomiej Zolnierkiewicz   ata: use CONFIG_P...
872
  #ifdef CONFIG_PM_SLEEP
62d64ae0e   Alan Cox   [PATCH] pata : mo...
873
  	.suspend		= ata_pci_device_suspend,
750c7136e   Bartlomiej Zolnierkiewicz   pata_sis: Power M...
874
  	.resume			= sis_reinit_one,
438ac6d5e   Tejun Heo   libata: add missi...
875
  #endif
669a5db41   Jeff Garzik   [libata] Add a bu...
876
  };
2fc75da0c   Axel Lin   ata: use module_p...
877
  module_pci_driver(sis_pci_driver);
669a5db41   Jeff Garzik   [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);