Blame view

drivers/ide/alim15x3.c 14.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
   *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
   *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
   *  Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer
   *
   *  Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org)
   *  May be copied or modified under the terms of the GNU General Public License
ccd32e221   Alan Cox   ide: Switch to a ...
8
   *  Copyright (C) 2002 Alan Cox
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
   *  ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
21b824771   Sergei Shtylyov   alim15x3: fix PIO...
10
   *  Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
3c8cc8df5   Bartlomiej Zolnierkiewicz   alim15x3: fix PIO...
11
   *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   *
   *  (U)DMA capable version of ali 1533/1543(C), 1535(D)
   *
   **********************************************************************
   *  9/7/99 --Parts from the above author are included and need to be
   *  converted into standard interface, once I finish the thought.
   *
   *  Recent changes
   *	Don't use LBA48 mode on ALi <= 0xC4
   *	Don't poke 0x79 with a non ALi northbridge
   *	Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang)
   *	Allow UDMA6 on revisions > 0xC4
   *
   *  Documentation
   *	Chipset documentation available under NDA only
   *
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
31
32
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/pci.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
  #include <linux/ide.h>
  #include <linux/init.h>
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
35
  #include <linux/dmi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
  
  #include <asm/io.h>
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
38
  #define DRV_NAME "alim15x3"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
44
45
46
  /*
   *	ALi devices are not plug in. Otherwise these static values would
   *	need to go. They ought to go away anyway
   */
   
  static u8 m5229_revision;
  static u8 chip_is_1543c_e;
  static struct pci_dev *isa_dev;
293f18ad7   Bartlomiej Zolnierkiewicz   alim15x3: add ali...
47
48
49
50
51
52
53
54
55
56
57
58
  static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
  {
  	struct pci_dev *pdev = to_pci_dev(hwif->dev);
  	int pio_fifo = 0x54 + hwif->channel;
  	u8 fifo;
  	int shift = 4 * (drive->dn & 1);
  
  	pci_read_config_byte(pdev, pio_fifo, &fifo);
  	fifo &= ~(0x0F << shift);
  	fifo |= (on << shift);
  	pci_write_config_byte(pdev, pio_fifo, fifo);
  }
a345c7856   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
59
  static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive,
e4c7112b5   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
60
  				struct ide_timing *t, u8 ultra)
a345c7856   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
61
62
63
  {
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
  	int port = hwif->channel ? 0x5c : 0x58;
e4c7112b5   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
64
65
66
67
68
69
70
71
72
73
74
75
  	int udmat = 0x56 + hwif->channel;
  	u8 unit = drive->dn & 1, udma;
  	int shift = 4 * unit;
  
  	/* Set up the UDMA */
  	pci_read_config_byte(dev, udmat, &udma);
  	udma &= ~(0x0F << shift);
  	udma |= ultra << shift;
  	pci_write_config_byte(dev, udmat, udma);
  
  	if (t == NULL)
  		return;
a345c7856   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
76
77
78
79
80
81
82
83
84
85
86
87
  
  	t->setup = clamp_val(t->setup, 1, 8) & 7;
  	t->act8b = clamp_val(t->act8b, 1, 8) & 7;
  	t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
  	t->active = clamp_val(t->active, 1, 8) & 7;
  	t->recover = clamp_val(t->recover, 1, 16) & 15;
  
  	pci_write_config_byte(dev, port, t->setup);
  	pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b);
  	pci_write_config_byte(dev, port + unit + 2,
  			      (t->active << 4) | t->recover);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  /**
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
89
   *	ali_set_pio_mode	-	set host controller for PIO mode
e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
90
   *	@hwif: port
26bcb879c   Bartlomiej Zolnierkiewicz   ide: add ide_set{...
91
   *	@drive: drive
21b824771   Sergei Shtylyov   alim15x3: fix PIO...
92
   *
26bcb879c   Bartlomiej Zolnierkiewicz   ide: add ide_set{...
93
   *	Program the controller for the given PIO mode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
   */
