linux/drivers/ide/ide-taskfile.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2000-2002        Michael Cornwell <cornwell@acm.org>
   3 *  Copyright (C) 2000-2002        Andre Hedrick <andre@linux-ide.org>
   4 *  Copyright (C) 2001-2002        Klaus Smolin
   5 *                                      IBM Storage Technology Division
   6 *  Copyright (C) 2003-2004, 2007  Bartlomiej Zolnierkiewicz
   7 *
   8 *  The big the bad and the ugly.
   9 */
  10
  11#include <linux/types.h>
  12#include <linux/string.h>
  13#include <linux/kernel.h>
  14#include <linux/sched.h>
  15#include <linux/interrupt.h>
  16#include <linux/errno.h>
  17#include <linux/slab.h>
  18#include <linux/delay.h>
  19#include <linux/hdreg.h>
  20#include <linux/ide.h>
  21#include <linux/scatterlist.h>
  22#include <linux/uaccess.h>
  23
  24#include <asm/io.h>
  25
  26void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
  27{
  28        ide_hwif_t *hwif = drive->hwif;
  29        const struct ide_tp_ops *tp_ops = hwif->tp_ops;
  30
  31        /* Be sure we're looking at the low order bytes */
  32        tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
  33
  34        tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf);
  35
  36        if (cmd->tf_flags & IDE_TFLAG_LBA48) {
  37                tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS);
  38
  39                tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob);
  40        }
  41}
  42
  43void ide_tf_dump(const char *s, struct ide_cmd *cmd)
  44{
  45#ifdef DEBUG
  46        printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
  47                "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
  48               s, cmd->tf.feature, cmd->tf.nsect,
  49               cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah,
  50               cmd->tf.device, cmd->tf.command);
  51        printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x\n",
  52               s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah);
  53#endif
  54}
  55
  56int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
  57{
  58        struct ide_cmd cmd;
  59
  60        memset(&cmd, 0, sizeof(cmd));
  61        cmd.tf.nsect = 0x01;
  62        if (drive->media == ide_disk)
  63                cmd.tf.command = ATA_CMD_ID_ATA;
  64        else
  65                cmd.tf.command = ATA_CMD_ID_ATAPI;
  66        cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
  67        cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
  68        cmd.protocol = ATA_PROT_PIO;
  69
  70        return ide_raw_taskfile(drive, &cmd, buf, 1);
  71}
  72
  73static ide_startstop_t task_no_data_intr(ide_drive_t *);
  74static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
  75static ide_startstop_t task_pio_intr(ide_drive_t *);
  76
  77ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
  78{
  79        ide_hwif_t *hwif = drive->hwif;
  80        struct ide_cmd *cmd = &hwif->cmd;
  81        struct ide_taskfile *tf = &cmd->tf;
  82        ide_handler_t *handler = NULL;
  83        const struct ide_tp_ops *tp_ops = hwif->tp_ops;
  84        const struct ide_dma_ops *dma_ops = hwif->dma_ops;
  85
  86        if (orig_cmd->protocol == ATA_PROT_PIO &&
  87            (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
  88            drive->mult_count == 0) {
  89                pr_err("%s: multimode not set!\n", drive->name);
  90                return ide_stopped;
  91        }
  92
  93        if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
  94                orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
  95
  96        memcpy(cmd, orig_cmd, sizeof(*cmd));
  97
  98        if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
  99                ide_tf_dump(drive->name, cmd);
 100                tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 101
 102                if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
 103                        u8 data[2] = { cmd->tf.data, cmd->hob.data };
 104
 105                        tp_ops->output_data(drive, cmd, data, 2);
 106                }
 107
 108                if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
 109                        u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
 110                                  0xE0 : 0xEF;
 111
 112                        if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
 113                                cmd->tf.device &= HIHI;
 114                        cmd->tf.device |= drive->select;
 115                }
 116
 117                tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
 118                tp_ops->tf_load(drive, &cmd->tf,  cmd->valid.out.tf);
 119        }
 120
 121        switch (cmd->protocol) {
 122        case ATA_PROT_PIO:
 123                if (cmd->tf_flags & IDE_TFLAG_WRITE) {
 124                        tp_ops->exec_command(hwif, tf->command);
 125                        ndelay(400);    /* FIXME */
 126                        return pre_task_out_intr(drive, cmd);
 127                }
 128                handler = task_pio_intr;
 129                /* fall-through */
 130        case ATA_PROT_NODATA:
 131                if (handler == NULL)
 132                        handler = task_no_data_intr;
 133                ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
 134                return ide_started;
 135        case ATA_PROT_DMA:
 136                if (ide_dma_prepare(drive, cmd))
 137                        return ide_stopped;
 138                hwif->expiry = dma_ops->dma_timer_expiry;
 139                ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
 140                dma_ops->dma_start(drive);
 141        default:
 142                return ide_started;
 143        }
 144}
 145EXPORT_SYMBOL_GPL(do_rw_taskfile);
 146
 147static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 148{
 149        ide_hwif_t *hwif = drive->hwif;
 150        struct ide_cmd *cmd = &hwif->cmd;
 151        struct ide_taskfile *tf = &cmd->tf;
 152        int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
 153        int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
 154        u8 stat;
 155
 156        local_irq_enable_in_hardirq();
 157
 158        while (1) {
 159                stat = hwif->tp_ops->read_status(hwif);
 160                if ((stat & ATA_BUSY) == 0 || retries-- == 0)
 161                        break;
 162                udelay(10);
 163        };
 164
 165        if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
 166                if (custom && tf->command == ATA_CMD_SET_MULTI) {
 167                        drive->mult_req = drive->mult_count = 0;
 168                        drive->special_flags |= IDE_SFLAG_RECALIBRATE;
 169                        (void)ide_dump_status(drive, __func__, stat);
 170                        return ide_stopped;
 171                } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
 172                        if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
 173                                ide_set_handler(drive, &task_no_data_intr,
 174                                                WAIT_WORSTCASE);
 175                                return ide_started;
 176                        }
 177                }
 178                return ide_error(drive, "task_no_data_intr", stat);
 179        }
 180
 181        if (custom && tf->command == ATA_CMD_SET_MULTI)
 182                drive->mult_count = drive->mult_req;
 183
 184        if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
 185            tf->command == ATA_CMD_CHK_POWER) {
 186                struct request *rq = hwif->rq;
 187
 188                if (blk_pm_request(rq))
 189                        ide_complete_pm_rq(drive, rq);
 190                else
 191                        ide_finish_cmd(drive, cmd, stat);
 192        }
 193
 194        return ide_stopped;
 195}
 196
 197static u8 wait_drive_not_busy(ide_drive_t *drive)
 198{
 199        ide_hwif_t *hwif = drive->hwif;
 200        int retries;
 201        u8 stat;
 202
 203        /*
 204         * Last sector was transfered, wait until device is ready.  This can
 205         * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
 206         */
 207        for (retries = 0; retries < 1000; retries++) {
 208                stat = hwif->tp_ops->read_status(hwif);
 209
 210                if (stat & ATA_BUSY)
 211                        udelay(10);
 212                else
 213                        break;
 214        }
 215
 216        if (stat & ATA_BUSY)
 217                pr_err("%s: drive still BUSY!\n", drive->name);
 218
 219        return stat;
 220}
 221
 222void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 223                   unsigned int write, unsigned int len)
 224{
 225        ide_hwif_t *hwif = drive->hwif;
 226        struct scatterlist *sg = hwif->sg_table;
 227        struct scatterlist *cursg = cmd->cursg;
 228        unsigned long uninitialized_var(flags);
 229        struct page *page;
 230        unsigned int offset;
 231        u8 *buf;
 232
 233        cursg = cmd->cursg;
 234        if (cursg == NULL)
 235                cursg = cmd->cursg = sg;
 236
 237        while (len) {
 238                unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
 239                int page_is_high;
 240
 241                if (nr_bytes > PAGE_SIZE)
 242                        nr_bytes = PAGE_SIZE;
 243
 244                page = sg_page(cursg);
 245                offset = cursg->offset + cmd->cursg_ofs;
 246
 247                /* get the current page and offset */
 248                page = nth_page(page, (offset >> PAGE_SHIFT));
 249                offset %= PAGE_SIZE;
 250
 251                page_is_high = PageHighMem(page);
 252                if (page_is_high)
 253                        local_irq_save(flags);
 254
 255                buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
 256
 257                cmd->nleft -= nr_bytes;
 258                cmd->cursg_ofs += nr_bytes;
 259
 260                if (cmd->cursg_ofs == cursg->length) {
 261                        cursg = cmd->cursg = sg_next(cmd->cursg);
 262                        cmd->cursg_ofs = 0;
 263                }
 264
 265                /* do the actual data transfer */
 266                if (write)
 267                        hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
 268                else
 269                        hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
 270
 271                kunmap_atomic(buf, KM_BIO_SRC_IRQ);
 272
 273                if (page_is_high)
 274                        local_irq_restore(flags);
 275
 276                len -= nr_bytes;
 277        }
 278}
 279EXPORT_SYMBOL_GPL(ide_pio_bytes);
 280
 281static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
 282                              unsigned int write)
 283{
 284        unsigned int nr_bytes;
 285
 286        u8 saved_io_32bit = drive->io_32bit;
 287
 288        if (cmd->tf_flags & IDE_TFLAG_FS)
 289                cmd->rq->errors = 0;
 290
 291        if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
 292                drive->io_32bit = 0;
 293
 294        touch_softlockup_watchdog();
 295
 296        if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
 297                nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
 298        else
 299                nr_bytes = SECTOR_SIZE;
 300
 301        ide_pio_bytes(drive, cmd, write, nr_bytes);
 302
 303        drive->io_32bit = saved_io_32bit;
 304}
 305
 306static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
 307{
 308        if (cmd->tf_flags & IDE_TFLAG_FS) {
 309                int nr_bytes = cmd->nbytes - cmd->nleft;
 310
 311                if (cmd->protocol == ATA_PROT_PIO &&
 312                    ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) {
 313                        if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
 314                                nr_bytes -= drive->mult_count << 9;
 315                        else
 316                                nr_bytes -= SECTOR_SIZE;
 317                }
 318
 319                if (nr_bytes > 0)
 320                        ide_complete_rq(drive, 0, nr_bytes);
 321        }
 322}
 323
 324void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
 325{
 326        struct request *rq = drive->hwif->rq;
 327        u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
 328        u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
 329
 330        ide_complete_cmd(drive, cmd, stat, err);
 331        rq->errors = err;
 332
 333        if (err == 0 && set_xfer) {
 334                ide_set_xfer_rate(drive, nsect);
 335                ide_driveid_update(drive);
 336        }
 337
 338        ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
 339}
 340
 341/*
 342 * Handler for command with PIO data phase.
 343 */
 344static ide_startstop_t task_pio_intr(ide_drive_t *drive)
 345{
 346        ide_hwif_t *hwif = drive->hwif;
 347        struct ide_cmd *cmd = &drive->hwif->cmd;
 348        u8 stat = hwif->tp_ops->read_status(hwif);
 349        u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
 350
 351        if (write == 0) {
 352                /* Error? */
 353                if (stat & ATA_ERR)
 354                        goto out_err;
 355
 356                /* Didn't want any data? Odd. */
 357                if ((stat & ATA_DRQ) == 0) {
 358                        /* Command all done? */
 359                        if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
 360                                goto out_end;
 361
 362                        /* Assume it was a spurious irq */
 363                        goto out_wait;
 364                }
 365        } else {
 366                if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
 367                        goto out_err;
 368
 369                /* Deal with unexpected ATA data phase. */
 370                if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
 371                        goto out_err;
 372        }
 373
 374        if (write && cmd->nleft == 0)
 375                goto out_end;
 376
 377        /* Still data left to transfer. */
 378        ide_pio_datablock(drive, cmd, write);
 379
 380        /* Are we done? Check status and finish transfer. */
 381        if (write == 0 && cmd->nleft == 0) {
 382                stat = wait_drive_not_busy(drive);
 383                if (!OK_STAT(stat, 0, BAD_STAT))
 384                        goto out_err;
 385
 386                goto out_end;
 387        }
 388out_wait:
 389        /* Still data left to transfer. */
 390        ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
 391        return ide_started;
 392out_end:
 393        if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
 394                ide_finish_cmd(drive, cmd, stat);
 395        else
 396                ide_complete_rq(drive, 0, blk_rq_sectors(cmd->rq) << 9);
 397        return ide_stopped;
 398out_err:
 399        ide_error_cmd(drive, cmd);
 400        return ide_error(drive, __func__, stat);
 401}
 402
 403static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
 404                                         struct ide_cmd *cmd)
 405{
 406        ide_startstop_t startstop;
 407
 408        if (ide_wait_stat(&startstop, drive, ATA_DRQ,
 409                          drive->bad_wstat, WAIT_DRQ)) {
 410                pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name,
 411                        (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
 412                        (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
 413                return startstop;
 414        }
 415
 416        if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
 417                local_irq_disable();
 418
 419        ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
 420
 421        ide_pio_datablock(drive, cmd, 1);
 422
 423        return ide_started;
 424}
 425
 426int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
 427                     u16 nsect)
 428{
 429        struct request *rq;
 430        int error;
 431        int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
 432
 433        rq = blk_get_request(drive->queue, rw, __GFP_WAIT);
 434        rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
 435
 436        /*
 437         * (ks) We transfer currently only whole sectors.
 438         * This is suffient for now.  But, it would be great,
 439         * if we would find a solution to transfer any size.
 440         * To support special commands like READ LONG.
 441         */
 442        if (nsect) {
 443                error = blk_rq_map_kern(drive->queue, rq, buf,
 444                                        nsect * SECTOR_SIZE, __GFP_WAIT);
 445                if (error)
 446                        goto put_req;
 447        }
 448
 449        rq->special = cmd;
 450        cmd->rq = rq;
 451
 452        error = blk_execute_rq(drive->queue, NULL, rq, 0);
 453
 454put_req:
 455        blk_put_request(rq);
 456        return error;
 457}
 458EXPORT_SYMBOL(ide_raw_taskfile);
 459
 460int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
 461{
 462        cmd->protocol = ATA_PROT_NODATA;
 463
 464        return ide_raw_taskfile(drive, cmd, NULL, 0);
 465}
 466EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
 467
 468#ifdef CONFIG_IDE_TASK_IOCTL
 469int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 470{
 471        ide_task_request_t      *req_task;
 472        struct ide_cmd          cmd;
 473        u8 *outbuf              = NULL;
 474        u8 *inbuf               = NULL;
 475        u8 *data_buf            = NULL;
 476        int err                 = 0;
 477        int tasksize            = sizeof(struct ide_task_request_s);
 478        unsigned int taskin     = 0;
 479        unsigned int taskout    = 0;
 480        u16 nsect               = 0;
 481        char __user *buf = (char __user *)arg;
 482
 483        req_task = kzalloc(tasksize, GFP_KERNEL);
 484        if (req_task == NULL)
 485                return -ENOMEM;
 486        if (copy_from_user(req_task, buf, tasksize)) {
 487                kfree(req_task);
 488                return -EFAULT;
 489        }
 490
 491        taskout = req_task->out_size;
 492        taskin  = req_task->in_size;
 493
 494        if (taskin > 65536 || taskout > 65536) {
 495                err = -EINVAL;
 496                goto abort;
 497        }
 498
 499        if (taskout) {
 500                int outtotal = tasksize;
 501                outbuf = kzalloc(taskout, GFP_KERNEL);
 502                if (outbuf == NULL) {
 503                        err = -ENOMEM;
 504                        goto abort;
 505                }
 506                if (copy_from_user(outbuf, buf + outtotal, taskout)) {
 507                        err = -EFAULT;
 508                        goto abort;
 509                }
 510        }
 511
 512        if (taskin) {
 513                int intotal = tasksize + taskout;
 514                inbuf = kzalloc(taskin, GFP_KERNEL);
 515                if (inbuf == NULL) {
 516                        err = -ENOMEM;
 517                        goto abort;
 518                }
 519                if (copy_from_user(inbuf, buf + intotal, taskin)) {
 520                        err = -EFAULT;
 521                        goto abort;
 522                }
 523        }
 524
 525        memset(&cmd, 0, sizeof(cmd));
 526
 527        memcpy(&cmd.hob, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
 528        memcpy(&cmd.tf,  req_task->io_ports,  HDIO_DRIVE_TASK_HDR_SIZE);
 529
 530        cmd.valid.out.tf = IDE_VALID_DEVICE;
 531        cmd.valid.in.tf  = IDE_VALID_DEVICE | IDE_VALID_IN_TF;
 532        cmd.tf_flags = IDE_TFLAG_IO_16BIT;
 533
 534        if (drive->dev_flags & IDE_DFLAG_LBA48) {
 535                cmd.tf_flags |= IDE_TFLAG_LBA48;
 536                cmd.valid.in.hob = IDE_VALID_IN_HOB;
 537        }
 538
 539        if (req_task->out_flags.all) {
 540                cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
 541
 542                if (req_task->out_flags.b.data)
 543                        cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
 544
 545                if (req_task->out_flags.b.nsector_hob)
 546                        cmd.valid.out.hob |= IDE_VALID_NSECT;
 547                if (req_task->out_flags.b.sector_hob)
 548                        cmd.valid.out.hob |= IDE_VALID_LBAL;
 549                if (req_task->out_flags.b.lcyl_hob)
 550                        cmd.valid.out.hob |= IDE_VALID_LBAM;
 551                if (req_task->out_flags.b.hcyl_hob)
 552                        cmd.valid.out.hob |= IDE_VALID_LBAH;
 553
 554                if (req_task->out_flags.b.error_feature)
 555                        cmd.valid.out.tf  |= IDE_VALID_FEATURE;
 556                if (req_task->out_flags.b.nsector)
 557                        cmd.valid.out.tf  |= IDE_VALID_NSECT;
 558                if (req_task->out_flags.b.sector)
 559                        cmd.valid.out.tf  |= IDE_VALID_LBAL;
 560                if (req_task->out_flags.b.lcyl)
 561                        cmd.valid.out.tf  |= IDE_VALID_LBAM;
 562                if (req_task->out_flags.b.hcyl)
 563                        cmd.valid.out.tf  |= IDE_VALID_LBAH;
 564        } else {
 565                cmd.valid.out.tf |= IDE_VALID_OUT_TF;
 566                if (cmd.tf_flags & IDE_TFLAG_LBA48)
 567                        cmd.valid.out.hob |= IDE_VALID_OUT_HOB;
 568        }
 569
 570        if (req_task->in_flags.b.data)
 571                cmd.ftf_flags |= IDE_FTFLAG_IN_DATA;
 572
 573        if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) {
 574                /* fixup data phase if needed */
 575                if (req_task->data_phase == TASKFILE_IN_DMAQ ||
 576                    req_task->data_phase == TASKFILE_IN_DMA)
 577                        cmd.tf_flags |= IDE_TFLAG_WRITE;
 578        }
 579
 580        cmd.protocol = ATA_PROT_DMA;
 581
 582        switch (req_task->data_phase) {
 583        case TASKFILE_MULTI_OUT:
 584                if (!drive->mult_count) {
 585                        /* (hs): give up if multcount is not set */
 586                        pr_err("%s: %s Multimode Write multcount is not set\n",
 587                                drive->name, __func__);
 588                        err = -EPERM;
 589                        goto abort;
 590                }
 591                cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
 592                /* fall through */
 593        case TASKFILE_OUT:
 594                cmd.protocol = ATA_PROT_PIO;
 595                /* fall through */
 596        case TASKFILE_OUT_DMAQ:
 597        case TASKFILE_OUT_DMA:
 598                cmd.tf_flags |= IDE_TFLAG_WRITE;
 599                nsect = taskout / SECTOR_SIZE;
 600                data_buf = outbuf;
 601                break;
 602        case TASKFILE_MULTI_IN:
 603                if (!drive->mult_count) {
 604                        /* (hs): give up if multcount is not set */
 605                        pr_err("%s: %s Multimode Read multcount is not set\n",
 606                                drive->name, __func__);
 607                        err = -EPERM;
 608                        goto abort;
 609                }
 610                cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
 611                /* fall through */
 612        case TASKFILE_IN:
 613                cmd.protocol = ATA_PROT_PIO;
 614                /* fall through */
 615        case TASKFILE_IN_DMAQ:
 616        case TASKFILE_IN_DMA:
 617                nsect = taskin / SECTOR_SIZE;
 618                data_buf = inbuf;
 619                break;
 620        case TASKFILE_NO_DATA:
 621                cmd.protocol = ATA_PROT_NODATA;
 622                break;
 623        default:
 624                err = -EFAULT;
 625                goto abort;
 626        }
 627
 628        if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
 629                nsect = 0;
 630        else if (!nsect) {
 631                nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
 632
 633                if (!nsect) {
 634                        pr_err("%s: in/out command without data\n",
 635                                        drive->name);
 636                        err = -EFAULT;
 637                        goto abort;
 638                }
 639        }
 640
 641        err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
 642
 643        memcpy(req_task->hob_ports, &cmd.hob, HDIO_DRIVE_HOB_HDR_SIZE - 2);
 644        memcpy(req_task->io_ports,  &cmd.tf,  HDIO_DRIVE_TASK_HDR_SIZE);
 645
 646        if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
 647            req_task->in_flags.all == 0) {
 648                req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
 649                if (drive->dev_flags & IDE_DFLAG_LBA48)
 650                        req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
 651        }
 652
 653        if (copy_to_user(buf, req_task, tasksize)) {
 654                err = -EFAULT;
 655                goto abort;
 656        }
 657        if (taskout) {
 658                int outtotal = tasksize;
 659                if (copy_to_user(buf + outtotal, outbuf, taskout)) {
 660                        err = -EFAULT;
 661                        goto abort;
 662                }
 663        }
 664        if (taskin) {
 665                int intotal = tasksize + taskout;
 666                if (copy_to_user(buf + intotal, inbuf, taskin)) {
 667                        err = -EFAULT;
 668                        goto abort;
 669                }
 670        }
 671abort:
 672        kfree(req_task);
 673        kfree(outbuf);
 674        kfree(inbuf);
 675
 676        return err;
 677}
 678#endif
 679
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.