1 |
1275 |
phoenix |
/*
|
2 |
|
|
* linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004
|
3 |
|
|
*
|
4 |
|
|
* Copyright (C) 2003 ATI Inc. <hyu@ati.com>
|
5 |
|
|
* Copyright (C) 2004 Bartlomiej Zolnierkiewicz
|
6 |
|
|
*
|
7 |
|
|
*/
|
8 |
|
|
|
9 |
|
|
#include <linux/config.h>
|
10 |
|
|
#include <linux/types.h>
|
11 |
|
|
#include <linux/module.h>
|
12 |
|
|
#include <linux/kernel.h>
|
13 |
|
|
#include <linux/ioport.h>
|
14 |
|
|
#include <linux/pci.h>
|
15 |
|
|
#include <linux/hdreg.h>
|
16 |
|
|
#include <linux/ide.h>
|
17 |
|
|
#include <linux/delay.h>
|
18 |
|
|
#include <linux/init.h>
|
19 |
|
|
|
20 |
|
|
#include <asm/io.h>
|
21 |
|
|
|
22 |
|
|
#include "ide_modes.h"
|
23 |
|
|
|
24 |
|
|
#define ATIIXP_IDE_PIO_TIMING 0x40
|
25 |
|
|
#define ATIIXP_IDE_MDMA_TIMING 0x44
|
26 |
|
|
#define ATIIXP_IDE_PIO_CONTROL 0x48
|
27 |
|
|
#define ATIIXP_IDE_PIO_MODE 0x4a
|
28 |
|
|
#define ATIIXP_IDE_UDMA_CONTROL 0x54
|
29 |
|
|
#define ATIIXP_IDE_UDMA_MODE 0x56
|
30 |
|
|
|
31 |
|
|
typedef struct {
|
32 |
|
|
u8 command_width;
|
33 |
|
|
u8 recover_width;
|
34 |
|
|
} atiixp_ide_timing;
|
35 |
|
|
|
36 |
|
|
static atiixp_ide_timing pio_timing[] = {
|
37 |
|
|
{ 0x05, 0x0d },
|
38 |
|
|
{ 0x04, 0x07 },
|
39 |
|
|
{ 0x03, 0x04 },
|
40 |
|
|
{ 0x02, 0x02 },
|
41 |
|
|
{ 0x02, 0x00 },
|
42 |
|
|
};
|
43 |
|
|
|
44 |
|
|
static atiixp_ide_timing mdma_timing[] = {
|
45 |
|
|
{ 0x07, 0x07 },
|
46 |
|
|
{ 0x02, 0x01 },
|
47 |
|
|
{ 0x02, 0x00 },
|
48 |
|
|
};
|
49 |
|
|
|
50 |
|
|
static int save_mdma_mode[4];
|
51 |
|
|
|
52 |
|
|
#define DISPLAY_ATIIXP_TIMINGS
|
53 |
|
|
|
54 |
|
|
#if defined(DISPLAY_ATIIXP_TIMINGS) && defined(CONFIG_PROC_FS)
|
55 |
|
|
|
56 |
|
|
#include <linux/stat.h>
|
57 |
|
|
#include <linux/proc_fs.h>
|
58 |
|
|
|
59 |
|
|
static u8 atiixp_proc;
|
60 |
|
|
static struct pci_dev *bmide_dev;
|
61 |
|
|
|
62 |
|
|
/**
|
63 |
|
|
* atiixp_get_info - fill in /proc for ATIIXP IDE
|
64 |
|
|
* @buffer: buffer to fill
|
65 |
|
|
* @addr: address of user start in buffer
|
66 |
|
|
* @offset: offset into 'file'
|
67 |
|
|
* @count: buffer count
|
68 |
|
|
*
|
69 |
|
|
* Output summary data on the tuning.
|
70 |
|
|
*/
|
71 |
|
|
|
72 |
|
|
static int atiixp_get_info(char *buffer, char **addr, off_t offset, int count)
|
73 |
|
|
{
|
74 |
|
|
char *p = buffer;
|
75 |
|
|
struct pci_dev *dev = bmide_dev;
|
76 |
|
|
unsigned long bibma = pci_resource_start(dev, 4);
|
77 |
|
|
u32 mdma_timing = 0;
|
78 |
|
|
u16 udma_mode = 0, pio_mode = 0;
|
79 |
|
|
u8 c0, c1, udma_control = 0;
|
80 |
|
|
|
81 |
|
|
p += sprintf(p, "\n ATI ");
|
82 |
|
|
p += sprintf(p, "ATIIXP Ultra100 IDE Chipset.\n");
|
83 |
|
|
|
84 |
|
|
pci_read_config_byte(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_control);
|
85 |
|
|
pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &udma_mode);
|
86 |
|
|
pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode);
|
87 |
|
|
pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &mdma_timing);
|
88 |
|
|
|
89 |
|
|
/*
|
90 |
|
|
* at that point bibma+0x2 et bibma+0xa are byte registers
|
91 |
|
|
* to investigate:
|
92 |
|
|
*/
|
93 |
|
|
c0 = inb(bibma + 0x02);
|
94 |
|
|
c1 = inb(bibma + 0x0a);
|
95 |
|
|
|
96 |
|
|
p += sprintf(p, "--------------- Primary Channel "
|
97 |
|
|
"---------------- Secondary Channel "
|
98 |
|
|
"-------------\n");
|
99 |
|
|
p += sprintf(p, " %sabled "
|
100 |
|
|
" %sabled\n",
|
101 |
|
|
(c0 & 0x80) ? "dis" : " en",
|
102 |
|
|
(c1 & 0x80) ? "dis" : " en");
|
103 |
|
|
p += sprintf(p, "--------------- drive0 --------- drive1 "
|
104 |
|
|
"-------- drive0 ---------- drive1 ------\n");
|
105 |
|
|
p += sprintf(p, "DMA enabled: %s %s "
|
106 |
|
|
" %s %s\n",
|
107 |
|
|
(c0 & 0x20) ? "yes" : "no ",
|
108 |
|
|
(c0 & 0x40) ? "yes" : "no ",
|
109 |
|
|
(c1 & 0x20) ? "yes" : "no ",
|
110 |
|
|
(c1 & 0x40) ? "yes" : "no " );
|
111 |
|
|
p += sprintf(p, "UDMA enabled: %s %s "
|
112 |
|
|
" %s %s\n",
|
113 |
|
|
(udma_control & 0x01) ? "yes" : "no ",
|
114 |
|
|
(udma_control & 0x02) ? "yes" : "no ",
|
115 |
|
|
(udma_control & 0x04) ? "yes" : "no ",
|
116 |
|
|
(udma_control & 0x08) ? "yes" : "no " );
|
117 |
|
|
p += sprintf(p, "UDMA mode: %c %c "
|
118 |
|
|
" %c %c\n",
|
119 |
|
|
(udma_control & 0x01) ?
|
120 |
|
|
((udma_mode & 0x07) + 48) : 'X',
|
121 |
|
|
(udma_control & 0x02) ?
|
122 |
|
|
(((udma_mode >> 4) & 0x07) + 48) : 'X',
|
123 |
|
|
(udma_control & 0x04) ?
|
124 |
|
|
(((udma_mode >> 8) & 0x07) + 48) : 'X',
|
125 |
|
|
(udma_control & 0x08) ?
|
126 |
|
|
(((udma_mode >> 12) & 0x07) + 48) : 'X');
|
127 |
|
|
p += sprintf(p, "MDMA mode: %c %c "
|
128 |
|
|
" %c %c\n",
|
129 |
|
|
(save_mdma_mode[0] && (c0 & 0x20)) ?
|
130 |
|
|
((save_mdma_mode[0] & 0xf) + 48) : 'X',
|
131 |
|
|
(save_mdma_mode[1] && (c0 & 0x40)) ?
|
132 |
|
|
((save_mdma_mode[1] & 0xf) + 48) : 'X',
|
133 |
|
|
(save_mdma_mode[2] && (c1 & 0x20)) ?
|
134 |
|
|
((save_mdma_mode[2] & 0xf) + 48) : 'X',
|
135 |
|
|
(save_mdma_mode[3] && (c1 & 0x40)) ?
|
136 |
|
|
((save_mdma_mode[3] & 0xf) + 48) : 'X');
|
137 |
|
|
p += sprintf(p, "PIO mode: %c %c "
|
138 |
|
|
" %c %c\n",
|
139 |
|
|
(c0 & 0x20) ? 'X' : ((pio_mode & 0x07) + 48),
|
140 |
|
|
(c0 & 0x40) ? 'X' : (((pio_mode >> 4) & 0x07) + 48),
|
141 |
|
|
(c1 & 0x20) ? 'X' : (((pio_mode >> 8) & 0x07) + 48),
|
142 |
|
|
(c1 & 0x40) ? 'X' : (((pio_mode >> 12) & 0x07) + 48));
|
143 |
|
|
|
144 |
|
|
return p - buffer; /* => must be less than 4k! */
|
145 |
|
|
}
|
146 |
|
|
|
147 |
|
|
static ide_pci_host_proc_t atiixp_procs = {
|
148 |
|
|
.name = "atiixp",
|
149 |
|
|
.set = 1,
|
150 |
|
|
.get_info = atiixp_get_info,
|
151 |
|
|
};
|
152 |
|
|
#endif /* defined(DISPLAY_ATIIXP_TIMINGS) && defined(CONFIG_PROC_FS) */
|
153 |
|
|
|
154 |
|
|
/**
|
155 |
|
|
* atiixp_ratemask - compute rate mask for ATIIXP IDE
|
156 |
|
|
* @drive: IDE drive to compute for
|
157 |
|
|
*
|
158 |
|
|
* Returns the available modes for the ATIIXP IDE controller.
|
159 |
|
|
*/
|
160 |
|
|
|
161 |
|
|
static u8 atiixp_ratemask(ide_drive_t *drive)
|
162 |
|
|
{
|
163 |
|
|
u8 mode = 3;
|
164 |
|
|
|
165 |
|
|
if (!eighty_ninty_three(drive))
|
166 |
|
|
mode = min(mode, (u8)1);
|
167 |
|
|
return mode;
|
168 |
|
|
}
|
169 |
|
|
|
170 |
|
|
/**
|
171 |
|
|
* atiixp_dma_2_pio - return the PIO mode matching DMA
|
172 |
|
|
* @xfer_rate: transfer speed
|
173 |
|
|
*
|
174 |
|
|
* Returns the nearest equivalent PIO timing for the PIO or DMA
|
175 |
|
|
* mode requested by the controller.
|
176 |
|
|
*/
|
177 |
|
|
|
178 |
|
|
static u8 atiixp_dma_2_pio(u8 xfer_rate) {
|
179 |
|
|
switch(xfer_rate) {
|
180 |
|
|
case XFER_UDMA_6:
|
181 |
|
|
case XFER_UDMA_5:
|
182 |
|
|
case XFER_UDMA_4:
|
183 |
|
|
case XFER_UDMA_3:
|
184 |
|
|
case XFER_UDMA_2:
|
185 |
|
|
case XFER_UDMA_1:
|
186 |
|
|
case XFER_UDMA_0:
|
187 |
|
|
case XFER_MW_DMA_2:
|
188 |
|
|
case XFER_PIO_4:
|
189 |
|
|
return 4;
|
190 |
|
|
case XFER_MW_DMA_1:
|
191 |
|
|
case XFER_PIO_3:
|
192 |
|
|
return 3;
|
193 |
|
|
case XFER_SW_DMA_2:
|
194 |
|
|
case XFER_PIO_2:
|
195 |
|
|
return 2;
|
196 |
|
|
case XFER_MW_DMA_0:
|
197 |
|
|
case XFER_SW_DMA_1:
|
198 |
|
|
case XFER_SW_DMA_0:
|
199 |
|
|
case XFER_PIO_1:
|
200 |
|
|
case XFER_PIO_0:
|
201 |
|
|
case XFER_PIO_SLOW:
|
202 |
|
|
default:
|
203 |
|
|
return 0;
|
204 |
|
|
}
|
205 |
|
|
}
|
206 |
|
|
|
207 |
|
|
static int atiixp_ide_dma_host_on(ide_drive_t *drive)
|
208 |
|
|
{
|
209 |
|
|
struct pci_dev *dev = drive->hwif->pci_dev;
|
210 |
|
|
unsigned long flags;
|
211 |
|
|
u16 tmp16;
|
212 |
|
|
|
213 |
|
|
spin_lock_irqsave(&ide_lock, flags);
|
214 |
|
|
|
215 |
|
|
pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
|
216 |
|
|
if (save_mdma_mode[drive->dn])
|
217 |
|
|
tmp16 &= ~(1 << drive->dn);
|
218 |
|
|
else
|
219 |
|
|
tmp16 |= (1 << drive->dn);
|
220 |
|
|
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
|
221 |
|
|
|
222 |
|
|
spin_unlock_irqrestore(&ide_lock, flags);
|
223 |
|
|
|
224 |
|
|
return __ide_dma_host_on(drive);
|
225 |
|
|
}
|
226 |
|
|
|
227 |
|
|
static int atiixp_ide_dma_host_off(ide_drive_t *drive)
|
228 |
|
|
{
|
229 |
|
|
struct pci_dev *dev = drive->hwif->pci_dev;
|
230 |
|
|
unsigned long flags;
|
231 |
|
|
u16 tmp16;
|
232 |
|
|
|
233 |
|
|
spin_lock_irqsave(&ide_lock, flags);
|
234 |
|
|
|
235 |
|
|
pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
|
236 |
|
|
tmp16 &= ~(1 << drive->dn);
|
237 |
|
|
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
|
238 |
|
|
|
239 |
|
|
spin_unlock_irqrestore(&ide_lock, flags);
|
240 |
|
|
|
241 |
|
|
return __ide_dma_host_off(drive);
|
242 |
|
|
}
|
243 |
|
|
|
244 |
|
|
/**
|
245 |
|
|
* atiixp_tune_drive - tune a drive attached to a ATIIXP
|
246 |
|
|
* @drive: drive to tune
|
247 |
|
|
* @pio: desired PIO mode
|
248 |
|
|
*
|
249 |
|
|
* Set the interface PIO mode.
|
250 |
|
|
*/
|
251 |
|
|
|
252 |
|
|
static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
|
253 |
|
|
{
|
254 |
|
|
struct pci_dev *dev = drive->hwif->pci_dev;
|
255 |
|
|
unsigned long flags;
|
256 |
|
|
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
|
257 |
|
|
u32 pio_timing_data;
|
258 |
|
|
u16 pio_mode_data;
|
259 |
|
|
|
260 |
|
|
spin_lock_irqsave(&ide_lock, flags);
|
261 |
|
|
|
262 |
|
|
pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
|
263 |
|
|
pio_mode_data &= ~(0x07 << (drive->dn * 4));
|
264 |
|
|
pio_mode_data |= (pio << (drive->dn * 4));
|
265 |
|
|
pci_write_config_word(dev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
|
266 |
|
|
|
267 |
|
|
pci_read_config_dword(dev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
|
268 |
|
|
pio_timing_data &= ~(0xff << timing_shift);
|
269 |
|
|
pio_timing_data |= (pio_timing[pio].recover_width << timing_shift) |
|
270 |
|
|
(pio_timing[pio].command_width << (timing_shift + 4));
|
271 |
|
|
pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
|
272 |
|
|
|
273 |
|
|
spin_unlock_irqrestore(&ide_lock, flags);
|
274 |
|
|
}
|
275 |
|
|
|
276 |
|
|
/**
|
277 |
|
|
* atiixp_tune_chipset - tune a ATIIXP interface
|
278 |
|
|
* @drive: IDE drive to tune
|
279 |
|
|
* @xferspeed: speed to configure
|
280 |
|
|
*
|
281 |
|
|
* Set a ATIIXP interface channel to the desired speeds. This involves
|
282 |
|
|
* requires the right timing data into the ATIIXP configuration space
|
283 |
|
|
* then setting the drive parameters appropriately
|
284 |
|
|
*/
|
285 |
|
|
|
286 |
|
|
static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
|
287 |
|
|
{
|
288 |
|
|
struct pci_dev *dev = drive->hwif->pci_dev;
|
289 |
|
|
unsigned long flags;
|
290 |
|
|
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
|
291 |
|
|
u32 tmp32;
|
292 |
|
|
u16 tmp16;
|
293 |
|
|
u8 speed, pio;
|
294 |
|
|
|
295 |
|
|
speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed);
|
296 |
|
|
|
297 |
|
|
spin_lock_irqsave(&ide_lock, flags);
|
298 |
|
|
|
299 |
|
|
save_mdma_mode[drive->dn] = 0;
|
300 |
|
|
if (speed >= XFER_UDMA_0) {
|
301 |
|
|
pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16);
|
302 |
|
|
tmp16 &= ~(0x07 << (drive->dn * 4));
|
303 |
|
|
tmp16 |= ((speed & 0x07) << (drive->dn * 4));
|
304 |
|
|
pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16);
|
305 |
|
|
} else {
|
306 |
|
|
if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) {
|
307 |
|
|
save_mdma_mode[drive->dn] = speed;
|
308 |
|
|
pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
|
309 |
|
|
tmp32 &= ~(0xff << timing_shift);
|
310 |
|
|
tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) |
|
311 |
|
|
(mdma_timing[speed & 0x03].command_width << (timing_shift + 4));
|
312 |
|
|
pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
|
313 |
|
|
}
|
314 |
|
|
}
|
315 |
|
|
|
316 |
|
|
spin_unlock_irqrestore(&ide_lock, flags);
|
317 |
|
|
|
318 |
|
|
if (speed >= XFER_SW_DMA_0)
|
319 |
|
|
pio = atiixp_dma_2_pio(speed);
|
320 |
|
|
else
|
321 |
|
|
pio = speed - XFER_PIO_0;
|
322 |
|
|
|
323 |
|
|
atiixp_tuneproc(drive, pio);
|
324 |
|
|
|
325 |
|
|
return ide_config_drive_speed(drive, speed);
|
326 |
|
|
}
|
327 |
|
|
|
328 |
|
|
/**
|
329 |
|
|
* atiixp_config_drive_for_dma - configure drive for DMA
|
330 |
|
|
* @drive: IDE drive to configure
|
331 |
|
|
*
|
332 |
|
|
* Set up a ATIIXP interface channel for the best available speed.
|
333 |
|
|
* We prefer UDMA if it is available and then MWDMA. If DMA is
|
334 |
|
|
* not available we switch to PIO and return 0.
|
335 |
|
|
*/
|
336 |
|
|
|
337 |
|
|
static int atiixp_config_drive_for_dma(ide_drive_t *drive)
|
338 |
|
|
{
|
339 |
|
|
u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive));
|
340 |
|
|
|
341 |
|
|
/* If no DMA speed was available then disable DMA and use PIO. */
|
342 |
|
|
if (!speed) {
|
343 |
|
|
u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
|
344 |
|
|
speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
|
345 |
|
|
}
|
346 |
|
|
|
347 |
|
|
(void) atiixp_speedproc(drive, speed);
|
348 |
|
|
return ide_dma_enable(drive);
|
349 |
|
|
}
|
350 |
|
|
|
351 |
|
|
/**
|
352 |
|
|
* atiixp_dma_check - set up an IDE device
|
353 |
|
|
* @drive: IDE drive to configure
|
354 |
|
|
*
|
355 |
|
|
* Set up the ATIIXP interface for the best available speed on this
|
356 |
|
|
* interface, preferring DMA to PIO.
|
357 |
|
|
*/
|
358 |
|
|
|
359 |
|
|
static int atiixp_dma_check(ide_drive_t *drive)
|
360 |
|
|
{
|
361 |
|
|
ide_hwif_t *hwif = HWIF(drive);
|
362 |
|
|
struct hd_driveid *id = drive->id;
|
363 |
|
|
u8 tspeed, speed;
|
364 |
|
|
|
365 |
|
|
drive->init_speed = 0;
|
366 |
|
|
|
367 |
|
|
if ((id->capability & 1) && drive->autodma) {
|
368 |
|
|
/* Consult the list of known "bad" drives */
|
369 |
|
|
if (__ide_dma_bad_drive(drive))
|
370 |
|
|
goto fast_ata_pio;
|
371 |
|
|
if (id->field_valid & 4) {
|
372 |
|
|
if (id->dma_ultra & hwif->ultra_mask) {
|
373 |
|
|
/* Force if Capable UltraDMA */
|
374 |
|
|
if ((id->field_valid & 2) &&
|
375 |
|
|
(!atiixp_config_drive_for_dma(drive)))
|
376 |
|
|
goto try_dma_modes;
|
377 |
|
|
}
|
378 |
|
|
} else if (id->field_valid & 2) {
|
379 |
|
|
try_dma_modes:
|
380 |
|
|
if ((id->dma_mword & hwif->mwdma_mask) ||
|
381 |
|
|
(id->dma_1word & hwif->swdma_mask)) {
|
382 |
|
|
/* Force if Capable regular DMA modes */
|
383 |
|
|
if (!atiixp_config_drive_for_dma(drive))
|
384 |
|
|
goto no_dma_set;
|
385 |
|
|
}
|
386 |
|
|
} else if (__ide_dma_good_drive(drive) &&
|
387 |
|
|
(id->eide_dma_time < 150)) {
|
388 |
|
|
/* Consult the list of known "good" drives */
|
389 |
|
|
if (!atiixp_config_drive_for_dma(drive))
|
390 |
|
|
goto no_dma_set;
|
391 |
|
|
} else {
|
392 |
|
|
goto fast_ata_pio;
|
393 |
|
|
}
|
394 |
|
|
return hwif->ide_dma_on(drive);
|
395 |
|
|
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
396 |
|
|
fast_ata_pio:
|
397 |
|
|
no_dma_set:
|
398 |
|
|
tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
|
399 |
|
|
speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
|
400 |
|
|
hwif->speedproc(drive, speed);
|
401 |
|
|
return hwif->ide_dma_off_quietly(drive);
|
402 |
|
|
}
|
403 |
|
|
/* IORDY not supported */
|
404 |
|
|
return 0;
|
405 |
|
|
}
|
406 |
|
|
|
407 |
|
|
/**
|
408 |
|
|
* init_chipset_atiixp - set up the ATIIXP chipset
|
409 |
|
|
* @dev: PCI device to set up
|
410 |
|
|
* @name: Name of the device
|
411 |
|
|
*
|
412 |
|
|
* Initialize the PCI device as required. For the ATIIXP this turns
|
413 |
|
|
* out to be nice and simple
|
414 |
|
|
*/
|
415 |
|
|
|
416 |
|
|
static unsigned int __devinit init_chipset_atiixp(struct pci_dev *dev, const char *name)
|
417 |
|
|
{
|
418 |
|
|
#if defined(DISPLAY_ATIIXP_TIMINGS) && defined(CONFIG_PROC_FS)
|
419 |
|
|
if (!atiixp_proc) {
|
420 |
|
|
atiixp_proc = 1;
|
421 |
|
|
bmide_dev = dev;
|
422 |
|
|
ide_pci_register_host_proc(&atiixp_procs);
|
423 |
|
|
}
|
424 |
|
|
#endif /* DISPLAY_ATIIXP_TIMINGS && CONFIG_PROC_FS */
|
425 |
|
|
return 0;
|
426 |
|
|
}
|
427 |
|
|
|
428 |
|
|
/**
|
429 |
|
|
* init_hwif_atiixp - fill in the hwif for the ATIIXP
|
430 |
|
|
* @hwif: IDE interface
|
431 |
|
|
*
|
432 |
|
|
* Set up the ide_hwif_t for the ATIIXP interface according to the
|
433 |
|
|
* capabilities of the hardware.
|
434 |
|
|
*/
|
435 |
|
|
|
436 |
|
|
static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
|
437 |
|
|
{
|
438 |
|
|
if (!hwif->irq)
|
439 |
|
|
hwif->irq = hwif->channel ? 15 : 14;
|
440 |
|
|
|
441 |
|
|
hwif->autodma = 0;
|
442 |
|
|
hwif->tuneproc = &atiixp_tuneproc;
|
443 |
|
|
hwif->speedproc = &atiixp_speedproc;
|
444 |
|
|
hwif->drives[0].autotune = 1;
|
445 |
|
|
hwif->drives[1].autotune = 1;
|
446 |
|
|
|
447 |
|
|
if (!hwif->dma_base)
|
448 |
|
|
return;
|
449 |
|
|
|
450 |
|
|
hwif->atapi_dma = 1;
|
451 |
|
|
hwif->ultra_mask = 0x3f;
|
452 |
|
|
hwif->mwdma_mask = 0x06;
|
453 |
|
|
hwif->swdma_mask = 0x04;
|
454 |
|
|
|
455 |
|
|
/* FIXME: proper cable detection needed */
|
456 |
|
|
hwif->udma_four = 1;
|
457 |
|
|
hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
|
458 |
|
|
hwif->ide_dma_host_off = &atiixp_ide_dma_host_off;
|
459 |
|
|
hwif->ide_dma_check = &atiixp_dma_check;
|
460 |
|
|
if (!noautodma)
|
461 |
|
|
hwif->autodma = 1;
|
462 |
|
|
|
463 |
|
|
hwif->drives[1].autodma = hwif->autodma;
|
464 |
|
|
hwif->drives[0].autodma = hwif->autodma;
|
465 |
|
|
}
|
466 |
|
|
|
467 |
|
|
static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
|
468 |
|
|
{ /* 0 */
|
469 |
|
|
.vendor = PCI_VENDOR_ID_ATI,
|
470 |
|
|
.device = PCI_DEVICE_ID_ATI_IXP_IDE,
|
471 |
|
|
.name = "ATIIXP",
|
472 |
|
|
.init_chipset = init_chipset_atiixp,
|
473 |
|
|
.init_hwif = init_hwif_atiixp,
|
474 |
|
|
.channels = 2,
|
475 |
|
|
.autodma = AUTODMA,
|
476 |
|
|
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
|
477 |
|
|
.bootable = ON_BOARD,
|
478 |
|
|
}
|
479 |
|
|
};
|
480 |
|
|
|
481 |
|
|
/**
|
482 |
|
|
* atiixp_init_one - called when a ATIIXP is found
|
483 |
|
|
* @dev: the atiixp device
|
484 |
|
|
* @id: the matching pci id
|
485 |
|
|
*
|
486 |
|
|
* Called when the PCI registration layer (or the IDE initialization)
|
487 |
|
|
* finds a device matching our IDE device tables.
|
488 |
|
|
*/
|
489 |
|
|
|
490 |
|
|
static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
491 |
|
|
{
|
492 |
|
|
ide_pci_device_t *d = &atiixp_pci_info[id->driver_data];
|
493 |
|
|
|
494 |
|
|
if (dev->device != d->device)
|
495 |
|
|
BUG();
|
496 |
|
|
ide_setup_pci_device(dev, d);
|
497 |
|
|
return 0;
|
498 |
|
|
}
|
499 |
|
|
|
500 |
|
|
static struct pci_device_id atiixp_pci_tbl[] = {
|
501 |
|
|
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
502 |
|
|
{ 0, },
|
503 |
|
|
};
|
504 |
|
|
|
505 |
|
|
static struct pci_driver driver = {
|
506 |
|
|
.name = "ATIIXP IDE",
|
507 |
|
|
.id_table = atiixp_pci_tbl,
|
508 |
|
|
.probe = atiixp_init_one,
|
509 |
|
|
};
|
510 |
|
|
|
511 |
|
|
static int atiixp_ide_init(void)
|
512 |
|
|
{
|
513 |
|
|
return ide_pci_register_driver(&driver);
|
514 |
|
|
}
|
515 |
|
|
|
516 |
|
|
module_init(atiixp_ide_init);
|
517 |
|
|
|
518 |
|
|
MODULE_AUTHOR("HUI YU");
|
519 |
|
|
MODULE_DESCRIPTION("PCI driver module for ATI IXP IDE");
|
520 |
|
|
MODULE_LICENSE("GPL");
|
521 |
|
|
|
522 |
|
|
EXPORT_NO_SYMBOLS;
|