patch-1.3.61 linux/drivers/block/umc8672.c
Next file: linux/drivers/char/vesa_blank.c
Previous file: linux/drivers/block/triton.c
Back to the patch index
Back to the overall index
- Lines: 186
- Date:
Fri Feb 9 07:31:23 1996
- Orig file:
v1.3.60/linux/drivers/block/umc8672.c
- Orig date:
Mon Nov 27 12:48:29 1995
diff -u --recursive --new-file v1.3.60/linux/drivers/block/umc8672.c linux/drivers/block/umc8672.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/block/umc8672.c Version 0.01 Nov 16, 1995
+ * linux/drivers/block/umc8672.c Version 0.02 Feb 06, 1996
*
- * Copyright (C) 1995 Linus Torvalds & author (see below)
+ * Copyright (C) 1995-1996 Linus Torvalds & author (see below)
*/
/*
@@ -13,6 +13,8 @@
* Version 0.01 Initial version, hacked out of ide.c,
* and #include'd rather than compiled separately.
* This will get cleaned up in a subsequent release.
+ *
+ * Version 0.02 now configs/compiles separate from ide.c -ml
*/
/*
@@ -32,77 +34,122 @@
* the results from the DOS speed test programm supplied from UMC. 11 is the
* highest speed (about PIO mode 3)
*/
+#undef REALLY_SLOW_IO /* most systems can safely undef this */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <asm/io.h>
+#include "ide.h"
/*
* The speeds will eventually become selectable using hdparm via ioctl's,
* but for now they are coded here:
*/
-#define UMC_DRIVE0 11 /* DOS messured drive Speeds */
-#define UMC_DRIVE1 11 /* 0 - 11 allowed */
-#define UMC_DRIVE2 11 /* 11 = Highest Speed */
-#define UMC_DRIVE3 11 /* In case of crash reduce speed */
+#define UMC_DRIVE0 1 /* DOS measured drive speeds */
+#define UMC_DRIVE1 1 /* 0 to 11 allowed */
+#define UMC_DRIVE2 1 /* 11 = Fastest Speed */
+#define UMC_DRIVE3 1 /* In case of crash reduce speed */
+
+static byte current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
+static const byte pio_to_umc [5] = {0,3,6,10,11}; /* rough guesses */
+
+/* 0 1 2 3 4 5 6 7 8 9 10 11 */
+static const byte speedtab [3][12] = {
+ {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
+ {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
+ {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
-void out_umc (char port,char wert)
+static void out_umc (char port,char wert)
{
outb_p (port,0x108);
outb_p (wert,0x109);
}
-byte in_umc (char port)
+static byte in_umc (char port)
{
outb_p (port,0x108);
return inb_p (0x109);
}
-void init_umc8672(void)
+static void umc_set_speeds (byte speeds[])
{
- int i,tmp;
- int speed [4];
-/* 0 1 2 3 4 5 6 7 8 9 10 11 */
- char speedtab [3][12] = {
- {0xf ,0xb ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
- {0x3 ,0x2 ,0x2 ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
- {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
+ int i, tmp;
+ unsigned long flags;
+ save_flags(flags);
cli ();
outb_p (0x5A,0x108); /* enable umc */
- if (in_umc (0xd5) != 0xa0)
- {
- sti ();
- printk ("UMC8672 not found\n");
- return;
- }
- speed[0] = UMC_DRIVE0;
- speed[1] = UMC_DRIVE1;
- speed[2] = UMC_DRIVE2;
- speed[3] = UMC_DRIVE3;
- for (i = 0;i < 4;i++)
- {
- if ((speed[i] < 0) || (speed[i] > 11))
- {
- sti ();
- printk ("UMC 8672 drive speed out of range. Drive %d Speed %d\n",
- i, speed[i]);
- printk ("UMC support aborted\n");
- return;
- }
- }
- out_umc (0xd7,(speedtab[0][speed[2]] | (speedtab[0][speed[3]]<<4)));
- out_umc (0xd6,(speedtab[0][speed[0]] | (speedtab[0][speed[1]]<<4)));
+
+ out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4)));
+ out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4)));
tmp = 0;
for (i = 3; i >= 0; i--)
{
- tmp = (tmp << 2) | speedtab[1][speed[i]];
+ tmp = (tmp << 2) | speedtab[1][speeds[i]];
}
out_umc (0xdc,tmp);
for (i = 0;i < 4; i++)
{
- out_umc (0xd0+i,speedtab[2][speed[i]]);
- out_umc (0xd8+i,speedtab[2][speed[i]]);
+ out_umc (0xd0+i,speedtab[2][speeds[i]]);
+ out_umc (0xd8+i,speedtab[2][speeds[i]]);
}
outb_p (0xa5,0x108); /* disable umc */
- sti ();
- printk ("Speeds for UMC8672 \n");
- for (i = 0;i < 4;i++)
- printk ("Drive %d speed %d\n",i,speed[i]);
+ restore_flags(flags);
+
+ printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
+ speeds[0], speeds[1], speeds[2], speeds[4]);
+}
+
+static void tune_umc (ide_drive_t *drive, byte pio)
+{
+ if (pio == 255) { /* auto-tune */
+ struct hd_driveid *id = drive->id;
+ pio = id->tPIO;
+ if (id->field_valid & 0x02) {
+ if (id->eide_pio_modes & 0x01)
+ pio = 3;
+ if (id->eide_pio_modes & 0x02)
+ pio = 4;
+ }
+ }
+ if (pio > 4)
+ pio = 4;
+ current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
+ umc_set_speeds (current_speeds);
+}
+
+void init_umc8672 (void) /* called from ide.c */
+{
+ unsigned long flags;
+
+ if (check_region(0x108, 2)) {
+ printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n");
+ return;
+ }
+ save_flags(flags);
+ cli ();
+ outb_p (0x5A,0x108); /* enable umc */
+ if (in_umc (0xd5) != 0xa0)
+ {
+ sti ();
+ printk ("umc8672: not found\n");
+ return;
+ }
+ outb_p (0xa5,0x108); /* disable umc */
+ restore_flags(flags);
+
+ umc_set_speeds (current_speeds);
+
+ request_region(0x108, 2, "umc8672");
+ ide_hwifs[0].chipset = ide_umc8672;
+ ide_hwifs[1].chipset = ide_umc8672;
+ ide_hwifs[0].tuneproc = &tune_umc;
+ ide_hwifs[1].tuneproc = &tune_umc;
+
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this