root/drivers/block/umc8672.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. out_umc
  2. in_umc
  3. umc_set_speeds
  4. tune_umc
  5. init_umc8672

   1 /*
   2  *  linux/drivers/block/umc8672.c       Version 0.02  Feb 06, 1996
   3  *
   4  *  Copyright (C) 1995-1996  Linus Torvalds & author (see below)
   5  */
   6 
   7 /*
   8  *  Principal Author/Maintainer:  PODIEN@hml2.atlas.de (Wolfram Podien)
   9  *
  10  *  This file provides support for the advanced features
  11  *  of the UMC 8672 IDE interface.
  12  *
  13  *  Version 0.01        Initial version, hacked out of ide.c,
  14  *                      and #include'd rather than compiled separately.
  15  *                      This will get cleaned up in a subsequent release.
  16  *
  17  *  Version 0.02        now configs/compiles separate from ide.c  -ml
  18  */
  19 
  20 /*
  21  * VLB Controller Support from 
  22  * Wolfram Podien
  23  * Rohoefe 3
  24  * D28832 Achim
  25  * Germany
  26  *
  27  * To enable UMC8672 support there must a lilo line like
  28  * append="hd=umc8672"...
  29  * To set the speed according to the abilities of the hardware there must be a
  30  * line like
  31  * #define UMC_DRIVE0 11
  32  * in the beginning of the driver, which sets the speed of drive 0 to 11 (there
  33  * are some lines present). 0 - 11 are allowed speed values. These values are
  34  * the results from the DOS speed test programm supplied from UMC. 11 is the 
  35  * highest speed (about PIO mode 3)
  36  */
  37 #undef REALLY_SLOW_IO           /* most systems can safely undef this */
  38 
  39 #include <linux/types.h>
  40 #include <linux/kernel.h>
  41 #include <linux/delay.h>
  42 #include <linux/timer.h>
  43 #include <linux/mm.h>
  44 #include <linux/ioport.h>
  45 #include <linux/blkdev.h>
  46 #include <linux/hdreg.h>
  47 #include <asm/io.h>
  48 #include "ide.h"
  49 
  50 /*
  51  * The speeds will eventually become selectable using hdparm via ioctl's,
  52  * but for now they are coded here:
  53  */
  54 #define UMC_DRIVE0      1              /* DOS measured drive speeds */
  55 #define UMC_DRIVE1      1              /* 0 to 11 allowed */
  56 #define UMC_DRIVE2      1              /* 11 = Fastest Speed */
  57 #define UMC_DRIVE3      1              /* In case of crash reduce speed */
  58 
  59 static byte current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
  60 static const byte pio_to_umc [5] = {0,3,6,10,11};       /* rough guesses */
  61 
  62 /*       0    1    2    3    4    5    6    7    8    9    10   11      */
  63 static const byte speedtab [3][12] = {
  64         {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
  65         {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
  66         {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
  67 
  68 static void out_umc (char port,char wert)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70         outb_p (port,0x108);
  71         outb_p (wert,0x109);
  72 }
  73 
  74 static byte in_umc (char port)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         outb_p (port,0x108);
  77         return inb_p (0x109);
  78 }
  79 
  80 static void umc_set_speeds (byte speeds[])
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82         int i, tmp;
  83         unsigned long flags;
  84 
  85         save_flags(flags);
  86         cli ();
  87         outb_p (0x5A,0x108); /* enable umc */
  88 
  89         out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4)));
  90         out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4)));
  91         tmp = 0;
  92         for (i = 3; i >= 0; i--)
  93         {
  94                 tmp = (tmp << 2) | speedtab[1][speeds[i]];
  95         }
  96         out_umc (0xdc,tmp);
  97         for (i = 0;i < 4; i++)
  98         {
  99                 out_umc (0xd0+i,speedtab[2][speeds[i]]);
 100                 out_umc (0xd8+i,speedtab[2][speeds[i]]);
 101         }
 102         outb_p (0xa5,0x108); /* disable umc */
 103         restore_flags(flags);
 104 
 105         printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
 106                 speeds[0], speeds[1], speeds[2], speeds[4]);
 107 }
 108 
 109 static void tune_umc (ide_drive_t *drive, byte pio)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         if (pio == 255)  {      /* auto-tune */
 112                 struct hd_driveid *id = drive->id;
 113                 pio = id->tPIO;
 114                 if (id->field_valid & 0x02) {
 115                         if (id->eide_pio_modes & 0x01)
 116                                 pio = 3;
 117                         if (id->eide_pio_modes & 0x02)
 118                                 pio = 4;
 119                 }
 120         }
 121         if (pio > 4)
 122                 pio = 4;
 123         current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
 124         umc_set_speeds (current_speeds);
 125 }
 126 
 127 void init_umc8672 (void)        /* called from ide.c */
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         unsigned long flags;
 130 
 131         if (check_region(0x108, 2)) {
 132                 printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n");
 133                 return;
 134         }
 135         save_flags(flags);
 136         cli ();
 137         outb_p (0x5A,0x108); /* enable umc */
 138         if (in_umc (0xd5) != 0xa0)
 139         {
 140                 sti ();
 141                 printk ("umc8672: not found\n");
 142                 return;  
 143         }
 144         outb_p (0xa5,0x108); /* disable umc */
 145         restore_flags(flags);
 146 
 147         umc_set_speeds (current_speeds);
 148 
 149         request_region(0x108, 2, "umc8672");
 150         ide_hwifs[0].chipset = ide_umc8672;
 151         ide_hwifs[1].chipset = ide_umc8672;
 152         ide_hwifs[0].tuneproc = &tune_umc;
 153         ide_hwifs[1].tuneproc = &tune_umc;
 154 
 155 }

/* [previous][next][first][last][top][bottom][index][help] */