26bcb879c   Bartlomiej Zolnierkiewicz   ide: add ide_set{...
95

e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
96
  static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  {
cde727be9   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
98
  	ide_drive_t *pair = ide_get_pair_dev(drive);
30e5ee4d1   Bartlomiej Zolnierkiewicz   ide: remove obsol...
99
  	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
3c8cc8df5   Bartlomiej Zolnierkiewicz   alim15x3: fix PIO...
100
  	unsigned long T =  1000000 / bus_speed; /* PCI clock based */
3c8cc8df5   Bartlomiej Zolnierkiewicz   alim15x3: fix PIO...
101
  	struct ide_timing t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102

e085b3cae   Bartlomiej Zolnierkiewicz   ide: change ->set...
103
  	ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
cde727be9   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
104
105
106
107
  	if (pair) {
  		struct ide_timing p;
  
  		ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
5740345b8   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
108
109
  		ide_timing_merge(&p, &t, &t,
  			IDE_TIMING_SETUP | IDE_TIMING_8BIT);
cde727be9   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
110
111
  		if (pair->dma_mode) {
  			ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
5740345b8   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
112
113
  			ide_timing_merge(&p, &t, &t,
  				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
cde727be9   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
114
115
  		}
  	}
3c8cc8df5   Bartlomiej Zolnierkiewicz   alim15x3: fix PIO...
116

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
  	/* 
  	 * PIO mode => ATA FIFO on, ATAPI FIFO off
  	 */
293f18ad7   Bartlomiej Zolnierkiewicz   alim15x3: add ali...
120
  	ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);
3c8cc8df5   Bartlomiej Zolnierkiewicz   alim15x3: fix PIO...
121

e4c7112b5   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
122
  	ali_program_timings(hwif, drive, &t, 0);
21b824771   Sergei Shtylyov   alim15x3: fix PIO...
123
124
125
  }
  
  /**
2d5eaa6dd   Bartlomiej Zolnierkiewicz   ide: rework the c...
126
127
   *	ali_udma_filter		-	compute UDMA mask
   *	@drive: IDE device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
   *
2d5eaa6dd   Bartlomiej Zolnierkiewicz   ide: rework the c...
129
130
131
   *	Return available UDMA modes.
   *
   *	The actual rules for the ALi are:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
   *		No UDMA on revisions <= 0x20
   *		Disk only for revisions < 0xC2
63b1623ef   Bartlomiej Zolnierkiewicz   alim15x3: add "wd...
134
   *		Not WDC drives on M1543C-E (?)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136

2d5eaa6dd   Bartlomiej Zolnierkiewicz   ide: rework the c...
137
  static u8 ali_udma_filter(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
  {
2d5eaa6dd   Bartlomiej Zolnierkiewicz   ide: rework the c...
139
140
141
  	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
  		if (drive->media != ide_disk)
  			return 0;
2db3dae51   Bartlomiej Zolnierkiewicz   alim15x3: remove ...
142
  		if (chip_is_1543c_e &&
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
143
  		    strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
2d5eaa6dd   Bartlomiej Zolnierkiewicz   ide: rework the c...
144
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  	}
2d5eaa6dd   Bartlomiej Zolnierkiewicz   ide: rework the c...
146
  	return drive->hwif->ultra_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
  }
  
  /**
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
150
   *	ali_set_dma_mode	-	set host controller for DMA mode
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
151
   *	@hwif: port
88b2b32ba   Bartlomiej Zolnierkiewicz   ide: move ide_con...
152
   *	@drive: drive
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
   *
   *	Configure the hardware for the desired IDE transfer mode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
   */
f212ff28f   Bartlomiej Zolnierkiewicz   ide: move ide_rat...
156

8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
157
  static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  {
e4c7112b5   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
159
  	static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
160
  	struct pci_dev *dev	= to_pci_dev(hwif->dev);
a345c7856   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
161
162
163
  	ide_drive_t *pair	= ide_get_pair_dev(drive);
  	int bus_speed		= ide_pci_clk ? ide_pci_clk : 33;
  	unsigned long T		=  1000000 / bus_speed; /* PCI clock based */
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
164
  	const u8 speed		= drive->dma_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  	u8 tmpbyte		= 0x00;
a345c7856   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
166
  	struct ide_timing t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  	if (speed < XFER_UDMA_0) {
a345c7856   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  		ide_timing_compute(drive, drive->dma_mode, &t, T, 1);
  		if (pair) {
  			struct ide_timing p;
  
  			ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
  			ide_timing_merge(&p, &t, &t,
  				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
  			if (pair->dma_mode) {
  				ide_timing_compute(pair, pair->dma_mode,
  						&p, T, 1);
  				ide_timing_merge(&p, &t, &t,
  					IDE_TIMING_SETUP | IDE_TIMING_8BIT);
  			}
  		}
e4c7112b5   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
183
  		ali_program_timings(hwif, drive, &t, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
  	} else {
e4c7112b5   Bartlomiej Zolnierkiewicz   alim15x3: fix han...
185
186
  		ali_program_timings(hwif, drive, NULL,
  				udma_timing[speed - XFER_UDMA_0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
189
190
191
192
  		if (speed >= XFER_UDMA_3) {
  			pci_read_config_byte(dev, 0x4b, &tmpbyte);
  			tmpbyte |= 1;
  			pci_write_config_byte(dev, 0x4b, tmpbyte);
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
  /**
8a4a5738b   Bartlomiej Zolnierkiewicz   ide: add ->dma_ch...
195
   *	ali_dma_check	-	DMA check
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
   *	@drive:	target device
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
197
   *	@cmd: command
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
200
   *
   *	Returns 1 if the DMA cannot be performed, zero on success.
   */
8a4a5738b   Bartlomiej Zolnierkiewicz   ide: add ->dma_ch...
201
  static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
  {
  	if (m5229_revision < 0xC2 && drive->media != ide_disk) {
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
204
  		if (cmd->tf_flags & IDE_TFLAG_WRITE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
  			return 1;	/* try PIO instead of DMA */
  	}
8a4a5738b   Bartlomiej Zolnierkiewicz   ide: add ->dma_ch...
207
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
211
212
  }
  
  /**
   *	init_chipset_ali15x3	-	Initialise an ALi IDE controller
   *	@dev: PCI device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
214
215
216
   *
   *	This function initializes the ALI IDE controller and where 
   *	appropriate also sets up the 1533 southbridge.
   */
a326b02b0   Bartlomiej Zolnierkiewicz   ide: drop 'name' ...
217

2ed0ef543   Bartlomiej Zolnierkiewicz   ide: fix ->init_c...
218
  static int init_chipset_ali15x3(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
220
221
  {
  	unsigned long flags;
  	u8 tmpbyte;
b14890099   Alan Cox   [PATCH] ide: more...
222
  	struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223

44c10138f   Auke Kok   PCI: Change all d...
224
  	m5229_revision = dev->revision;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225

b14890099   Alan Cox   [PATCH] ide: more...
226
  	isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
230
231
232
233
234
235
236
237
238
239
240
  	local_irq_save(flags);
  
  	if (m5229_revision < 0xC2) {
  		/*
  		 * revision 0x20 (1543-E, 1543-F)
  		 * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
  		 * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7
  		 */
  		pci_read_config_byte(dev, 0x4b, &tmpbyte);
  		/*
  		 * clear bit 7
  		 */
  		pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
cad221aa8   Bartlomiej Zolnierkiewicz   alim15x3: fix CD_...
241
242
243
244
245
246
247
  		/*
  		 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
  		 */
  		if (m5229_revision >= 0x20 && isa_dev) {
  			pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
  			chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
  		}
b14890099   Alan Cox   [PATCH] ide: more...
248
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  	}
  
  	/*
  	 * 1543C-B?, 1535, 1535D, 1553
  	 * Note 1: not all "motherboard" support this detection
  	 * Note 2: if no udma 66 device, the detection may "error".
  	 *         but in this case, we will not set the device to
  	 *         ultra 66, the detection result is not important
  	 */
  
  	/*
  	 * enable "Cable Detection", m5229, 0x4b, bit3
  	 */
  	pci_read_config_byte(dev, 0x4b, &tmpbyte);
  	pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08);
  
  	/*
  	 * We should only tune the 1533 enable if we are using an ALi
  	 * North bridge. We might have no north found on some zany
  	 * box without a device at 0:0.0. The ALi bridge will be at
  	 * 0:0.0 so if we didn't find one we know what is cooking.
  	 */
b14890099   Alan Cox   [PATCH] ide: more...
271
272
  	if (north && north->vendor != PCI_VENDOR_ID_AL)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  
  	if (m5229_revision < 0xC5 && isa_dev)
  	{	
  		/*
  		 * set south-bridge's enable bit, m1533, 0x79
  		 */
  
  		pci_read_config_byte(isa_dev, 0x79, &tmpbyte);
  		if (m5229_revision == 0xC2) {
  			/*
  			 * 1543C-B0 (m1533, 0x79, bit 2)
  			 */
  			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04);
  		} else if (m5229_revision >= 0xC3) {
  			/*
  			 * 1553/1535 (m1533, 0x79, bit 1)
  			 */
  			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
  		}
  	}
cad221aa8   Bartlomiej Zolnierkiewicz   alim15x3: fix CD_...
293

b14890099   Alan Cox   [PATCH] ide: more...
294
  out:
cad221aa8   Bartlomiej Zolnierkiewicz   alim15x3: fix CD_...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  	/*
  	 * CD_ROM DMA on (m5229, 0x53, bit0)
  	 *      Enable this bit even if we want to use PIO.
  	 * PIO FIFO off (m5229, 0x53, bit1)
  	 *      The hardware will use 0x54h and 0x55h to control PIO FIFO.
  	 *	(Not on later devices it seems)
  	 *
  	 *	0x53 changes meaning on later revs - we must no touch
  	 *	bit 1 on them.  Need to check if 0x20 is the right break.
  	 */
  	if (m5229_revision >= 0x20) {
  		pci_read_config_byte(dev, 0x53, &tmpbyte);
  
  		if (m5229_revision <= 0x20)
  			tmpbyte = (tmpbyte & (~0x02)) | 0x01;
  		else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
  			tmpbyte |= 0x03;
  		else
  			tmpbyte |= 0x01;
  
  		pci_write_config_byte(dev, 0x53, tmpbyte);
  	}
b14890099   Alan Cox   [PATCH] ide: more...
317
318
  	pci_dev_put(north);
  	pci_dev_put(isa_dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319
320
321
  	local_irq_restore(flags);
  	return 0;
  }
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
322
323
324
  /*
   *	Cable special cases
   */
1855256c4   Jeff Garzik   drivers/firmware:...
325
  static const struct dmi_system_id cable_dmi_table[] = {
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
326
327
328
329
  	{
  		.ident = "HP Pavilion N5430",
  		.matches = {
  			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
8663fd6d0   Bartlomiej Zolnierkiewicz   alim15x3: Correct...
330
  			DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
331
332
  		},
  	},
03e6f489b   Daniel Exner   pata_ali/alim15x3...
333
334
335
336
337
338
339
  	{
  		.ident = "Toshiba Satellite S1800-814",
  		.matches = {
  			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
  			DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"),
  		},
  	},
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
340
341
342
343
344
345
346
347
348
  	{ }
  };
  
  static int ali_cable_override(struct pci_dev *pdev)
  {
  	/* Fujitsu P2000 */
  	if (pdev->subsystem_vendor == 0x10CF &&
  	    pdev->subsystem_device == 0x10AF)
  		return 1;
d151456a7   Bartlomiej Zolnierkiewicz   alim15x3: add Mit...
349
350
351
352
  	/* Mitac 8317 (Winbook-A) and relatives */
  	if (pdev->subsystem_vendor == 0x1071 &&
  	    pdev->subsystem_device == 0x8317)
  		return 1;
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
353
354
355
356
357
358
  	/* Systems by DMI */
  	if (dmi_check_system(cable_dmi_table))
  		return 1;
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
  /**
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
360
   *	ali_cable_detect	-	cable detection
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
362
363
364
   *	@hwif: IDE interface
   *
   *	This checks if the controller and the cable are capable
   *	of UDMA66 transfers. It doesn't check the drives.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
   */
f454cbe8c   Bartlomiej Zolnierkiewicz   ide: ->cable_dete...
366
  static u8 ali_cable_detect(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
368
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
369
  	u8 cbl = ATA_CBL_PATA40, tmpbyte;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
372
  	if (m5229_revision >= 0xC2) {
  		/*
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
373
374
375
376
377
378
379
  		 * m5229 80-pin cable detection (from Host View)
  		 *
  		 * 0x4a bit0 is 0 => primary channel has 80-pin
  		 * 0x4a bit1 is 0 => secondary channel has 80-pin
  		 *
  		 * Certain laptops use short but suitable cables
  		 * and don't implement the detect logic.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  		 */
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
381
382
383
384
385
386
387
  		if (ali_cable_override(dev))
  			cbl = ATA_CBL_PATA40_SHORT;
  		else {
  			pci_read_config_byte(dev, 0x4a, &tmpbyte);
  			if ((tmpbyte & (1 << hwif->channel)) == 0)
  				cbl = ATA_CBL_PATA80;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  	}
95ba8c17b   Bartlomiej Zolnierkiewicz   alim15x3: backpor...
389
  	return cbl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  }
03682411b   Anton Vorontsov   alim15x3: Remove ...
391
  #ifndef CONFIG_SPARC64
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
393
394
395
396
397
  /**
   *	init_hwif_ali15x3	-	Initialize the ALI IDE x86 stuff
   *	@hwif: interface to configure
   *
   *	Obtain the IRQ tables for an ALi based IDE solution on the PC
   *	class platforms. This part of the code isn't applicable to the
03682411b   Anton Vorontsov   alim15x3: Remove ...
398
   *	Sparc systems.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
   */
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
400
  static void init_hwif_ali15x3(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
405
  {
  	u8 ideic, inmir;
  	s8 irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
  				      1, 11, 0, 12, 0, 14, 0, 15 };
  	int irq = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
  	if (isa_dev) {
  		/*
  		 * read IDE interface control
  		 */
  		pci_read_config_byte(isa_dev, 0x58, &ideic);
  
  		/* bit0, bit1 */
  		ideic = ideic & 0x03;
  
  		/* get IRQ for IDE Controller */
  		if ((hwif->channel && ideic == 0x03) ||
  		    (!hwif->channel && !ideic)) {
  			/*
  			 * get SIRQ1 routing table
  			 */
  			pci_read_config_byte(isa_dev, 0x44, &inmir);
  			inmir = inmir & 0x0f;
  			irq = irq_routing_table[inmir];
  		} else if (hwif->channel && !(ideic & 0x01)) {
  			/*
  			 * get SIRQ2 routing table
  			 */
  			pci_read_config_byte(isa_dev, 0x75, &inmir);
  			inmir = inmir & 0x0f;
  			irq = irq_routing_table[inmir];
  		}
  		if(irq >= 0)
  			hwif->irq = irq;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
  }
6d1cee443   Anton Vorontsov   alim15x3: disable...
436
437
  #else
  #define init_hwif_ali15x3 NULL
03682411b   Anton Vorontsov   alim15x3: Remove ...
438
  #endif /* CONFIG_SPARC64 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
440
441
442
  
  /**
   *	init_dma_ali15x3	-	set up DMA on ALi15x3
   *	@hwif: IDE interface
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
443
   *	@d: IDE port info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
   *
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
445
   *	Set up the DMA functionality on the ALi 15x3.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
   */
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
447
  static int init_dma_ali15x3(ide_hwif_t *hwif, const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
  {
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
449
450
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
  	unsigned long base = ide_pci_dma_base(hwif, d);
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
451
452
453
454
455
456
457
458
459
  	if (base == 0)
  		return -1;
  
  	hwif->dma_base = base;
  
  	if (ide_pci_check_simplex(hwif, d) < 0)
  		return -1;
  
  	if (ide_pci_set_master(dev, d->name) < 0)
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
460
  		return -1;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
461
  	if (!hwif->channel)
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
462
463
464
465
466
467
468
469
  		outb(inb(base + 2) & 0x60, base + 2);
  
  	printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx
  ",
  			 hwif->name, base, base + 7);
  
  	if (ide_allocate_dma_engine(hwif))
  		return -1;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
470
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
  }
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
472
473
474
475
476
477
  static const struct ide_port_ops ali_port_ops = {
  	.set_pio_mode		= ali_set_pio_mode,
  	.set_dma_mode		= ali_set_dma_mode,
  	.udma_filter		= ali_udma_filter,
  	.cable_detect		= ali_cable_detect,
  };
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
478
479
  static const struct ide_dma_ops ali_dma_ops = {
  	.dma_host_set		= ide_dma_host_set,
8a4a5738b   Bartlomiej Zolnierkiewicz   ide: add ->dma_ch...
480
  	.dma_setup		= ide_dma_setup,
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
481
  	.dma_start		= ide_dma_start,
653bcf529   Bartlomiej Zolnierkiewicz   ide: __ide_dma_en...
482
  	.dma_end		= ide_dma_end,
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
483
484
  	.dma_test_irq		= ide_dma_test_irq,
  	.dma_lost_irq		= ide_dma_lost_irq,
8a4a5738b   Bartlomiej Zolnierkiewicz   ide: add ->dma_ch...
485
  	.dma_check		= ali_dma_check,
22117d6ea   Bartlomiej Zolnierkiewicz   ide: add ->dma_ti...
486
  	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
592b53152   Sergei Shtylyov   ide: move read_sf...
487
  	.dma_sff_read_status	= ide_dma_sff_read_status,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
488
  };
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
489
  static const struct ide_port_info ali15x3_chipset = {
ced3ec8aa   Bartlomiej Zolnierkiewicz   ide: prefix messa...
490
  	.name		= DRV_NAME,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
  	.init_chipset	= init_chipset_ali15x3,
  	.init_hwif	= init_hwif_ali15x3,
  	.init_dma	= init_dma_ali15x3,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
494
  	.port_ops	= &ali_port_ops,
3f023b013   Sergei Shtylyov   ide: don't set hw...
495
  	.dma_ops	= &sff_dma_ops,
4099d1432   Bartlomiej Zolnierkiewicz   ide: add PIO masks
496
  	.pio_mask	= ATA_PIO5,
5f8b6c348   Bartlomiej Zolnierkiewicz   ide: add ->mwdma_...
497
498
  	.swdma_mask	= ATA_SWDMA2,
  	.mwdma_mask	= ATA_MWDMA2,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
500
501
502
503
504
505
506
507
508
  };
  
  /**
   *	alim15x3_init_one	-	set up an ALi15x3 IDE controller
   *	@dev: PCI device to set up
   *
   *	Perform the actual set up for an ALi15x3 that has been found by the
   *	hot plug layer.
   */
   
fe31edc8a   Greg Kroah-Hartman   Drivers: ide: rem...
509
510
  static int alim15x3_init_one(struct pci_dev *dev,
  			     const struct pci_device_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
  {
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
512
  	struct ide_port_info d = ali15x3_chipset;
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
513
  	u8 rev = dev->revision, idx = id->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514

283283070   Bartlomiej Zolnierkiewicz   alim15x3: use ->h...
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
  	if (rev <= 0xC4)
  		d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
  
  	if (rev >= 0x20) {
  		if (rev == 0x20)
  			d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
  
  		if (rev < 0xC2)
  			d.udma_mask = ATA_UDMA2;
  		else if (rev == 0xC2 || rev == 0xC3)
  			d.udma_mask = ATA_UDMA4;
  		else if (rev == 0xC4)
  			d.udma_mask = ATA_UDMA5;
  		else
  			d.udma_mask = ATA_UDMA6;
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
531
532
  
  		d.dma_ops = &ali_dma_ops;
6d36b95fe   Bartlomiej Zolnierkiewicz   alim15x3: skip DM...
533
534
535
536
  	} else {
  		d.host_flags |= IDE_HFLAG_NO_DMA;
  
  		d.mwdma_mask = d.swdma_mask = 0;
283283070   Bartlomiej Zolnierkiewicz   alim15x3: use ->h...
537
  	}
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
538
539
  	if (idx == 0)
  		d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
540
  	return ide_pci_init_one(dev, &d, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  }
9cbcc5e3c   Bartlomiej Zolnierkiewicz   ide: use PCI_VDEV...
542
543
  static const struct pci_device_id alim15x3_pci_tbl[] = {
  	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 },
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
544
  	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 1 },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
546
547
  	{ 0, },
  };
  MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
548
  static struct pci_driver alim15x3_pci_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
550
551
  	.name		= "ALI15x3_IDE",
  	.id_table	= alim15x3_pci_tbl,
  	.probe		= alim15x3_init_one,
8ee3f3b69   Bartlomiej Zolnierkiewicz   alim15x3: add ->r...
552
  	.remove		= ide_pci_remove,
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
553
554
  	.suspend	= ide_pci_suspend,
  	.resume		= ide_pci_resume,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
  };
82ab1eece   Bartlomiej Zolnierkiewicz   ide: add missing ...
556
  static int __init ali15x3_ide_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
  {
a9ab09e26   Bartlomiej Zolnierkiewicz   ide: use unique n...
558
  	return ide_pci_register_driver(&alim15x3_pci_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
  }
8ee3f3b69   Bartlomiej Zolnierkiewicz   alim15x3: add ->r...
560
561
  static void __exit ali15x3_ide_exit(void)
  {
95964018d   Hannes Eder   alim15x3: fix spa...
562
  	pci_unregister_driver(&alim15x3_pci_driver);
8ee3f3b69   Bartlomiej Zolnierkiewicz   alim15x3: add ->r...
563
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564
  module_init(ali15x3_ide_init);
8ee3f3b69   Bartlomiej Zolnierkiewicz   alim15x3: add ->r...
565
  module_exit(ali15x3_ide_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566

3c8cc8df5   Bartlomiej Zolnierkiewicz   alim15x3: fix PIO...
567
  MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
  MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");
  MODULE_LICENSE("GPL");