File: /usr/src/linux/drivers/ide/sl82c105.c

1     /*
2      * linux/drivers/ide/sl82c105.c
3      *
4      * SL82C105/Winbond 553 IDE driver
5      *
6      * Maintainer unknown.
7      *
8      * Drive tuning added from Rebel.com's kernel sources
9      *  -- Russell King (15/11/98) linux@arm.linux.org.uk
10      */
11     
12     #include <linux/config.h>
13     #include <linux/types.h>
14     #include <linux/kernel.h>
15     #include <linux/timer.h>
16     #include <linux/mm.h>
17     #include <linux/ioport.h>
18     #include <linux/interrupt.h>
19     #include <linux/blkdev.h>
20     #include <linux/hdreg.h>
21     #include <linux/pci.h>
22     #include <linux/ide.h>
23     
24     #include <asm/io.h>
25     #include <asm/dma.h>
26     
27     #include "ide_modes.h"
28     
29     extern char *ide_xfer_verbose (byte xfer_rate);
30     
31     /*
32      * Convert a PIO mode and cycle time to the required on/off
33      * times for the interface.  This has protection against run-away
34      * timings.
35      */
36     static unsigned int get_timing_sl82c105(ide_pio_data_t *p)
37     {
38     	unsigned int cmd_on;
39     	unsigned int cmd_off;
40     
41     	cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30;
42     	cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30;
43     
44     	if (cmd_on > 32)
45     		cmd_on = 32;
46     	if (cmd_on == 0)
47     		cmd_on = 1;
48     
49     	if (cmd_off > 32)
50     		cmd_off = 32;
51     	if (cmd_off == 0)
52     		cmd_off = 1;
53     
54     	return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00);
55     }
56     
57     /*
58      * Configure the drive and chipset for PIO
59      */
60     static void config_for_pio(ide_drive_t *drive, int pio, int report)
61     {
62     	ide_hwif_t *hwif = HWIF(drive);
63     	struct pci_dev *dev = hwif->pci_dev;
64     	ide_pio_data_t p;
65     	unsigned short drv_ctrl = 0x909;
66     	unsigned int xfer_mode, reg;
67     
68     	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
69     
70     	pio = ide_get_best_pio_mode(drive, pio, 5, &p);
71     
72     	switch (pio) {
73     	default:
74     	case 0:		xfer_mode = XFER_PIO_0;		break;
75     	case 1:		xfer_mode = XFER_PIO_1;		break;
76     	case 2:		xfer_mode = XFER_PIO_2;		break;
77     	case 3:		xfer_mode = XFER_PIO_3;		break;
78     	case 4:		xfer_mode = XFER_PIO_4;		break;
79     	}
80     
81     	if (ide_config_drive_speed(drive, xfer_mode) == 0)
82     		drv_ctrl = get_timing_sl82c105(&p);
83     
84     	if (drive->using_dma == 0) {
85     		/*
86     		 * If we are actually using MW DMA, then we can not
87     		 * reprogram the interface drive control register.
88     		 */
89     		pci_write_config_word(dev, reg, drv_ctrl);
90     		pci_read_config_word(dev, reg, &drv_ctrl);
91     
92     		if (report) {
93     			printk("%s: selected %s (%dns) (%04X)\n", drive->name,
94     			       ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
95     		}
96     	}
97     }
98     
99     /*
100      * Configure the drive and the chipset for DMA
101      */
102     static int config_for_dma(ide_drive_t *drive)
103     {
104     	ide_hwif_t *hwif = HWIF(drive);
105     	struct pci_dev *dev = hwif->pci_dev;
106     	unsigned short drv_ctrl = 0x909;
107     	unsigned int reg;
108     
109     	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
110     
111     	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) == 0)
112     		drv_ctrl = 0x0240;
113     
114     	pci_write_config_word(dev, reg, drv_ctrl);
115     
116     	return 0;
117     }
118     
119     /*
120      * Check to see if the drive and
121      * chipset is capable of DMA mode
122      */
123     static int sl82c105_check_drive(ide_drive_t *drive)
124     {
125     	ide_dma_action_t dma_func = ide_dma_off_quietly;
126     
127     	do {
128     		struct hd_driveid *id = drive->id;
129     		ide_hwif_t *hwif = HWIF(drive);
130     
131     		if (!hwif->autodma)
132     			break;
133     
134     		if (!id || !(id->capability & 1))
135     			break;
136     
137     		/* Consult the list of known "bad" drives */
138     		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
139     			dma_func = ide_dma_off;
140     			break;
141     		}
142     
143     		if (id->field_valid & 2) {
144     			if  (id->dma_mword & 7 || id->dma_1word & 7)
145     				dma_func = ide_dma_on;
146     			break;
147     		}
148     
149     		if (ide_dmaproc(ide_dma_good_drive, drive)) {
150     			dma_func = ide_dma_on;
151     			break;
152     		}
153     	} while (0);
154     
155     	return HWIF(drive)->dmaproc(dma_func, drive);
156     }
157     
158     /*
159      * Our own dmaproc, only to intercept ide_dma_check
160      */
161     static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
162     {
163     	switch (func) {
164     	case ide_dma_check:
165     		return sl82c105_check_drive(drive);
166     	case ide_dma_on:
167     		if (config_for_dma(drive))
168     			func = ide_dma_off;
169     		/* fall through */
170     	case ide_dma_off_quietly:
171     	case ide_dma_off:
172     		config_for_pio(drive, 4, 0);
173     		break;
174     	default:
175     		break;
176     	}
177     	return ide_dmaproc(func, drive);
178     }
179     
180     /*
181      * We only deal with PIO mode here - DMA mode 'using_dma' is not
182      * initialised at the point that this function is called.
183      */
184     static void tune_sl82c105(ide_drive_t *drive, byte pio)
185     {
186     	config_for_pio(drive, pio, 1);
187     
188     	/*
189     	 * We support 32-bit I/O on this interface, and it
190     	 * doesn't have problems with interrupts.
191     	 */
192     	drive->io_32bit = 1;
193     	drive->unmask = 1;
194     }
195     
196     /*
197      * Return the revision of the Winbond bridge
198      * which this function is part of.
199      */
200     static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
201     {
202     	struct pci_dev *bridge;
203     	unsigned char rev;
204     
205     	bridge = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, NULL);
206     
207     	/*
208     	 * If we are part of a Winbond 553
209     	 */
210     	if (!bridge || bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA)
211     		return -1;
212     
213     	if (bridge->bus != dev->bus ||
214     	    PCI_SLOT(bridge->devfn) != PCI_SLOT(dev->devfn))
215     		return -1;
216     
217     	/*
218     	 * We need to find function 0's revision, not function 1
219     	 */
220     	pci_read_config_byte(bridge, PCI_REVISION_ID, &rev);
221     
222     	return rev;
223     }
224     
225     /*
226      * Enable the PCI device
227      */
228     unsigned int __init pci_init_sl82c105(struct pci_dev *dev, const char *msg)
229     {
230     	unsigned char ctrl_stat;
231     
232     	/*
233     	 * Enable the ports
234     	 */
235     	pci_read_config_byte(dev, 0x40, &ctrl_stat);
236     	pci_write_config_byte(dev, 0x40, ctrl_stat | 0x33);
237     
238     	return dev->irq;
239     }
240     
241     void __init dma_init_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
242     {
243     	unsigned int rev;
244     	byte dma_state;
245     
246     	dma_state = inb(dma_base + 2);
247     	rev = sl82c105_bridge_revision(hwif->pci_dev);
248     	if (rev <= 5) {
249     		hwif->autodma = 0;
250     		hwif->drives[0].autotune = 1;
251     		hwif->drives[1].autotune = 1;
252     		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
253     		       hwif->name, rev);
254     		dma_state &= ~0x60;
255     	} else {
256     		dma_state |= 0x60;
257     		hwif->autodma = 1;
258     	}
259     	outb(dma_state, dma_base + 2);
260     
261     	hwif->dmaproc = NULL;
262     	ide_setup_dma(hwif, dma_base, 8);
263     	if (hwif->dmaproc)
264     		hwif->dmaproc = sl82c105_dmaproc;
265     }
266     
267     /*
268      * Initialise the chip
269      */
270     void __init ide_init_sl82c105(ide_hwif_t *hwif)
271     {
272     	hwif->tuneproc = tune_sl82c105;
273     }
274     
275