Import 2.3.18pre1
[davej-history.git] / drivers / block / hpt34x.c
blob284bf40bc08e7917f0cf277e59887f786abb39ec
1 /*
2 * linux/drivers/block/hpt34x.c Version 0.25 July 11, 1999
4 * Copyright (C) 1998-99 Andre Hedrick
6 * 00:12.0 Unknown mass storage controller:
7 * Triones Technologies, Inc.
8 * Unknown device 0003 (rev 01)
10 * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010)
11 * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030)
12 * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010)
13 * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030)
14 * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070)
15 * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0)
17 * drive_number
18 * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
19 * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
22 #include <linux/config.h>
23 #include <linux/types.h>
24 #include <linux/kernel.h>
25 #include <linux/delay.h>
26 #include <linux/timer.h>
27 #include <linux/mm.h>
28 #include <linux/ioport.h>
29 #include <linux/blkdev.h>
30 #include <linux/hdreg.h>
32 #include <linux/interrupt.h>
33 #include <linux/pci.h>
34 #include <linux/init.h>
35 #include <linux/ide.h>
37 #include <asm/io.h>
38 #include <asm/irq.h>
40 #include "ide_modes.h"
42 #ifndef SPLIT_BYTE
43 #define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
44 #endif
46 #define HPT343_DEBUG_DRIVE_INFO 0
47 #define HPT343_DISABLE_ALL_DMAING 0
48 #define HPT343_DMA_DISK_ONLY 0
50 extern char *ide_xfer_verbose (byte xfer_rate);
52 static void hpt34x_clear_chipset (ide_drive_t *drive)
54 int drive_number = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
55 unsigned int reg1 = 0, tmp1 = 0;
56 unsigned int reg2 = 0, tmp2 = 0;
58 pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, &reg1);
59 pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, &reg2);
60 tmp1 = ((0x00 << (3*drive_number)) | (reg1 & ~(7 << (3*drive_number))));
61 tmp2 = ((0x00 << drive_number) | reg2);
62 pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1);
63 pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2);
66 static int hpt34x_tune_chipset (ide_drive_t *drive, byte speed)
68 int err;
69 byte hi_speed, lo_speed;
70 int drive_number = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
71 unsigned int reg1 = 0, tmp1 = 0;
72 unsigned int reg2 = 0, tmp2 = 0;
74 SPLIT_BYTE(speed, hi_speed, lo_speed);
76 if (hi_speed & 7) {
77 hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
78 } else {
79 lo_speed <<= 5;
80 lo_speed >>= 5;
83 pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, &reg1);
84 pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, &reg2);
85 tmp1 = ((lo_speed << (3*drive_number)) | (reg1 & ~(7 << (3*drive_number))));
86 tmp2 = ((hi_speed << drive_number) | reg2);
87 err = ide_config_drive_speed(drive, speed);
88 pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1);
89 pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2);
91 #if HPT343_DEBUG_DRIVE_INFO
92 printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
93 " (0x%02x 0x%02x) 0x%04x\n",
94 drive->name, ide_xfer_verbose(speed),
95 drive_number, reg1, tmp1, reg2, tmp2,
96 hi_speed, lo_speed, err);
97 #endif /* HPT343_DEBUG_DRIVE_INFO */
99 return(err);
103 * This allows the configuration of ide_pci chipset registers
104 * for cards that learn about the drive's UDMA, DMA, PIO capabilities
105 * after the drive is reported by the OS. Initally for designed for
106 * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
108 static int config_chipset_for_dma (ide_drive_t *drive)
110 struct hd_driveid *id = drive->id;
111 byte speed = 0x00;
113 #if HPT343_DISABLE_ALL_DMAING
114 return ((int) ide_dma_off);
115 #elif HPT343_DMA_DISK_ONLY
116 if (drive->media != ide_disk)
117 return ((int) ide_dma_off_quietly);
118 #endif /* HPT343_DISABLE_ALL_DMAING */
120 if (id->dma_ultra & 0x0010) {
121 goto backspeed;
122 } else if (id->dma_ultra & 0x0008) {
123 goto backspeed;
124 } else if (id->dma_ultra & 0x0004) {
125 backspeed:
126 if (!((id->dma_ultra >> 8) & 4)) {
127 drive->id->dma_ultra &= ~0xFF00;
128 drive->id->dma_ultra |= 0x0404;
129 drive->id->dma_mword &= ~0x0F00;
130 drive->id->dma_1word &= ~0x0F00;
132 speed = XFER_UDMA_2;
133 } else if (id->dma_ultra & 0x0002) {
134 if (!((id->dma_ultra >> 8) & 2)) {
135 drive->id->dma_ultra &= ~0xFF00;
136 drive->id->dma_ultra |= 0x0202;
137 drive->id->dma_mword &= ~0x0F00;
138 drive->id->dma_1word &= ~0x0F00;
140 speed = XFER_UDMA_1;
141 } else if (id->dma_ultra & 0x0001) {
142 if (!((id->dma_ultra >> 8) & 1)) {
143 drive->id->dma_ultra &= ~0xFF00;
144 drive->id->dma_ultra |= 0x0101;
145 drive->id->dma_mword &= ~0x0F00;
146 drive->id->dma_1word &= ~0x0F00;
148 speed = XFER_UDMA_0;
149 } else if (id->dma_mword & 0x0004) {
150 if (!((id->dma_mword >> 8) & 4)) {
151 drive->id->dma_mword &= ~0x0F00;
152 drive->id->dma_mword |= 0x0404;
153 drive->id->dma_1word &= ~0x0F00;
155 speed = XFER_MW_DMA_2;
156 } else if (id->dma_mword & 0x0002) {
157 if (!((id->dma_mword >> 8) & 2)) {
158 drive->id->dma_mword &= ~0x0F00;
159 drive->id->dma_mword |= 0x0202;
160 drive->id->dma_1word &= ~0x0F00;
162 speed = XFER_MW_DMA_1;
163 } else if (id->dma_mword & 0x0001) {
164 if (!((id->dma_mword >> 8) & 1)) {
165 drive->id->dma_mword &= ~0x0F00;
166 drive->id->dma_mword |= 0x0101;
167 drive->id->dma_1word &= ~0x0F00;
169 speed = XFER_MW_DMA_0;
170 } else if (id->dma_1word & 0x0004) {
171 if (!((id->dma_1word >> 8) & 4)) {
172 drive->id->dma_1word &= ~0x0F00;
173 drive->id->dma_1word |= 0x0404;
174 drive->id->dma_mword &= ~0x0F00;
176 speed = XFER_SW_DMA_2;
177 } else if (id->dma_1word & 0x0002) {
178 if (!((id->dma_1word >> 8) & 2)) {
179 drive->id->dma_1word &= ~0x0F00;
180 drive->id->dma_1word |= 0x0202;
181 drive->id->dma_mword &= ~0x0F00;
183 speed = XFER_SW_DMA_1;
184 } else if (id->dma_1word & 0x0001) {
185 if (!((id->dma_1word >> 8) & 1)) {
186 drive->id->dma_1word &= ~0x0F00;
187 drive->id->dma_1word |= 0x0101;
188 drive->id->dma_mword &= ~0x0F00;
190 speed = XFER_SW_DMA_0;
191 } else {
192 return ((int) ide_dma_off_quietly);
195 (void) hpt34x_tune_chipset(drive, speed);
197 return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off :
198 ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
199 ((id->dma_mword >> 8) & 7) ? ide_dma_on :
200 ((id->dma_1word >> 8) & 7) ? ide_dma_on :
201 ide_dma_off_quietly);
204 static void config_chipset_for_pio (ide_drive_t *drive)
206 unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
207 unsigned short xfer_pio = drive->id->eide_pio_modes;
209 byte timing, speed, pio;
211 pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
213 if (xfer_pio> 4)
214 xfer_pio = 0;
216 if (drive->id->eide_pio_iordy > 0) {
217 for (xfer_pio = 5;
218 xfer_pio>0 &&
219 drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
220 xfer_pio--);
221 } else {
222 xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
223 (drive->id->eide_pio_modes & 2) ? 0x04 :
224 (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
227 timing = (xfer_pio >= pio) ? xfer_pio : pio;
229 switch(timing) {
230 case 4: speed = XFER_PIO_4;break;
231 case 3: speed = XFER_PIO_3;break;
232 case 2: speed = XFER_PIO_2;break;
233 case 1: speed = XFER_PIO_1;break;
234 default:
235 speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
236 break;
238 (void) hpt34x_tune_chipset(drive, speed);
241 static void hpt34x_tune_drive (ide_drive_t *drive, byte pio)
243 byte speed;
245 hpt34x_clear_chipset(drive);
246 switch(pio) {
247 case 4: speed = XFER_PIO_4;break;
248 case 3: speed = XFER_PIO_3;break;
249 case 2: speed = XFER_PIO_2;break;
250 case 1: speed = XFER_PIO_1;break;
251 default: speed = XFER_PIO_0;break;
253 (void) hpt34x_tune_chipset(drive, speed);
256 static int config_drive_xfer_rate (ide_drive_t *drive)
258 struct hd_driveid *id = drive->id;
259 ide_dma_action_t dma_func = ide_dma_on;
261 if (id && (id->capability & 1) && HWIF(drive)->autodma) {
262 /* Consult the list of known "bad" drives */
263 if (ide_dmaproc(ide_dma_bad_drive, drive)) {
264 dma_func = ide_dma_off;
265 goto fast_ata_pio;
267 dma_func = ide_dma_off_quietly;
268 if (id->field_valid & 4) {
269 if (id->dma_ultra & 0x0007) {
270 /* Force if Capable UltraDMA */
271 dma_func = config_chipset_for_dma(drive);
272 if ((id->field_valid & 2) &&
273 (dma_func != ide_dma_on))
274 goto try_dma_modes;
276 } else if (id->field_valid & 2) {
277 try_dma_modes:
278 if ((id->dma_mword & 0x0007) ||
279 (id->dma_1word & 0x0007)) {
280 /* Force if Capable regular DMA modes */
281 dma_func = config_chipset_for_dma(drive);
282 if (dma_func != ide_dma_on)
283 goto no_dma_set;
285 } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
286 if (id->eide_dma_time > 150) {
287 goto no_dma_set;
289 /* Consult the list of known "good" drives */
290 dma_func = config_chipset_for_dma(drive);
291 if (dma_func != ide_dma_on)
292 goto no_dma_set;
293 } else {
294 goto fast_ata_pio;
296 } else if ((id->capability & 8) || (id->field_valid & 2)) {
297 fast_ata_pio:
298 dma_func = ide_dma_off_quietly;
299 no_dma_set:
301 config_chipset_for_pio(drive);
303 return HWIF(drive)->dmaproc(dma_func, drive);
307 * hpt34x_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
309 * This is specific to the HPT343 UDMA bios-less chipset
310 * and HPT345 UDMA bios chipset (stamped HPT363)
311 * by HighPoint|Triones Technologies, Inc.
314 int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
316 switch (func) {
317 case ide_dma_check:
318 hpt34x_clear_chipset(drive);
319 return config_drive_xfer_rate(drive);
320 #if 0
321 case ide_dma_off:
322 case ide_dma_off_quietly:
323 case ide_dma_on:
324 case ide_dma_check:
325 return config_drive_xfer_rate(drive);
326 case ide_dma_read:
327 case ide_dma_write:
328 case ide_dma_begin:
329 case ide_dma_end:
330 case ide_dma_test_irq:
331 #endif
332 default:
333 break;
335 return ide_dmaproc(func, drive); /* use standard DMA stuff */
339 * If the BIOS does not set the IO base addaress to XX00, 343 will fail.
341 #define HPT34X_PCI_INIT_REG 0x80
343 unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name)
345 unsigned short cmd;
347 pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00);
348 pci_read_config_word(dev, PCI_COMMAND, &cmd);
349 if (cmd & PCI_COMMAND_MEMORY) {
350 if (dev->resource[PCI_ROM_RESOURCE].start) {
351 pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
352 printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->resource[PCI_ROM_RESOURCE].start);
354 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
355 } else {
356 int i = 0;
357 unsigned long hpt34xIoBase = dev->resource[4].start;
359 pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO);
360 dev->resource[0].start = (hpt34xIoBase + 0x20);
361 dev->resource[1].start = (hpt34xIoBase + 0x34);
362 dev->resource[2].start = (hpt34xIoBase + 0x28);
363 dev->resource[3].start = (hpt34xIoBase + 0x3c);
364 for(i=0; i<4; i++)
365 dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
367 * Since 20-23 can be assigned and are R/W, we correct them.
369 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, dev->resource[0].start);
370 pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start);
371 pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start);
372 pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start);
374 pci_write_config_word(dev, PCI_COMMAND, cmd);
375 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
377 return dev->irq;
380 void __init ide_init_hpt34x (ide_hwif_t *hwif)
382 hwif->tuneproc = &hpt34x_tune_drive;
383 if (hwif->dma_base) {
384 unsigned short pcicmd = 0;
386 pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
387 #ifdef CONFIG_BLK_DEV_HPT34X_DMA
388 #if 0
389 hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
390 #endif
391 #endif /* CONFIG_BLK_DEV_HPT34X_DMA */
392 hwif->dmaproc = &hpt34x_dmaproc;
393 } else {
394 hwif->drives[0].autotune = 1;
395 hwif->drives[1].autotune = 1;