linux/drivers/ide/ide-lib.c
<<
>>
Prefs
   1#include <linux/module.h>
   2#include <linux/types.h>
   3#include <linux/string.h>
   4#include <linux/kernel.h>
   5#include <linux/timer.h>
   6#include <linux/mm.h>
   7#include <linux/interrupt.h>
   8#include <linux/major.h>
   9#include <linux/errno.h>
  10#include <linux/genhd.h>
  11#include <linux/blkpg.h>
  12#include <linux/slab.h>
  13#include <linux/pci.h>
  14#include <linux/delay.h>
  15#include <linux/hdreg.h>
  16#include <linux/ide.h>
  17#include <linux/bitops.h>
  18
  19#include <asm/byteorder.h>
  20#include <asm/irq.h>
  21#include <asm/uaccess.h>
  22#include <asm/io.h>
  23
  24/*
  25 *      IDE library routines. These are plug in code that most 
  26 *      drivers can use but occasionally may be weird enough
  27 *      to want to do their own thing with
  28 *
  29 *      Add common non I/O op stuff here. Make sure it has proper
  30 *      kernel-doc function headers or your patch will be rejected
  31 */
  32
  33static const char *udma_str[] =
  34         { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
  35           "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
  36static const char *mwdma_str[] =
  37        { "MWDMA0", "MWDMA1", "MWDMA2" };
  38static const char *swdma_str[] =
  39        { "SWDMA0", "SWDMA1", "SWDMA2" };
  40static const char *pio_str[] =
  41        { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
  42
  43/**
  44 *      ide_xfer_verbose        -       return IDE mode names
  45 *      @mode: transfer mode
  46 *
  47 *      Returns a constant string giving the name of the mode
  48 *      requested.
  49 */
  50
  51const char *ide_xfer_verbose(u8 mode)
  52{
  53        const char *s;
  54        u8 i = mode & 0xf;
  55
  56        if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
  57                s = udma_str[i];
  58        else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
  59                s = mwdma_str[i];
  60        else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
  61                s = swdma_str[i];
  62        else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
  63                s = pio_str[i & 0x7];
  64        else if (mode == XFER_PIO_SLOW)
  65                s = "PIO SLOW";
  66        else
  67                s = "XFER ERROR";
  68
  69        return s;
  70}
  71
  72EXPORT_SYMBOL(ide_xfer_verbose);
  73
  74/**
  75 *      ide_rate_filter         -       filter transfer mode
  76 *      @drive: IDE device
  77 *      @speed: desired speed
  78 *
  79 *      Given the available transfer modes this function returns
  80 *      the best available speed at or below the speed requested.
  81 *
  82 *      TODO: check device PIO capabilities
  83 */
  84
  85static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
  86{
  87        ide_hwif_t *hwif = drive->hwif;
  88        u8 mode = ide_find_dma_mode(drive, speed);
  89
  90        if (mode == 0) {
  91                if (hwif->pio_mask)
  92                        mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
  93                else
  94                        mode = XFER_PIO_4;
  95        }
  96
  97//      printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
  98
  99        return min(speed, mode);
 100}
 101
 102/*
 103 * Standard (generic) timings for PIO modes, from ATA2 specification.
 104 * These timings are for access to the IDE data port register *only*.
 105 * Some drives may specify a mode, while also specifying a different
 106 * value for cycle_time (from drive identification data).
 107 */
 108const ide_pio_timings_t ide_pio_timings[6] = {
 109        { 70,   165,    600 },  /* PIO Mode 0 */
 110        { 50,   125,    383 },  /* PIO Mode 1 */
 111        { 30,   100,    240 },  /* PIO Mode 2 */
 112        { 30,   80,     180 },  /* PIO Mode 3 with IORDY */
 113        { 25,   70,     120 },  /* PIO Mode 4 with IORDY */
 114        { 20,   50,     100 }   /* PIO Mode 5 with IORDY (nonstandard) */
 115};
 116
 117EXPORT_SYMBOL_GPL(ide_pio_timings);
 118
 119/*
 120 * Shared data/functions for determining best PIO mode for an IDE drive.
 121 * Most of this stuff originally lived in cmd640.c, and changes to the
 122 * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid
 123 * breaking the fragile cmd640.c support.
 124 */
 125
 126/*
 127 * Black list. Some drives incorrectly report their maximal PIO mode,
 128 * at least in respect to CMD640. Here we keep info on some known drives.
 129 */
 130static struct ide_pio_info {
 131        const char      *name;
 132        int             pio;
 133} ide_pio_blacklist [] = {
 134/*      { "Conner Peripherals 1275MB - CFS1275A", 4 }, */
 135        { "Conner Peripherals 540MB - CFS540A", 3 },
 136
 137        { "WDC AC2700",  3 },
 138        { "WDC AC2540",  3 },
 139        { "WDC AC2420",  3 },
 140        { "WDC AC2340",  3 },
 141        { "WDC AC2250",  0 },
 142        { "WDC AC2200",  0 },
 143        { "WDC AC21200", 4 },
 144        { "WDC AC2120",  0 },
 145        { "WDC AC2850",  3 },
 146        { "WDC AC1270",  3 },
 147        { "WDC AC1170",  1 },
 148        { "WDC AC1210",  1 },
 149        { "WDC AC280",   0 },
 150/*      { "WDC AC21000", 4 }, */
 151        { "WDC AC31000", 3 },
 152        { "WDC AC31200", 3 },
 153/*      { "WDC AC31600", 4 }, */
 154
 155        { "Maxtor 7131 AT", 1 },
 156        { "Maxtor 7171 AT", 1 },
 157        { "Maxtor 7213 AT", 1 },
 158        { "Maxtor 7245 AT", 1 },
 159        { "Maxtor 7345 AT", 1 },
 160        { "Maxtor 7546 AT", 3 },
 161        { "Maxtor 7540 AV", 3 },
 162
 163        { "SAMSUNG SHD-3121A", 1 },
 164        { "SAMSUNG SHD-3122A", 1 },
 165        { "SAMSUNG SHD-3172A", 1 },
 166
 167/*      { "ST51080A", 4 },
 168 *      { "ST51270A", 4 },
 169 *      { "ST31220A", 4 },
 170 *      { "ST31640A", 4 },
 171 *      { "ST32140A", 4 },
 172 *      { "ST3780A",  4 },
 173 */
 174        { "ST5660A",  3 },
 175        { "ST3660A",  3 },
 176        { "ST3630A",  3 },
 177        { "ST3655A",  3 },
 178        { "ST3391A",  3 },
 179        { "ST3390A",  1 },
 180        { "ST3600A",  1 },
 181        { "ST3290A",  0 },
 182        { "ST3144A",  0 },
 183        { "ST3491A",  1 },      /* reports 3, should be 1 or 2 (depending on */ 
 184                                /* drive) according to Seagates FIND-ATA program */
 185
 186        { "QUANTUM ELS127A", 0 },
 187        { "QUANTUM ELS170A", 0 },
 188        { "QUANTUM LPS240A", 0 },
 189        { "QUANTUM LPS210A", 3 },
 190        { "QUANTUM LPS270A", 3 },
 191        { "QUANTUM LPS365A", 3 },
 192        { "QUANTUM LPS540A", 3 },
 193        { "QUANTUM LIGHTNING 540A", 3 },
 194        { "QUANTUM LIGHTNING 730A", 3 },
 195
 196        { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
 197        { "QUANTUM FIREBALL_640", 3 }, 
 198        { "QUANTUM FIREBALL_1080", 3 },
 199        { "QUANTUM FIREBALL_1280", 3 },
 200        { NULL, 0 }
 201};
 202
 203/**
 204 *      ide_scan_pio_blacklist  -       check for a blacklisted drive
 205 *      @model: Drive model string
 206 *
 207 *      This routine searches the ide_pio_blacklist for an entry
 208 *      matching the start/whole of the supplied model name.
 209 *
 210 *      Returns -1 if no match found.
 211 *      Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
 212 */
 213
 214static int ide_scan_pio_blacklist (char *model)
 215{
 216        struct ide_pio_info *p;
 217
 218        for (p = ide_pio_blacklist; p->name != NULL; p++) {
 219                if (strncmp(p->name, model, strlen(p->name)) == 0)
 220                        return p->pio;
 221        }
 222        return -1;
 223}
 224
 225unsigned int ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
 226{
 227        struct hd_driveid *id = drive->id;
 228        int cycle_time = 0;
 229
 230        if (id->field_valid & 2) {
 231                if (id->capability & 8)
 232                        cycle_time = id->eide_pio_iordy;
 233                else
 234                        cycle_time = id->eide_pio;
 235        }
 236
 237        /* conservative "downgrade" for all pre-ATA2 drives */
 238        if (pio < 3) {
 239                if (cycle_time && cycle_time < ide_pio_timings[pio].cycle_time)
 240                        cycle_time = 0; /* use standard timing */
 241        }
 242
 243        return cycle_time ? cycle_time : ide_pio_timings[pio].cycle_time;
 244}
 245
 246EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
 247
 248/**
 249 *      ide_get_best_pio_mode   -       get PIO mode from drive
 250 *      @drive: drive to consider
 251 *      @mode_wanted: preferred mode
 252 *      @max_mode: highest allowed mode
 253 *
 254 *      This routine returns the recommended PIO settings for a given drive,
 255 *      based on the drive->id information and the ide_pio_blacklist[].
 256 *
 257 *      Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
 258 *      This is used by most chipset support modules when "auto-tuning".
 259 */
 260
 261u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
 262{
 263        int pio_mode;
 264        struct hd_driveid* id = drive->id;
 265        int overridden  = 0;
 266
 267        if (mode_wanted != 255)
 268                return min_t(u8, mode_wanted, max_mode);
 269
 270        if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0 &&
 271            (pio_mode = ide_scan_pio_blacklist(id->model)) != -1) {
 272                printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
 273        } else {
 274                pio_mode = id->tPIO;
 275                if (pio_mode > 2) {     /* 2 is maximum allowed tPIO value */
 276                        pio_mode = 2;
 277                        overridden = 1;
 278                }
 279                if (id->field_valid & 2) {        /* drive implements ATA2? */
 280                        if (id->capability & 8) { /* IORDY supported? */
 281                                if (id->eide_pio_modes & 7) {
 282                                        overridden = 0;
 283                                        if (id->eide_pio_modes & 4)
 284                                                pio_mode = 5;
 285                                        else if (id->eide_pio_modes & 2)
 286                                                pio_mode = 4;
 287                                        else
 288                                                pio_mode = 3;
 289                                }
 290                        }
 291                }
 292
 293                if (overridden)
 294                        printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
 295                                         drive->name);
 296
 297                /*
 298                 * Conservative "downgrade" for all pre-ATA2 drives
 299                 */
 300                if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 &&
 301                    pio_mode && pio_mode < 4) {
 302                        pio_mode--;
 303                        printk(KERN_INFO "%s: applying conservative "
 304                                         "PIO \"downgrade\"\n", drive->name);
 305                }
 306        }
 307
 308        if (pio_mode > max_mode)
 309                pio_mode = max_mode;
 310
 311        return pio_mode;
 312}
 313
 314EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
 315
 316/* req_pio == "255" for auto-tune */
 317void ide_set_pio(ide_drive_t *drive, u8 req_pio)
 318{
 319        ide_hwif_t *hwif = drive->hwif;
 320        u8 host_pio, pio;
 321
 322        if (hwif->set_pio_mode == NULL)
 323                return;
 324
 325        BUG_ON(hwif->pio_mask == 0x00);
 326
 327        host_pio = fls(hwif->pio_mask) - 1;
 328
 329        pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
 330
 331        /*
 332         * TODO:
 333         * - report device max PIO mode
 334         * - check req_pio != 255 against device max PIO mode
 335         */
 336        printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
 337                          drive->name, host_pio, req_pio,
 338                          req_pio == 255 ? "(auto-tune)" : "", pio);
 339
 340        (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
 341}
 342
 343EXPORT_SYMBOL_GPL(ide_set_pio);
 344
 345/**
 346 *      ide_toggle_bounce       -       handle bounce buffering
 347 *      @drive: drive to update
 348 *      @on: on/off boolean
 349 *
 350 *      Enable or disable bounce buffering for the device. Drives move
 351 *      between PIO and DMA and that changes the rules we need.
 352 */
 353 
 354void ide_toggle_bounce(ide_drive_t *drive, int on)
 355{
 356        u64 addr = BLK_BOUNCE_HIGH;     /* dma64_addr_t */
 357
 358        if (!PCI_DMA_BUS_IS_PHYS) {
 359                addr = BLK_BOUNCE_ANY;
 360        } else if (on && drive->media == ide_disk) {
 361                if (HWIF(drive)->pci_dev)
 362                        addr = HWIF(drive)->pci_dev->dma_mask;
 363        }
 364
 365        if (drive->queue)
 366                blk_queue_bounce_limit(drive->queue, addr);
 367}
 368
 369int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
 370{
 371        ide_hwif_t *hwif = drive->hwif;
 372
 373        if (hwif->set_pio_mode == NULL)
 374                return -1;
 375
 376        /*
 377         * TODO: temporary hack for some legacy host drivers that didn't
 378         * set transfer mode on the device in ->set_pio_mode method...
 379         */
 380        if (hwif->set_dma_mode == NULL) {
 381                hwif->set_pio_mode(drive, mode - XFER_PIO_0);
 382                return 0;
 383        }
 384
 385        if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
 386                if (ide_config_drive_speed(drive, mode))
 387                        return -1;
 388                hwif->set_pio_mode(drive, mode - XFER_PIO_0);
 389                return 0;
 390        } else {
 391                hwif->set_pio_mode(drive, mode - XFER_PIO_0);
 392                return ide_config_drive_speed(drive, mode);
 393        }
 394}
 395
 396int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
 397{
 398        ide_hwif_t *hwif = drive->hwif;
 399
 400        if (hwif->set_dma_mode == NULL)
 401                return -1;
 402
 403        if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
 404                if (ide_config_drive_speed(drive, mode))
 405                        return -1;
 406                hwif->set_dma_mode(drive, mode);
 407                return 0;
 408        } else {
 409                hwif->set_dma_mode(drive, mode);
 410                return ide_config_drive_speed(drive, mode);
 411        }
 412}
 413
 414EXPORT_SYMBOL_GPL(ide_set_dma_mode);
 415
 416/**
 417 *      ide_set_xfer_rate       -       set transfer rate
 418 *      @drive: drive to set
 419 *      @rate: speed to attempt to set
 420 *      
 421 *      General helper for setting the speed of an IDE device. This
 422 *      function knows about user enforced limits from the configuration
 423 *      which ->set_pio_mode/->set_dma_mode does not.
 424 */
 425
 426int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
 427{
 428        ide_hwif_t *hwif = drive->hwif;
 429
 430        if (hwif->set_dma_mode == NULL)
 431                return -1;
 432
 433        rate = ide_rate_filter(drive, rate);
 434
 435        if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
 436                return ide_set_pio_mode(drive, rate);
 437
 438        /*
 439         * TODO: transfer modes 0x00-0x07 passed from the user-space are
 440         * currently handled here which needs fixing (please note that such
 441         * case could happen iff the transfer mode has already been set on
 442         * the device by ide-proc.c::set_xfer_rate()).
 443         */
 444
 445        return ide_set_dma_mode(drive, rate);
 446}
 447
 448static void ide_dump_opcode(ide_drive_t *drive)
 449{
 450        struct request *rq;
 451        u8 opcode = 0;
 452        int found = 0;
 453
 454        spin_lock(&ide_lock);
 455        rq = NULL;
 456        if (HWGROUP(drive))
 457                rq = HWGROUP(drive)->rq;
 458        spin_unlock(&ide_lock);
 459        if (!rq)
 460                return;
 461        if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
 462            rq->cmd_type == REQ_TYPE_ATA_TASK) {
 463                char *args = rq->buffer;
 464                if (args) {
 465                        opcode = args[0];
 466                        found = 1;
 467                }
 468        } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
 469                ide_task_t *args = rq->special;
 470                if (args) {
 471                        task_struct_t *tf = (task_struct_t *) args->tfRegister;
 472                        opcode = tf->command;
 473                        found = 1;
 474                }
 475        }
 476
 477        printk("ide: failed opcode was: ");
 478        if (!found)
 479                printk("unknown\n");
 480        else
 481                printk("0x%02x\n", opcode);
 482}
 483
 484static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
 485{
 486        ide_hwif_t *hwif = HWIF(drive);
 487        unsigned long flags;
 488        u8 err = 0;
 489
 490        local_irq_save(flags);
 491        printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
 492        if (stat & BUSY_STAT)
 493                printk("Busy ");
 494        else {
 495                if (stat & READY_STAT)  printk("DriveReady ");
 496                if (stat & WRERR_STAT)  printk("DeviceFault ");
 497                if (stat & SEEK_STAT)   printk("SeekComplete ");
 498                if (stat & DRQ_STAT)    printk("DataRequest ");
 499                if (stat & ECC_STAT)    printk("CorrectedError ");
 500                if (stat & INDEX_STAT)  printk("Index ");
 501                if (stat & ERR_STAT)    printk("Error ");
 502        }
 503        printk("}\n");
 504        if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
 505                err = hwif->INB(IDE_ERROR_REG);
 506                printk("%s: %s: error=0x%02x { ", drive->name, msg, err);
 507                if (err & ABRT_ERR)     printk("DriveStatusError ");
 508                if (err & ICRC_ERR)
 509                        printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
 510                if (err & ECC_ERR)      printk("UncorrectableError ");
 511                if (err & ID_ERR)       printk("SectorIdNotFound ");
 512                if (err & TRK0_ERR)     printk("TrackZeroNotFound ");
 513                if (err & MARK_ERR)     printk("AddrMarkNotFound ");
 514                printk("}");
 515                if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR ||
 516                    (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
 517                        if (drive->addressing == 1) {
 518                                __u64 sectors = 0;
 519                                u32 low = 0, high = 0;
 520                                hwif->OUTB(drive->ctl&~0x80, IDE_CONTROL_REG);
 521                                low = ide_read_24(drive);
 522                                hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
 523                                high = ide_read_24(drive);
 524                                sectors = ((__u64)high << 24) | low;
 525                                printk(", LBAsect=%llu, high=%d, low=%d",
 526                                       (unsigned long long) sectors,
 527                                       high, low);
 528                        } else {
 529                                u8 cur = hwif->INB(IDE_SELECT_REG);
 530                                if (cur & 0x40) {       /* using LBA? */
 531                                        printk(", LBAsect=%ld", (unsigned long)
 532                                         ((cur&0xf)<<24)
 533                                         |(hwif->INB(IDE_HCYL_REG)<<16)
 534                                         |(hwif->INB(IDE_LCYL_REG)<<8)
 535                                         | hwif->INB(IDE_SECTOR_REG));
 536                                } else {
 537                                        printk(", CHS=%d/%d/%d",
 538                                         (hwif->INB(IDE_HCYL_REG)<<8) +
 539                                          hwif->INB(IDE_LCYL_REG),
 540                                          cur & 0xf,
 541                                          hwif->INB(IDE_SECTOR_REG));
 542                                }
 543                        }
 544                        if (HWGROUP(drive) && HWGROUP(drive)->rq)
 545                                printk(", sector=%llu",
 546                                        (unsigned long long)HWGROUP(drive)->rq->sector);
 547                }
 548                printk("\n");
 549        }
 550        ide_dump_opcode(drive);
 551        local_irq_restore(flags);
 552        return err;
 553}
 554
 555/**
 556 *      ide_dump_atapi_status       -       print human readable atapi status
 557 *      @drive: drive that status applies to
 558 *      @msg: text message to print
 559 *      @stat: status byte to decode
 560 *
 561 *      Error reporting, in human readable form (luxurious, but a memory hog).
 562 */
 563
 564static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat)
 565{
 566        unsigned long flags;
 567
 568        atapi_status_t status;
 569        atapi_error_t error;
 570
 571        status.all = stat;
 572        error.all = 0;
 573        local_irq_save(flags);
 574        printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
 575        if (status.b.bsy)
 576                printk("Busy ");
 577        else {
 578                if (status.b.drdy)      printk("DriveReady ");
 579                if (status.b.df)        printk("DeviceFault ");
 580                if (status.b.dsc)       printk("SeekComplete ");
 581                if (status.b.drq)       printk("DataRequest ");
 582                if (status.b.corr)      printk("CorrectedError ");
 583                if (status.b.idx)       printk("Index ");
 584                if (status.b.check)     printk("Error ");
 585        }
 586        printk("}\n");
 587        if (status.b.check && !status.b.bsy) {
 588                error.all = HWIF(drive)->INB(IDE_ERROR_REG);
 589                printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all);
 590                if (error.b.ili)        printk("IllegalLengthIndication ");
 591                if (error.b.eom)        printk("EndOfMedia ");
 592                if (error.b.abrt)       printk("AbortedCommand ");
 593                if (error.b.mcr)        printk("MediaChangeRequested ");
 594                if (error.b.sense_key)  printk("LastFailedSense=0x%02x ",
 595                                                error.b.sense_key);
 596                printk("}\n");
 597        }
 598        ide_dump_opcode(drive);
 599        local_irq_restore(flags);
 600        return error.all;
 601}
 602
 603/**
 604 *      ide_dump_status         -       translate ATA/ATAPI error
 605 *      @drive: drive the error occured on
 606 *      @msg: information string
 607 *      @stat: status byte
 608 *
 609 *      Error reporting, in human readable form (luxurious, but a memory hog).
 610 *      Combines the drive name, message and status byte to provide a
 611 *      user understandable explanation of the device error.
 612 */
 613
 614u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
 615{
 616        if (drive->media == ide_disk)
 617                return ide_dump_ata_status(drive, msg, stat);
 618        return ide_dump_atapi_status(drive, msg, stat);
 619}
 620
 621EXPORT_SYMBOL(ide_dump_status);
 622
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.