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

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