root/drivers/block/cmd640.c

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

DEFINITIONS

This source file includes following definitions.
  1. put_cmd640_reg_pci1
  2. get_cmd640_reg_pci1
  3. put_cmd640_reg_pci2
  4. get_cmd640_reg_pci2
  5. put_cmd640_reg_vlb
  6. get_cmd640_reg_vlb
  7. probe_for_cmd640_pci1
  8. probe_for_cmd640_pci2
  9. probe_for_cmd640_vlb
  10. cmd640_reset_controller
  11. ide_probe_for_cmd640x
  12. as_clocks
  13. set_readahead_mode
  14. known_drive_readahead
  15. cmd640_set_timing
  16. known_drive_pio
  17. cmd640_timings_to_regvals
  18. set_pio_mode
  19. cmd640_tune_drive

   1 /*
   2  *  linux/drivers/block/cmd640.c        Version 0.04  Jan 11, 1996
   3  *
   4  *  Copyright (C) 1995-1996  Linus Torvalds & author (see below)
   5  */
   6 
   7 /*
   8  *  Principal Author/Maintainer:  abramov@cecmow.enet.dec.com (Igor)
   9  *
  10  *  This file provides support for the advanced features and bugs
  11  *  of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
  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        Fixes for vlb initialization code, enable
  18  *                      read-ahead for versions 'B' and 'C' of chip by
  19  *                      default, some code cleanup.
  20  *
  21  *  Version 0.03        Added reset of secondary interface,
  22  *                      and black list for devices which are not compatible
  23  *                      with read ahead mode. Separate function for setting
  24  *                      readahead is added, possibly it will be called some
  25  *                      day from ioctl processing code.
  26  *
  27  *  Version 0.04        Now configs/compiles separate from ide.c  -ml
  28  */
  29 
  30 /*
  31  *  There is a known problem with current version of this driver.
  32  *  If the only device on secondary interface is CD-ROM, at some
  33  *  computers it is not recognized. In all reported cases CD-ROM
  34  *  was 2x or 4x speed Mitsumi drive.
  35  *
  36  *  The following workarounds could work:
  37  * 
  38  *    1. put CD-ROM as slave on primary interface
  39  *
  40  *    2. or define symbol at next line as 0
  41  * 
  42  */
  43 
  44 #define CMD640_NORMAL_INIT 1
  45 
  46 #undef REALLY_SLOW_IO           /* most systems can safely undef this */
  47 
  48 #include <linux/types.h>
  49 #include <linux/kernel.h>
  50 #include <linux/delay.h>
  51 #include <linux/timer.h>
  52 #include <linux/mm.h>
  53 #include <linux/ioport.h>
  54 #include <linux/blkdev.h>
  55 #include <linux/hdreg.h>
  56 #include <asm/io.h>
  57 
  58 #include "ide.h"
  59 
  60 extern ide_hwif_t ide_hwifs[];
  61 
  62 int cmd640_vlb = 0;
  63 
  64 /*
  65  * CMD640 specific registers definition.
  66  */
  67 
  68 #define VID             0x00
  69 #define DID             0x02
  70 #define PCMD            0x04
  71 #define PSTTS           0x06
  72 #define REVID           0x08
  73 #define PROGIF          0x09
  74 #define SUBCL           0x0a
  75 #define BASCL           0x0b
  76 #define BaseA0          0x10
  77 #define BaseA1          0x14
  78 #define BaseA2          0x18
  79 #define BaseA3          0x1c
  80 #define INTLINE         0x3c
  81 #define INPINE          0x3d
  82 
  83 #define CFR             0x50
  84 #define   CFR_DEVREV            0x03
  85 #define   CFR_IDE01INTR         0x04
  86 #define   CFR_DEVID             0x18
  87 #define   CFR_AT_VESA_078h      0x20
  88 #define   CFR_DSA1              0x40
  89 #define   CFR_DSA0              0x80
  90 
  91 #define CNTRL           0x51
  92 #define   CNTRL_DIS_RA0         0x40
  93 #define   CNTRL_DIS_RA1         0x80
  94 #define   CNTRL_ENA_2ND         0x08
  95 
  96 #define CMDTIM          0x52
  97 #define ARTTIM0         0x53
  98 #define DRWTIM0         0x54
  99 #define ARTTIM1         0x55
 100 #define DRWTIM1         0x56
 101 #define ARTTIM23        0x57
 102 #define   DIS_RA2               0x04
 103 #define   DIS_RA3               0x08
 104 #define DRWTIM23        0x58
 105 #define BRST            0x59
 106 
 107 /* Interface to access cmd640x registers */
 108 static void (*put_cmd640_reg)(int key, int reg_no, int val);
 109 static byte (*get_cmd640_reg)(int key, int reg_no);
 110 
 111 enum { none, vlb, pci1, pci2 };
 112 static int      bus_type = none;
 113 static int      cmd640_chip_version;
 114 static int      cmd640_key;
 115 static byte     is_cmd640[MAX_HWIFS];
 116 static int      bus_speed; /* MHz */
 117 
 118 /*
 119  * For some unknown reasons pcibios functions which read and write registers
 120  * do not always work with cmd640. We use direct io instead.
 121  */
 122 
 123 /* PCI method 1 access */
 124 
 125 static void put_cmd640_reg_pci1(int key, int reg_no, int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 126 {
 127         unsigned long flags;
 128 
 129         save_flags(flags);
 130         cli();
 131         outl_p((reg_no & 0xfc) | key, 0xcf8);
 132         outb_p(val, (reg_no & 3) + 0xcfc);
 133         restore_flags(flags);
 134 }
 135 
 136 static byte get_cmd640_reg_pci1(int key, int reg_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138         byte b;
 139         unsigned long flags;
 140 
 141         save_flags(flags);
 142         cli();
 143         outl_p((reg_no & 0xfc) | key, 0xcf8);
 144         b = inb_p(0xcfc + (reg_no & 3));
 145         restore_flags(flags);
 146         return b;
 147 }
 148 
 149 /* PCI method 2 access (from CMD datasheet) */
 150 
 151 static void put_cmd640_reg_pci2(int key, int reg_no, int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 153         unsigned long flags;
 154 
 155         save_flags(flags);
 156         cli();
 157         outb_p(0x10, 0xcf8);
 158         outb_p(val, key + reg_no);
 159         outb_p(0, 0xcf8);
 160         restore_flags(flags);
 161 }
 162 
 163 static byte get_cmd640_reg_pci2(int key, int reg_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         byte b;
 166         unsigned long flags;
 167 
 168         save_flags(flags);
 169         cli();
 170         outb_p(0x10, 0xcf8);
 171         b = inb_p(key + reg_no);
 172         outb_p(0, 0xcf8);
 173         restore_flags(flags);
 174         return b;
 175 }
 176 
 177 /* VLB access */
 178 
 179 static void put_cmd640_reg_vlb(int key, int reg_no, int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         unsigned long flags;
 182 
 183         save_flags(flags);
 184         cli();
 185         outb_p(reg_no, key + 8);
 186         outb_p(val, key + 0xc);
 187         restore_flags(flags);
 188 }
 189 
 190 static byte get_cmd640_reg_vlb(int key, int reg_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192         byte b;
 193         unsigned long flags;
 194 
 195         save_flags(flags);
 196         cli();
 197         outb_p(reg_no, key + 8);
 198         b = inb_p(key + 0xc);
 199         restore_flags(flags);
 200         return b;
 201 }
 202 
 203 /*
 204  * Probe for CMD640x -- pci method 1
 205  */
 206 
 207 static int probe_for_cmd640_pci1(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         long id;
 210         int     k;
 211 
 212         for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
 213                 outl(k, 0xcf8);
 214                 id = inl(0xcfc);
 215                 if (id != 0x06401095)
 216                         continue;
 217                 put_cmd640_reg = put_cmd640_reg_pci1;
 218                 get_cmd640_reg = get_cmd640_reg_pci1;
 219                 cmd640_key = k;
 220                 return 1;
 221         }
 222         return 0;
 223 }
 224 
 225 /*
 226  * Probe for CMD640x -- pci method 2
 227  */
 228 
 229 static int probe_for_cmd640_pci2(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         int i;
 232         int v_id;
 233         int d_id;
 234 
 235         for (i = 0xc000; i <= 0xcf00; i += 0x100) {
 236                 outb(0x10, 0xcf8);
 237                 v_id = inw(i);
 238                 d_id = inw(i + 2);
 239                 outb(0, 0xcf8);
 240                 if (v_id != 0x1095 || d_id != 0x640)
 241                         continue;
 242                 put_cmd640_reg = put_cmd640_reg_pci2;
 243                 get_cmd640_reg = get_cmd640_reg_pci2;
 244                 cmd640_key = i;
 245                 return 1;
 246         }
 247         return 0;
 248 }
 249 
 250 /*
 251  * Probe for CMD640x -- vlb
 252  */
 253 
 254 static int probe_for_cmd640_vlb(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 255         byte b;
 256 
 257         outb(CFR, 0x178);
 258         b = inb(0x17c);
 259         if (b == 0xff || b == 0 || (b & CFR_AT_VESA_078h)) {
 260                 outb(CFR, 0x78);
 261                 b = inb(0x7c);
 262                 if (b == 0xff || b == 0 || !(b & CFR_AT_VESA_078h))
 263                         return 0;
 264                 cmd640_key = 0x70;
 265         } else {
 266                 cmd640_key = 0x170;
 267         }
 268         put_cmd640_reg = put_cmd640_reg_vlb;
 269         get_cmd640_reg = get_cmd640_reg_vlb;
 270         return 1;
 271 }
 272 
 273 /*
 274  * Low level reset for controller, actually it has nothing specific for
 275  * CMD640, but I don't know how to use standard reset routine before
 276  * we recognized any drives.
 277  */
 278 
 279 static void cmd640_reset_controller(int iface_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         int retry_count = 600;
 282         int base_port = iface_no ? 0x170 : 0x1f0;
 283 
 284         outb_p(4, base_port + 7);
 285         udelay(5);
 286         outb_p(0, base_port + 7);
 287 
 288         do {
 289                 udelay(5);
 290                 retry_count -= 1;
 291         } while ((inb_p(base_port + 7) & 0x80) && retry_count);
 292 
 293         if (retry_count == 0)
 294                 printk("cmd640: failed to reset controller %d\n", iface_no);
 295 #if 0   
 296         else
 297                 printk("cmd640: controller %d reset [%d]\n", 
 298                         iface_no, retry_count);
 299 #endif
 300 }
 301 
 302 /*
 303  * Probe for Cmd640x and initialize it if found
 304  */
 305 
 306 int ide_probe_for_cmd640x(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 307 {
 308         int  i;
 309         int  second_port;
 310         int  cmd_read_ahead;
 311         byte b;
 312 
 313         for (i = 0; i < MAX_HWIFS; i++)
 314                 is_cmd640[i] = 0;
 315 
 316         if (probe_for_cmd640_pci1()) {
 317                 bus_type = pci1;
 318         } else if (probe_for_cmd640_pci2()) {
 319                 bus_type = pci2;
 320         } else if (cmd640_vlb && probe_for_cmd640_vlb()) {
 321                 /* May be remove cmd640_vlb at all, and probe in any case */
 322                 bus_type = vlb;
 323         } else {
 324                 return 0;
 325         }
 326 
 327         /*
 328          * Undocumented magic. (There is no 0x5b port in specs)
 329          */
 330 
 331         put_cmd640_reg(cmd640_key, 0x5b, 0xbd);
 332         if (get_cmd640_reg(cmd640_key, 0x5b) != 0xbd) {
 333                 printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
 334                 return 0;
 335         }
 336         put_cmd640_reg(cmd640_key, 0x5b, 0);
 337 
 338         /*
 339          * Documented magic.
 340          */
 341 
 342         cmd640_chip_version = get_cmd640_reg(cmd640_key, CFR) & CFR_DEVREV;
 343         if (cmd640_chip_version == 0) {
 344                 printk ("ide: wrong CMD640 version -- 0\n");
 345                 return 0;
 346         }
 347 
 348         /*
 349          * Do not initialize secondary controller for vlbus
 350          */
 351         second_port = (bus_type != vlb);
 352 
 353         /*
 354          * Set the maximum allowed bus speed (it is safest until we
 355          *                                    find how to detect bus speed)
 356          * Normally PCI bus runs at 33MHz, but often works overclocked to 40
 357          */
 358         bus_speed = (bus_type == vlb) ? 50 : 40; 
 359 
 360         /*
 361          * Enable readahead for versions above 'A'
 362          */
 363         cmd_read_ahead = (cmd640_chip_version > 1);
 364 
 365         /*
 366          * Setup Control Register
 367          */
 368         b = get_cmd640_reg(cmd640_key, CNTRL);  
 369 
 370 #if CMD640_NORMAL_INIT
 371         if (second_port)
 372                 b |= CNTRL_ENA_2ND;
 373         else
 374                 b &= ~CNTRL_ENA_2ND;
 375 #endif 
 376 
 377         if (cmd_read_ahead)
 378                 b &= ~(CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
 379         else
 380                 b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
 381 
 382 
 383         put_cmd640_reg(cmd640_key, CNTRL, b);
 384 
 385         /*
 386          * Initialize 2nd IDE port, if required
 387          */
 388         if (second_port) {
 389                 /* We reset timings, and setup read-ahead */
 390                 b = cmd_read_ahead ? 0 : (DIS_RA2 | DIS_RA3);
 391                 put_cmd640_reg(cmd640_key, ARTTIM23, b);
 392                 put_cmd640_reg(cmd640_key, DRWTIM23, 0);
 393 
 394                 cmd640_reset_controller(1);
 395         }
 396 
 397         ide_hwifs[0].serialized = 1;
 398 
 399         printk("ide: buggy CMD640%c interface at ", 
 400                'A' - 1 + cmd640_chip_version);
 401         switch (bus_type) {
 402                 case vlb :
 403                         printk("local bus, port 0x%x", cmd640_key);
 404                         break;
 405                 case pci1:
 406                         printk("pci, (0x%x)", cmd640_key);
 407                         break;
 408                 case pci2:
 409                         printk("pci,(access method 2) (0x%x)", cmd640_key);
 410                         break;
 411         }
 412 
 413         is_cmd640[0] = is_cmd640[1] = 1;
 414 
 415         /*
 416          * Reset interface timings
 417          */
 418         put_cmd640_reg(cmd640_key, CMDTIM, 0);
 419 
 420         printk("\n ... serialized, %s read-ahead, secondary interface %s\n",
 421                cmd_read_ahead ? "enabled" : "disabled",
 422                second_port ? "enabled" : "disabled");
 423 
 424         return 1;
 425 }
 426 
 427 static int as_clocks(int a) {
     /* [previous][next][first][last][top][bottom][index][help] */
 428         switch (a & 0xc0) {
 429                 case 0 :        return 4;
 430                 case 0x40 :     return 2;
 431                 case 0x80 :     return 3;
 432                 case 0xc0 :     return 5;
 433                 default :       return -1;
 434         }
 435 }
 436 
 437 /*
 438  * Sets readahead mode for specific drive
 439  *  in the future it could be called from ioctl
 440  */
 441 
 442 static void set_readahead_mode(int mode, int if_num, int dr_num)
     /* [previous][next][first][last][top][bottom][index][help] */
 443 {
 444         static int masks[2][2] = 
 445                 { 
 446                         {CNTRL_DIS_RA0, CNTRL_DIS_RA1}, 
 447                         {DIS_RA2,       DIS_RA3}
 448                 };
 449 
 450         int port = (if_num == 0) ? CNTRL : ARTTIM23;
 451         int mask = masks[if_num][dr_num];
 452         byte b;
 453 
 454         b = get_cmd640_reg(cmd640_key, port);
 455         if (mode)
 456                 b &= mask; /* Enable readahead for specific drive */
 457         else
 458                 b |= mask; /* Disable readahed for specific drive */
 459         put_cmd640_reg(cmd640_key, port, b);
 460 }               
 461 
 462 static struct readahead_black_list {
 463         const char*     name;
 464         int             mode;   
 465 } drives_ra[] = {
 466         { "ST3655A",    0 },
 467         { NULL, 0 }
 468 };      
 469 
 470 static int known_drive_readahead(char* name) {
     /* [previous][next][first][last][top][bottom][index][help] */
 471         int i;
 472 
 473         for (i = 0; drives_ra[i].name != NULL; i++)
 474                 if (strcmp(name, drives_ra[i].name) == 0)
 475                         return drives_ra[i].mode;
 476         return -1;
 477 }
 478 
 479 /*
 480  * Tuning of drive parameters
 481  */
 482 
 483 static void cmd640_set_timing(int if_num, int dr_num, int r1, int r2) {
     /* [previous][next][first][last][top][bottom][index][help] */
 484         int  b_reg;
 485         byte b;
 486         int  r52;
 487         static int a = 0;
 488 
 489         b_reg = if_num ? ARTTIM23 : dr_num ? ARTTIM1 : ARTTIM0;
 490 
 491         if (if_num == 0) {
 492                 put_cmd640_reg(cmd640_key, b_reg, r1);
 493                 put_cmd640_reg(cmd640_key, b_reg + 1, r2);
 494         } else {
 495                 b = get_cmd640_reg(cmd640_key, b_reg);
 496                 if (a == 0 || as_clocks(b) < as_clocks(r1))
 497                         put_cmd640_reg(cmd640_key, b_reg, (b & 0xc0) | r1);
 498                 
 499                 if (a == 0) {
 500                         put_cmd640_reg(cmd640_key, b_reg + 1, r2);
 501                 } else {
 502                         b = get_cmd640_reg(cmd640_key, b_reg + 1);
 503                         r52 =  (b&0x0f) < (r2&0x0f) ? (r2&0x0f) : (b&0x0f);
 504                         r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
 505                         put_cmd640_reg(cmd640_key, b_reg+1, r52);
 506                 }
 507                 a = 1;
 508         }
 509 
 510         b = get_cmd640_reg(cmd640_key, CMDTIM);
 511         if (b == 0) {
 512                 put_cmd640_reg(cmd640_key, CMDTIM, r2);
 513         } else {
 514                 r52  = (b&0x0f) < (r2&0x0f) ? (r2&0x0f) : (b&0x0f);
 515                 r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
 516                 put_cmd640_reg(cmd640_key, CMDTIM, r52);
 517         }
 518 }
 519 
 520 static struct pio_timing {
 521         int     mc_time;        /* Minimal cycle time (ns) */
 522         int     av_time;        /* Address valid to DIOR-/DIOW- setup (ns) */
 523         int     ds_time;        /* DIOR data setup      (ns) */
 524 } pio_timings[6] = {
 525         { 70,   165,    600 },  /* PIO Mode 0 */
 526         { 50,   125,    383 },  /* PIO Mode 1 */
 527         { 30,   100,    240 },  /* PIO Mode 2 */
 528         { 30,   80,     180 },  /* PIO Mode 3 */
 529         { 25,   70,     125 },  /* PIO Mode 4 */
 530         { 20,   50,     100 }   /* PIO Mode ? */
 531 };
 532 
 533 static struct drive_pio_info {
 534         const char      *name;
 535         int             pio;
 536 } drive_pios[] = {
 537         { "Maxtor 7131 AT", 1 },
 538         { "Maxtor 7171 AT", 1 },
 539         { "Maxtor 7213 AT", 1 },
 540         { "Maxtor 7245 AT", 1 },
 541         { "SAMSUNG SHD-3122A", 1 },
 542         { "QUANTUM ELS127A", 0 },
 543         { "QUANTUM LPS240A", 0 },
 544         { "QUANTUM LPS270A", 3 },
 545         { "QUANTUM LPS540A", 3 },
 546         { "QUANTUM FIREBALL1080A", 3 },
 547         { NULL, 0 }
 548 };
 549 
 550 static int known_drive_pio(char* name) {
     /* [previous][next][first][last][top][bottom][index][help] */
 551         struct drive_pio_info* pi;
 552 
 553         for (pi = drive_pios; pi->name != NULL; pi++) {
 554                 if (strcmp(pi->name, name) == 0)
 555                         return pi->pio;
 556         }
 557         return -1;
 558 }
 559 
 560 static void cmd640_timings_to_regvals(int mc_time, int av_time, int ds_time,
     /* [previous][next][first][last][top][bottom][index][help] */
 561                                 int clock_time,
 562                                 int* r1, int* r2)
 563 {
 564         int a, b;
 565 
 566         a = (mc_time + clock_time - 1)/clock_time;
 567         if (a <= 2) *r1 = 0x40;
 568         else if (a == 3) *r1 = 0x80;
 569         else if (a == 4) *r1 = 0;
 570         else *r1 = 0xc0;
 571 
 572         a = (av_time + clock_time - 1)/clock_time;
 573         if (a < 2)
 574                 a = 2;
 575         b = (ds_time + clock_time - 1)/clock_time - a;
 576         if (b < 2)
 577                 b = 2;
 578         if (b > 0x11) {
 579                 a += b - 0x11;
 580                 b = 0x11;
 581         }
 582         if (a > 0xf)
 583                 a = 0;
 584         if (cmd640_chip_version > 1)
 585                 b -= 1;
 586         if (b > 0xf)
 587                 b = 0;
 588         *r2 = (a << 4) | b;
 589 }
 590 
 591 static void set_pio_mode(int if_num, int drv_num, int mode_num) {
     /* [previous][next][first][last][top][bottom][index][help] */
 592         int p_base;
 593         int i;
 594 
 595         p_base = if_num ? 0x170 : 0x1f0;
 596         outb_p(3, p_base + 1);
 597         outb_p(mode_num | 8, p_base + 2);
 598         outb_p((drv_num | 0xa) << 4, p_base + 6);
 599         outb_p(0xef, p_base + 7);
 600         for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
 601                 udelay(10000);
 602 }
 603 
 604 void cmd640_tune_drive(ide_drive_t* drive) {
     /* [previous][next][first][last][top][bottom][index][help] */
 605         int interface_number;
 606         int drive_number;
 607         int clock_time; /* ns */
 608         int max_pio;
 609         int mc_time, av_time, ds_time;
 610         struct hd_driveid* id;
 611         int r1, r2;
 612         int mode;
 613 
 614         /*
 615          * Determine if drive is under cmd640 control
 616          */
 617         interface_number = HWIF(drive) - ide_hwifs;
 618         if (!is_cmd640[interface_number])
 619                 return;
 620 
 621         drive_number = drive - HWIF(drive)->drives;
 622         clock_time = 1000/bus_speed;
 623         id = drive->id;
 624         if ((max_pio = known_drive_pio(id->model)) != -1) {
 625                 mc_time = pio_timings[max_pio].mc_time;
 626                 av_time = pio_timings[max_pio].av_time;
 627                 ds_time = pio_timings[max_pio].ds_time;
 628         } else {
 629                 max_pio = id->tPIO;
 630                 mc_time = pio_timings[max_pio].mc_time;
 631                 av_time = pio_timings[max_pio].av_time;
 632                 ds_time = pio_timings[max_pio].ds_time;
 633                 if (id->field_valid & 2) {
 634                         if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
 635                                 if (id->eide_pio_modes & 4) max_pio = 5;
 636                                 else if (id->eide_pio_modes & 2) max_pio = 4;
 637                                 else max_pio = 3;
 638                                 ds_time = id->eide_pio_iordy;
 639                                 mc_time = pio_timings[max_pio].mc_time;
 640                                 av_time = pio_timings[max_pio].av_time;
 641                         } else {
 642                                 ds_time = id->eide_pio;
 643                         }
 644                         if (ds_time == 0)
 645                                 ds_time = pio_timings[max_pio].ds_time;
 646                 }
 647         }
 648         cmd640_timings_to_regvals(mc_time, av_time, ds_time, clock_time,
 649                                 &r1, &r2);
 650         set_pio_mode(interface_number, drive_number, max_pio);
 651         cmd640_set_timing(interface_number, drive_number, r1, r2);
 652 
 653         /*
 654          * Disable (or set) readahead mode for known drive
 655          */
 656         if ((mode = known_drive_readahead(id->model)) != -1) {
 657                 set_readahead_mode(mode, interface_number, drive_number);
 658                 printk("Readahead %s,", mode ? "enabled" : "disabled");
 659         }
 660         printk ("Mode and Timing set to PIO%d (0x%x 0x%x)\n", max_pio, r1, r2);
 661 }

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