linux/drivers/ide/ide-xfer-mode.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <linux/types.h>
   3#include <linux/string.h>
   4#include <linux/kernel.h>
   5#include <linux/export.h>
   6#include <linux/interrupt.h>
   7#include <linux/ide.h>
   8#include <linux/bitops.h>
   9
  10static const char *udma_str[] =
  11         { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
  12           "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
  13static const char *mwdma_str[] =
  14        { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
  15static const char *swdma_str[] =
  16        { "SWDMA0", "SWDMA1", "SWDMA2" };
  17static const char *pio_str[] =
  18        { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
  19
  20/**
  21 *      ide_xfer_verbose        -       return IDE mode names
  22 *      @mode: transfer mode
  23 *
  24 *      Returns a constant string giving the name of the mode
  25 *      requested.
  26 */
  27
  28const char *ide_xfer_verbose(u8 mode)
  29{
  30        const char *s;
  31        u8 i = mode & 0xf;
  32
  33        if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
  34                s = udma_str[i];
  35        else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
  36                s = mwdma_str[i];
  37        else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
  38                s = swdma_str[i];
  39        else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
  40                s = pio_str[i & 0x7];
  41        else if (mode == XFER_PIO_SLOW)
  42                s = "PIO SLOW";
  43        else
  44                s = "XFER ERROR";
  45
  46        return s;
  47}
  48EXPORT_SYMBOL(ide_xfer_verbose);
  49
  50/**
  51 *      ide_get_best_pio_mode   -       get PIO mode from drive
  52 *      @drive: drive to consider
  53 *      @mode_wanted: preferred mode
  54 *      @max_mode: highest allowed mode
  55 *
  56 *      This routine returns the recommended PIO settings for a given drive,
  57 *      based on the drive->id information and the ide_pio_blacklist[].
  58 *
  59 *      Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
  60 *      This is used by most chipset support modules when "auto-tuning".
  61 */
  62
  63static u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
  64{
  65        u16 *id = drive->id;
  66        int pio_mode = -1, overridden = 0;
  67
  68        if (mode_wanted != 255)
  69                return min_t(u8, mode_wanted, max_mode);
  70
  71        if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
  72                pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
  73
  74        if (pio_mode != -1) {
  75                printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
  76        } else {
  77                pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
  78                if (pio_mode > 2) {     /* 2 is maximum allowed tPIO value */
  79                        pio_mode = 2;
  80                        overridden = 1;
  81                }
  82
  83                if (id[ATA_ID_FIELD_VALID] & 2) {             /* ATA2? */
  84                        if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
  85                                pio_mode = 4 + min_t(int, 2,
  86                                                     id[ATA_ID_CFA_MODES] & 7);
  87                        else if (ata_id_has_iordy(id)) {
  88                                if (id[ATA_ID_PIO_MODES] & 7) {
  89                                        overridden = 0;
  90                                        if (id[ATA_ID_PIO_MODES] & 4)
  91                                                pio_mode = 5;
  92                                        else if (id[ATA_ID_PIO_MODES] & 2)
  93                                                pio_mode = 4;
  94                                        else
  95                                                pio_mode = 3;
  96                                }
  97                        }
  98                }
  99
 100                if (overridden)
 101                        printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
 102                                         drive->name);
 103        }
 104
 105        if (pio_mode > max_mode)
 106                pio_mode = max_mode;
 107
 108        return pio_mode;
 109}
 110
 111int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
 112{
 113        /*
 114         * IORDY may lead to controller lock up on certain controllers
 115         * if the port is not occupied.
 116         */
 117        if (pio == 0 && (drive->hwif->port_flags & IDE_PFLAG_PROBING))
 118                return 0;
 119        return ata_id_pio_need_iordy(drive->id, pio);
 120}
 121EXPORT_SYMBOL_GPL(ide_pio_need_iordy);
 122
 123int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
 124{
 125        ide_hwif_t *hwif = drive->hwif;
 126        const struct ide_port_ops *port_ops = hwif->port_ops;
 127
 128        if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
 129                return 0;
 130
 131        if (port_ops == NULL || port_ops->set_pio_mode == NULL)
 132                return -1;
 133
 134        /*
 135         * TODO: temporary hack for some legacy host drivers that didn't
 136         * set transfer mode on the device in ->set_pio_mode method...
 137         */
 138        if (port_ops->set_dma_mode == NULL) {
 139                drive->pio_mode = mode;
 140                port_ops->set_pio_mode(hwif, drive);
 141                return 0;
 142        }
 143
 144        if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
 145                if (ide_config_drive_speed(drive, mode))
 146                        return -1;
 147                drive->pio_mode = mode;
 148                port_ops->set_pio_mode(hwif, drive);
 149                return 0;
 150        } else {
 151                drive->pio_mode = mode;
 152                port_ops->set_pio_mode(hwif, drive);
 153                return ide_config_drive_speed(drive, mode);
 154        }
 155}
 156
 157int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
 158{
 159        ide_hwif_t *hwif = drive->hwif;
 160        const struct ide_port_ops *port_ops = hwif->port_ops;
 161
 162        if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
 163                return 0;
 164
 165        if (port_ops == NULL || port_ops->set_dma_mode == NULL)
 166                return -1;
 167
 168        if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
 169                if (ide_config_drive_speed(drive, mode))
 170                        return -1;
 171                drive->dma_mode = mode;
 172                port_ops->set_dma_mode(hwif, drive);
 173                return 0;
 174        } else {
 175                drive->dma_mode = mode;
 176                port_ops->set_dma_mode(hwif, drive);
 177                return ide_config_drive_speed(drive, mode);
 178        }
 179}
 180EXPORT_SYMBOL_GPL(ide_set_dma_mode);
 181
 182/* req_pio == "255" for auto-tune */
 183void ide_set_pio(ide_drive_t *drive, u8 req_pio)
 184{
 185        ide_hwif_t *hwif = drive->hwif;
 186        const struct ide_port_ops *port_ops = hwif->port_ops;
 187        u8 host_pio, pio;
 188
 189        if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
 190            (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
 191                return;
 192
 193        BUG_ON(hwif->pio_mask == 0x00);
 194
 195        host_pio = fls(hwif->pio_mask) - 1;
 196
 197        pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
 198
 199        /*
 200         * TODO:
 201         * - report device max PIO mode
 202         * - check req_pio != 255 against device max PIO mode
 203         */
 204        printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
 205                          drive->name, host_pio, req_pio,
 206                          req_pio == 255 ? "(auto-tune)" : "", pio);
 207
 208        (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
 209}
 210EXPORT_SYMBOL_GPL(ide_set_pio);
 211
 212/**
 213 *      ide_rate_filter         -       filter transfer mode
 214 *      @drive: IDE device
 215 *      @speed: desired speed
 216 *
 217 *      Given the available transfer modes this function returns
 218 *      the best available speed at or below the speed requested.
 219 *
 220 *      TODO: check device PIO capabilities
 221 */
 222
 223static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
 224{
 225        ide_hwif_t *hwif = drive->hwif;
 226        u8 mode = ide_find_dma_mode(drive, speed);
 227
 228        if (mode == 0) {
 229                if (hwif->pio_mask)
 230                        mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
 231                else
 232                        mode = XFER_PIO_4;
 233        }
 234
 235/*      printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
 236
 237        return min(speed, mode);
 238}
 239
 240/**
 241 *      ide_set_xfer_rate       -       set transfer rate
 242 *      @drive: drive to set
 243 *      @rate: speed to attempt to set
 244 *
 245 *      General helper for setting the speed of an IDE device. This
 246 *      function knows about user enforced limits from the configuration
 247 *      which ->set_pio_mode/->set_dma_mode does not.
 248 */
 249
 250int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
 251{
 252        ide_hwif_t *hwif = drive->hwif;
 253        const struct ide_port_ops *port_ops = hwif->port_ops;
 254
 255        if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
 256            (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
 257                return -1;
 258
 259        rate = ide_rate_filter(drive, rate);
 260
 261        BUG_ON(rate < XFER_PIO_0);
 262
 263        if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
 264                return ide_set_pio_mode(drive, rate);
 265
 266        return ide_set_dma_mode(drive, rate);
 267}
 268