linux/drivers/ide/cmd640.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  Copyright (C) 1995-1996  Linus Torvalds & authors (see below)
   4 */
   5
   6/*
   7 *  Original authors:   abramov@cecmow.enet.dec.com (Igor Abramov)
   8 *                      mlord@pobox.com (Mark Lord)
   9 *
  10 *  See linux/MAINTAINERS for address of current maintainer.
  11 *
  12 *  This file provides support for the advanced features and bugs
  13 *  of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
  14 *
  15 *  These chips are basically fucked by design, and getting this driver
  16 *  to work on every motherboard design that uses this screwed chip seems
  17 *  bloody well impossible.  However, we're still trying.
  18 *
  19 *  Version 0.97 worked for everybody.
  20 *
  21 *  User feedback is essential.  Many thanks to the beta test team:
  22 *
  23 *  A.Hartgers@stud.tue.nl, JZDQC@CUNYVM.CUNY.edu, abramov@cecmow.enet.dec.com,
  24 *  bardj@utopia.ppp.sn.no, bart@gaga.tue.nl, bbol001@cs.auckland.ac.nz,
  25 *  chrisc@dbass.demon.co.uk, dalecki@namu26.Num.Math.Uni-Goettingen.de,
  26 *  derekn@vw.ece.cmu.edu, florian@btp2x3.phy.uni-bayreuth.de,
  27 *  flynn@dei.unipd.it, gadio@netvision.net.il, godzilla@futuris.net,
  28 *  j@pobox.com, jkemp1@mises.uni-paderborn.de, jtoppe@hiwaay.net,
  29 *  kerouac@ssnet.com, meskes@informatik.rwth-aachen.de, hzoli@cs.elte.hu,
  30 *  peter@udgaard.isgtec.com, phil@tazenda.demon.co.uk, roadcapw@cfw.com,
  31 *  s0033las@sun10.vsz.bme.hu, schaffer@tam.cornell.edu, sjd@slip.net,
  32 *  steve@ei.org, ulrpeg@bigcomm.gun.de, ism@tardis.ed.ac.uk, mack@cray.com
  33 *  liug@mama.indstate.edu, and others.
  34 *
  35 *  Version 0.01        Initial version, hacked out of ide.c,
  36 *                      and #include'd rather than compiled separately.
  37 *                      This will get cleaned up in a subsequent release.
  38 *
  39 *  Version 0.02        Fixes for vlb initialization code, enable prefetch
  40 *                      for versions 'B' and 'C' of chip by default,
  41 *                      some code cleanup.
  42 *
  43 *  Version 0.03        Added reset of secondary interface,
  44 *                      and black list for devices which are not compatible
  45 *                      with prefetch mode. Separate function for setting
  46 *                      prefetch is added, possibly it will be called some
  47 *                      day from ioctl processing code.
  48 *
  49 *  Version 0.04        Now configs/compiles separate from ide.c
  50 *
  51 *  Version 0.05        Major rewrite of interface timing code.
  52 *                      Added new function cmd640_set_mode to set PIO mode
  53 *                      from ioctl call. New drives added to black list.
  54 *
  55 *  Version 0.06        More code cleanup. Prefetch is enabled only for
  56 *                      detected hard drives, not included in prefetch
  57 *                      black list.
  58 *
  59 *  Version 0.07        Changed to more conservative drive tuning policy.
  60 *                      Unknown drives, which report PIO < 4 are set to
  61 *                      (reported_PIO - 1) if it is supported, or to PIO0.
  62 *                      List of known drives extended by info provided by
  63 *                      CMD at their ftp site.
  64 *
  65 *  Version 0.08        Added autotune/noautotune support.
  66 *
  67 *  Version 0.09        Try to be smarter about 2nd port enabling.
  68 *  Version 0.10        Be nice and don't reset 2nd port.
  69 *  Version 0.11        Try to handle more weird situations.
  70 *
  71 *  Version 0.12        Lots of bug fixes from Laszlo Peter
  72 *                      irq unmasking disabled for reliability.
  73 *                      try to be even smarter about the second port.
  74 *                      tidy up source code formatting.
  75 *  Version 0.13        permit irq unmasking again.
  76 *  Version 0.90        massive code cleanup, some bugs fixed.
  77 *                      defaults all drives to PIO mode0, prefetch off.
  78 *                      autotune is OFF by default, with compile time flag.
  79 *                      prefetch can be turned OFF/ON using "hdparm -p8/-p9"
  80 *                       (requires hdparm-3.1 or newer)
  81 *  Version 0.91        first release to linux-kernel list.
  82 *  Version 0.92        move initial reg dump to separate callable function
  83 *                      change "readahead" to "prefetch" to avoid confusion
  84 *  Version 0.95        respect original BIOS timings unless autotuning.
  85 *                      tons of code cleanup and rearrangement.
  86 *                      added CONFIG_BLK_DEV_CMD640_ENHANCED option
  87 *                      prevent use of unmask when prefetch is on
  88 *  Version 0.96        prevent use of io_32bit when prefetch is off
  89 *  Version 0.97        fix VLB secondary interface for sjd@slip.net
  90 *                      other minor tune-ups:  0.96 was very good.
  91 *  Version 0.98        ignore PCI version when disabled by BIOS
  92 *  Version 0.99        display setup/active/recovery clocks with PIO mode
  93 *  Version 1.00        Mmm.. cannot depend on PCMD_ENA in all systems
  94 *  Version 1.01        slow/fast devsel can be selected with "hdparm -p6/-p7"
  95 *                       ("fast" is necessary for 32bit I/O in some systems)
  96 *  Version 1.02        fix bug that resulted in slow "setup times"
  97 *                       (patch courtesy of Zoltan Hidvegi)
  98 */
  99
 100#define CMD640_PREFETCH_MASKS 1
 101
 102/*#define CMD640_DUMP_REGS */
 103
 104#include <linux/types.h>
 105#include <linux/kernel.h>
 106#include <linux/delay.h>
 107#include <linux/ide.h>
 108#include <linux/init.h>
 109#include <linux/module.h>
 110
 111#include <asm/io.h>
 112
 113#define DRV_NAME "cmd640"
 114
 115static bool cmd640_vlb;
 116
 117/*
 118 * CMD640 specific registers definition.
 119 */
 120
 121#define VID             0x00
 122#define DID             0x02
 123#define PCMD            0x04
 124#define   PCMD_ENA      0x01
 125#define PSTTS           0x06
 126#define REVID           0x08
 127#define PROGIF          0x09
 128#define SUBCL           0x0a
 129#define BASCL           0x0b
 130#define BaseA0          0x10
 131#define BaseA1          0x14
 132#define BaseA2          0x18
 133#define BaseA3          0x1c
 134#define INTLINE         0x3c
 135#define INPINE          0x3d
 136
 137#define CFR             0x50
 138#define   CFR_DEVREV            0x03
 139#define   CFR_IDE01INTR         0x04
 140#define   CFR_DEVID             0x18
 141#define   CFR_AT_VESA_078h      0x20
 142#define   CFR_DSA1              0x40
 143#define   CFR_DSA0              0x80
 144
 145#define CNTRL           0x51
 146#define   CNTRL_DIS_RA0         0x40
 147#define   CNTRL_DIS_RA1         0x80
 148#define   CNTRL_ENA_2ND         0x08
 149
 150#define CMDTIM          0x52
 151#define ARTTIM0         0x53
 152#define DRWTIM0         0x54
 153#define ARTTIM1         0x55
 154#define DRWTIM1         0x56
 155#define ARTTIM23        0x57
 156#define   ARTTIM23_DIS_RA2      0x04
 157#define   ARTTIM23_DIS_RA3      0x08
 158#define   ARTTIM23_IDE23INTR    0x10
 159#define DRWTIM23        0x58
 160#define BRST            0x59
 161
 162/*
 163 * Registers and masks for easy access by drive index:
 164 */
 165static u8 prefetch_regs[4]  = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};
 166static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};
 167
 168#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 169
 170static u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
 171static u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM23, DRWTIM23};
 172
 173/*
 174 * Current cmd640 timing values for each drive.
 175 * The defaults for each are the slowest possible timings.
 176 */
 177static u8 setup_counts[4]    = {4, 4, 4, 4};     /* Address setup count (in clocks) */
 178static u8 active_counts[4]   = {16, 16, 16, 16}; /* Active count   (encoded) */
 179static u8 recovery_counts[4] = {16, 16, 16, 16}; /* Recovery count (encoded) */
 180
 181#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 182
 183static DEFINE_SPINLOCK(cmd640_lock);
 184
 185/*
 186 * Interface to access cmd640x registers
 187 */
 188static unsigned int cmd640_key;
 189static void (*__put_cmd640_reg)(u16 reg, u8 val);
 190static u8 (*__get_cmd640_reg)(u16 reg);
 191
 192/*
 193 * This is read from the CFR reg, and is used in several places.
 194 */
 195static unsigned int cmd640_chip_version;
 196
 197/*
 198 * The CMD640x chip does not support DWORD config write cycles, but some
 199 * of the BIOSes use them to implement the config services.
 200 * Therefore, we must use direct IO instead.
 201 */
 202
 203/* PCI method 1 access */
 204
 205static void put_cmd640_reg_pci1(u16 reg, u8 val)
 206{
 207        outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
 208        outb_p(val, (reg & 3) | 0xcfc);
 209}
 210
 211static u8 get_cmd640_reg_pci1(u16 reg)
 212{
 213        outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
 214        return inb_p((reg & 3) | 0xcfc);
 215}
 216
 217/* PCI method 2 access (from CMD datasheet) */
 218
 219static void put_cmd640_reg_pci2(u16 reg, u8 val)
 220{
 221        outb_p(0x10, 0xcf8);
 222        outb_p(val, cmd640_key + reg);
 223        outb_p(0, 0xcf8);
 224}
 225
 226static u8 get_cmd640_reg_pci2(u16 reg)
 227{
 228        u8 b;
 229
 230        outb_p(0x10, 0xcf8);
 231        b = inb_p(cmd640_key + reg);
 232        outb_p(0, 0xcf8);
 233        return b;
 234}
 235
 236/* VLB access */
 237
 238static void put_cmd640_reg_vlb(u16 reg, u8 val)
 239{
 240        outb_p(reg, cmd640_key);
 241        outb_p(val, cmd640_key + 4);
 242}
 243
 244static u8 get_cmd640_reg_vlb(u16 reg)
 245{
 246        outb_p(reg, cmd640_key);
 247        return inb_p(cmd640_key + 4);
 248}
 249
 250static u8 get_cmd640_reg(u16 reg)
 251{
 252        unsigned long flags;
 253        u8 b;
 254
 255        spin_lock_irqsave(&cmd640_lock, flags);
 256        b = __get_cmd640_reg(reg);
 257        spin_unlock_irqrestore(&cmd640_lock, flags);
 258        return b;
 259}
 260
 261static void put_cmd640_reg(u16 reg, u8 val)
 262{
 263        unsigned long flags;
 264
 265        spin_lock_irqsave(&cmd640_lock, flags);
 266        __put_cmd640_reg(reg, val);
 267        spin_unlock_irqrestore(&cmd640_lock, flags);
 268}
 269
 270static int __init match_pci_cmd640_device(void)
 271{
 272        const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
 273        unsigned int i;
 274        for (i = 0; i < 4; i++) {
 275                if (get_cmd640_reg(i) != ven_dev[i])
 276                        return 0;
 277        }
 278#ifdef STUPIDLY_TRUST_BROKEN_PCMD_ENA_BIT
 279        if ((get_cmd640_reg(PCMD) & PCMD_ENA) == 0) {
 280                printk("ide: cmd640 on PCI disabled by BIOS\n");
 281                return 0;
 282        }
 283#endif /* STUPIDLY_TRUST_BROKEN_PCMD_ENA_BIT */
 284        return 1; /* success */
 285}
 286
 287/*
 288 * Probe for CMD640x -- pci method 1
 289 */
 290static int __init probe_for_cmd640_pci1(void)
 291{
 292        __get_cmd640_reg = get_cmd640_reg_pci1;
 293        __put_cmd640_reg = put_cmd640_reg_pci1;
 294        for (cmd640_key = 0x80000000;
 295             cmd640_key <= 0x8000f800;
 296             cmd640_key += 0x800) {
 297                if (match_pci_cmd640_device())
 298                        return 1; /* success */
 299        }
 300        return 0;
 301}
 302
 303/*
 304 * Probe for CMD640x -- pci method 2
 305 */
 306static int __init probe_for_cmd640_pci2(void)
 307{
 308        __get_cmd640_reg = get_cmd640_reg_pci2;
 309        __put_cmd640_reg = put_cmd640_reg_pci2;
 310        for (cmd640_key = 0xc000; cmd640_key <= 0xcf00; cmd640_key += 0x100) {
 311                if (match_pci_cmd640_device())
 312                        return 1; /* success */
 313        }
 314        return 0;
 315}
 316
 317/*
 318 * Probe for CMD640x -- vlb
 319 */
 320static int __init probe_for_cmd640_vlb(void)
 321{
 322        u8 b;
 323
 324        __get_cmd640_reg = get_cmd640_reg_vlb;
 325        __put_cmd640_reg = put_cmd640_reg_vlb;
 326        cmd640_key = 0x178;
 327        b = get_cmd640_reg(CFR);
 328        if (b == 0xff || b == 0x00 || (b & CFR_AT_VESA_078h)) {
 329                cmd640_key = 0x78;
 330                b = get_cmd640_reg(CFR);
 331                if (b == 0xff || b == 0x00 || !(b & CFR_AT_VESA_078h))
 332                        return 0;
 333        }
 334        return 1; /* success */
 335}
 336
 337/*
 338 *  Returns 1 if an IDE interface/drive exists at 0x170,
 339 *  Returns 0 otherwise.
 340 */
 341static int __init secondary_port_responding(void)
 342{
 343        unsigned long flags;
 344
 345        spin_lock_irqsave(&cmd640_lock, flags);
 346
 347        outb_p(0x0a, 0x176);    /* select drive0 */
 348        udelay(100);
 349        if ((inb_p(0x176) & 0x1f) != 0x0a) {
 350                outb_p(0x1a, 0x176); /* select drive1 */
 351                udelay(100);
 352                if ((inb_p(0x176) & 0x1f) != 0x1a) {
 353                        spin_unlock_irqrestore(&cmd640_lock, flags);
 354                        return 0; /* nothing responded */
 355                }
 356        }
 357        spin_unlock_irqrestore(&cmd640_lock, flags);
 358        return 1; /* success */
 359}
 360
 361#ifdef CMD640_DUMP_REGS
 362/*
 363 * Dump out all cmd640 registers.  May be called from ide.c
 364 */
 365static void cmd640_dump_regs(void)
 366{
 367        unsigned int reg = cmd640_vlb ? 0x50 : 0x00;
 368
 369        /* Dump current state of chip registers */
 370        printk("ide: cmd640 internal register dump:");
 371        for (; reg <= 0x59; reg++) {
 372                if (!(reg & 0x0f))
 373                        printk("\n%04x:", reg);
 374                printk(" %02x", get_cmd640_reg(reg));
 375        }
 376        printk("\n");
 377}
 378#endif
 379
 380static void __set_prefetch_mode(ide_drive_t *drive, int mode)
 381{
 382        if (mode) {     /* want prefetch on? */
 383#if CMD640_PREFETCH_MASKS
 384                drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
 385                drive->dev_flags &= ~IDE_DFLAG_UNMASK;
 386#endif
 387                drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
 388        } else {
 389                drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK;
 390                drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
 391                drive->io_32bit = 0;
 392        }
 393}
 394
 395#ifndef CONFIG_BLK_DEV_CMD640_ENHANCED
 396/*
 397 * Check whether prefetch is on for a drive,
 398 * and initialize the unmask flags for safe operation.
 399 */
 400static void __init check_prefetch(ide_drive_t *drive, unsigned int index)
 401{
 402        u8 b = get_cmd640_reg(prefetch_regs[index]);
 403
 404        __set_prefetch_mode(drive, (b & prefetch_masks[index]) ? 0 : 1);
 405}
 406#else
 407
 408/*
 409 * Sets prefetch mode for a drive.
 410 */
 411static void set_prefetch_mode(ide_drive_t *drive, unsigned int index, int mode)
 412{
 413        unsigned long flags;
 414        int reg = prefetch_regs[index];
 415        u8 b;
 416
 417        spin_lock_irqsave(&cmd640_lock, flags);
 418        b = __get_cmd640_reg(reg);
 419        __set_prefetch_mode(drive, mode);
 420        if (mode)
 421                b &= ~prefetch_masks[index];    /* enable prefetch */
 422        else
 423                b |= prefetch_masks[index];     /* disable prefetch */
 424        __put_cmd640_reg(reg, b);
 425        spin_unlock_irqrestore(&cmd640_lock, flags);
 426}
 427
 428/*
 429 * Dump out current drive clocks settings
 430 */
 431static void display_clocks(unsigned int index)
 432{
 433        u8 active_count, recovery_count;
 434
 435        active_count = active_counts[index];
 436        if (active_count == 1)
 437                ++active_count;
 438        recovery_count = recovery_counts[index];
 439        if (active_count > 3 && recovery_count == 1)
 440                ++recovery_count;
 441        if (cmd640_chip_version > 1)
 442                recovery_count += 1;  /* cmd640b uses (count + 1)*/
 443        printk(", clocks=%d/%d/%d\n", setup_counts[index], active_count, recovery_count);
 444}
 445
 446/*
 447 * Pack active and recovery counts into single byte representation
 448 * used by controller
 449 */
 450static inline u8 pack_nibbles(u8 upper, u8 lower)
 451{
 452        return ((upper & 0x0f) << 4) | (lower & 0x0f);
 453}
 454
 455/*
 456 * This routine writes the prepared setup/active/recovery counts
 457 * for a drive into the cmd640 chipset registers to active them.
 458 */
 459static void program_drive_counts(ide_drive_t *drive, unsigned int index)
 460{
 461        unsigned long flags;
 462        u8 setup_count    = setup_counts[index];
 463        u8 active_count   = active_counts[index];
 464        u8 recovery_count = recovery_counts[index];
 465
 466        /*
 467         * Set up address setup count and drive read/write timing registers.
 468         * Primary interface has individual count/timing registers for
 469         * each drive.  Secondary interface has one common set of registers,
 470         * so we merge the timings, using the slowest value for each timing.
 471         */
 472        if (index > 1) {
 473                ide_drive_t *peer = ide_get_pair_dev(drive);
 474                unsigned int mate = index ^ 1;
 475
 476                if (peer) {
 477                        if (setup_count < setup_counts[mate])
 478                                setup_count = setup_counts[mate];
 479                        if (active_count < active_counts[mate])
 480                                active_count = active_counts[mate];
 481                        if (recovery_count < recovery_counts[mate])
 482                                recovery_count = recovery_counts[mate];
 483                }
 484        }
 485
 486        /*
 487         * Convert setup_count to internal chipset representation
 488         */
 489        switch (setup_count) {
 490        case 4:  setup_count = 0x00; break;
 491        case 3:  setup_count = 0x80; break;
 492        case 1:
 493        case 2:  setup_count = 0x40; break;
 494        default: setup_count = 0xc0; /* case 5 */
 495        }
 496
 497        /*
 498         * Now that everything is ready, program the new timings
 499         */
 500        spin_lock_irqsave(&cmd640_lock, flags);
 501        /*
 502         * Program the address_setup clocks into ARTTIM reg,
 503         * and then the active/recovery counts into the DRWTIM reg
 504         * (this converts counts of 16 into counts of zero -- okay).
 505         */
 506        setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
 507        __put_cmd640_reg(arttim_regs[index], setup_count);
 508        __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
 509        spin_unlock_irqrestore(&cmd640_lock, flags);
 510}
 511
 512/*
 513 * Set a specific pio_mode for a drive
 514 */
 515static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
 516                            u8 pio_mode, unsigned int cycle_time)
 517{
 518        struct ide_timing *t;
 519        int setup_time, active_time, recovery_time, clock_time;
 520        u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
 521        int bus_speed;
 522
 523        if (cmd640_vlb)
 524                bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
 525        else
 526                bus_speed = ide_pci_clk ? ide_pci_clk : 33;
 527
 528        if (pio_mode > 5)
 529                pio_mode = 5;
 530
 531        t = ide_timing_find_mode(XFER_PIO_0 + pio_mode);
 532        setup_time  = t->setup;
 533        active_time = t->active;
 534
 535        recovery_time = cycle_time - (setup_time + active_time);
 536        clock_time = 1000 / bus_speed;
 537        cycle_count = DIV_ROUND_UP(cycle_time, clock_time);
 538
 539        setup_count = DIV_ROUND_UP(setup_time, clock_time);
 540
 541        active_count = DIV_ROUND_UP(active_time, clock_time);
 542        if (active_count < 2)
 543                active_count = 2; /* minimum allowed by cmd640 */
 544
 545        recovery_count = DIV_ROUND_UP(recovery_time, clock_time);
 546        recovery_count2 = cycle_count - (setup_count + active_count);
 547        if (recovery_count2 > recovery_count)
 548                recovery_count = recovery_count2;
 549        if (recovery_count < 2)
 550                recovery_count = 2; /* minimum allowed by cmd640 */
 551        if (recovery_count > 17) {
 552                active_count += recovery_count - 17;
 553                recovery_count = 17;
 554        }
 555        if (active_count > 16)
 556                active_count = 16; /* maximum allowed by cmd640 */
 557        if (cmd640_chip_version > 1)
 558                recovery_count -= 1;  /* cmd640b uses (count + 1)*/
 559        if (recovery_count > 16)
 560                recovery_count = 16; /* maximum allowed by cmd640 */
 561
 562        setup_counts[index]    = setup_count;
 563        active_counts[index]   = active_count;
 564        recovery_counts[index] = recovery_count;
 565
 566        /*
 567         * In a perfect world, we might set the drive pio mode here
 568         * (using WIN_SETFEATURE) before continuing.
 569         *
 570         * But we do not, because:
 571         *      1) this is the wrong place to do it (proper is do_special() in ide.c)
 572         *      2) in practice this is rarely, if ever, necessary
 573         */
 574        program_drive_counts(drive, index);
 575}
 576
 577static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 578{
 579        unsigned int index = 0, cycle_time;
 580        const u8 pio = drive->pio_mode - XFER_PIO_0;
 581        u8 b;
 582
 583        switch (pio) {
 584        case 6: /* set fast-devsel off */
 585        case 7: /* set fast-devsel on */
 586                b = get_cmd640_reg(CNTRL) & ~0x27;
 587                if (pio & 1)
 588                        b |= 0x27;
 589                put_cmd640_reg(CNTRL, b);
 590                printk("%s: %sabled cmd640 fast host timing (devsel)\n",
 591                        drive->name, (pio & 1) ? "en" : "dis");
 592                return;
 593        case 8: /* set prefetch off */
 594        case 9: /* set prefetch on */
 595                set_prefetch_mode(drive, index, pio & 1);
 596                printk("%s: %sabled cmd640 prefetch\n",
 597                        drive->name, (pio & 1) ? "en" : "dis");
 598                return;
 599        }
 600
 601        cycle_time = ide_pio_cycle_time(drive, pio);
 602        cmd640_set_mode(drive, index, pio, cycle_time);
 603
 604        printk("%s: selected cmd640 PIO mode%d (%dns)",
 605                drive->name, pio, cycle_time);
 606
 607        display_clocks(index);
 608}
 609#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 610
 611static void __init cmd640_init_dev(ide_drive_t *drive)
 612{
 613        unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);
 614
 615#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 616        /*
 617         * Reset timing to the slowest speed and turn off prefetch.
 618         * This way, the drive identify code has a better chance.
 619         */
 620        setup_counts[i]    =  4;        /* max possible */
 621        active_counts[i]   = 16;        /* max possible */
 622        recovery_counts[i] = 16;        /* max possible */
 623        program_drive_counts(drive, i);
 624        set_prefetch_mode(drive, i, 0);
 625        printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i);
 626#else
 627        /*
 628         * Set the drive unmask flags to match the prefetch setting.
 629         */
 630        check_prefetch(drive, i);
 631        printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n",
 632                i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on");
 633#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 634}
 635
 636static int cmd640_test_irq(ide_hwif_t *hwif)
 637{
 638        int irq_reg             = hwif->channel ? ARTTIM23 : CFR;
 639        u8  irq_mask            = hwif->channel ? ARTTIM23_IDE23INTR :
 640                                                  CFR_IDE01INTR;
 641        u8  irq_stat            = get_cmd640_reg(irq_reg);
 642
 643        return (irq_stat & irq_mask) ? 1 : 0;
 644}
 645
 646static const struct ide_port_ops cmd640_port_ops = {
 647        .init_dev               = cmd640_init_dev,
 648#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 649        .set_pio_mode           = cmd640_set_pio_mode,
 650#endif
 651        .test_irq               = cmd640_test_irq,
 652};
 653
 654static int pci_conf1(void)
 655{
 656        unsigned long flags;
 657        u32 tmp;
 658
 659        spin_lock_irqsave(&cmd640_lock, flags);
 660        outb(0x01, 0xCFB);
 661        tmp = inl(0xCF8);
 662        outl(0x80000000, 0xCF8);
 663        if (inl(0xCF8) == 0x80000000) {
 664                outl(tmp, 0xCF8);
 665                spin_unlock_irqrestore(&cmd640_lock, flags);
 666                return 1;
 667        }
 668        outl(tmp, 0xCF8);
 669        spin_unlock_irqrestore(&cmd640_lock, flags);
 670        return 0;
 671}
 672
 673static int pci_conf2(void)
 674{
 675        unsigned long flags;
 676
 677        spin_lock_irqsave(&cmd640_lock, flags);
 678        outb(0x00, 0xCFB);
 679        outb(0x00, 0xCF8);
 680        outb(0x00, 0xCFA);
 681        if (inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00) {
 682                spin_unlock_irqrestore(&cmd640_lock, flags);
 683                return 1;
 684        }
 685        spin_unlock_irqrestore(&cmd640_lock, flags);
 686        return 0;
 687}
 688
 689static const struct ide_port_info cmd640_port_info __initconst = {
 690        .chipset                = ide_cmd640,
 691        .host_flags             = IDE_HFLAG_SERIALIZE |
 692                                  IDE_HFLAG_NO_DMA |
 693                                  IDE_HFLAG_ABUSE_PREFETCH |
 694                                  IDE_HFLAG_ABUSE_FAST_DEVSEL,
 695        .port_ops               = &cmd640_port_ops,
 696        .pio_mask               = ATA_PIO5,
 697};
 698
 699static int __init cmd640x_init_one(unsigned long base, unsigned long ctl)
 700{
 701        if (!request_region(base, 8, DRV_NAME)) {
 702                printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
 703                                DRV_NAME, base, base + 7);
 704                return -EBUSY;
 705        }
 706
 707        if (!request_region(ctl, 1, DRV_NAME)) {
 708                printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
 709                                DRV_NAME, ctl);
 710                release_region(base, 8);
 711                return -EBUSY;
 712        }
 713
 714        return 0;
 715}
 716
 717/*
 718 * Probe for a cmd640 chipset, and initialize it if found.
 719 */
 720static int __init cmd640x_init(void)
 721{
 722        int second_port_cmd640 = 0, rc;
 723        const char *bus_type, *port2;
 724        u8 b, cfr;
 725        struct ide_hw hw[2], *hws[2];
 726
 727        if (cmd640_vlb && probe_for_cmd640_vlb()) {
 728                bus_type = "VLB";
 729        } else {
 730                cmd640_vlb = 0;
 731                /* Find out what kind of PCI probing is supported otherwise
 732                   Justin Gibbs will sulk.. */
 733                if (pci_conf1() && probe_for_cmd640_pci1())
 734                        bus_type = "PCI (type1)";
 735                else if (pci_conf2() && probe_for_cmd640_pci2())
 736                        bus_type = "PCI (type2)";
 737                else
 738                        return 0;
 739        }
 740        /*
 741         * Undocumented magic (there is no 0x5b reg in specs)
 742         */
 743        put_cmd640_reg(0x5b, 0xbd);
 744        if (get_cmd640_reg(0x5b) != 0xbd) {
 745                printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n");
 746                return 0;
 747        }
 748        put_cmd640_reg(0x5b, 0);
 749
 750#ifdef CMD640_DUMP_REGS
 751        cmd640_dump_regs();
 752#endif
 753
 754        /*
 755         * Documented magic begins here
 756         */
 757        cfr = get_cmd640_reg(CFR);
 758        cmd640_chip_version = cfr & CFR_DEVREV;
 759        if (cmd640_chip_version == 0) {
 760                printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version);
 761                return 0;
 762        }
 763
 764        rc = cmd640x_init_one(0x1f0, 0x3f6);
 765        if (rc)
 766                return rc;
 767
 768        rc = cmd640x_init_one(0x170, 0x376);
 769        if (rc) {
 770                release_region(0x3f6, 1);
 771                release_region(0x1f0, 8);
 772                return rc;
 773        }
 774
 775        memset(&hw, 0, sizeof(hw));
 776
 777        ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
 778        hw[0].irq = 14;
 779
 780        ide_std_init_ports(&hw[1], 0x170, 0x376);
 781        hw[1].irq = 15;
 782
 783        printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
 784                         "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr);
 785
 786        /*
 787         * Initialize data for primary port
 788         */
 789        hws[0] = &hw[0];
 790
 791        /*
 792         * Ensure compatibility by always using the slowest timings
 793         * for access to the drive's command register block,
 794         * and reset the prefetch burstsize to default (512 bytes).
 795         *
 796         * Maybe we need a way to NOT do these on *some* systems?
 797         */
 798        put_cmd640_reg(CMDTIM, 0);
 799        put_cmd640_reg(BRST, 0x40);
 800
 801        b = get_cmd640_reg(CNTRL);
 802
 803        /*
 804         * Try to enable the secondary interface, if not already enabled
 805         */
 806        if (secondary_port_responding()) {
 807                if ((b & CNTRL_ENA_2ND)) {
 808                        second_port_cmd640 = 1;
 809                        port2 = "okay";
 810                } else if (cmd640_vlb) {
 811                        second_port_cmd640 = 1;
 812                        port2 = "alive";
 813                } else
 814                        port2 = "not cmd640";
 815        } else {
 816                put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */
 817                if (secondary_port_responding()) {
 818                        second_port_cmd640 = 1;
 819                        port2 = "enabled";
 820                } else {
 821                        put_cmd640_reg(CNTRL, b); /* restore original setting */
 822                        port2 = "not responding";
 823                }
 824        }
 825
 826        /*
 827         * Initialize data for secondary cmd640 port, if enabled
 828         */
 829        if (second_port_cmd640)
 830                hws[1] = &hw[1];
 831
 832        printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
 833                         second_port_cmd640 ? "" : "not ", port2);
 834
 835#ifdef CMD640_DUMP_REGS
 836        cmd640_dump_regs();
 837#endif
 838
 839        return ide_host_add(&cmd640_port_info, hws, second_port_cmd640 ? 2 : 1,
 840                            NULL);
 841}
 842
 843module_param_named(probe_vlb, cmd640_vlb, bool, 0);
 844MODULE_PARM_DESC(probe_vlb, "probe for VLB version of CMD640 chipset");
 845
 846module_init(cmd640x_init);
 847
 848MODULE_LICENSE("GPL");
 849