#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/uaccess.h>
void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS);
tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob);
void ide_tf_dump(const char *s, struct ide_cmd *cmd)
printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
s, cmd->tf.feature, cmd->tf.nsect,
cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah,
cmd->tf.device, cmd->tf.command);
printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x\n",
s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah);
int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
memset(&cmd, 0, sizeof(cmd));
if (drive->media == ide_disk)
cmd.tf.command = ATA_CMD_ID_ATA;
cmd.tf.command = ATA_CMD_ID_ATAPI;
cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
cmd.protocol = ATA_PROT_PIO;
return ide_raw_taskfile(drive, &cmd, buf, 1);
static ide_startstop_t task_no_data_intr(ide_drive_t *);
static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
static ide_startstop_t task_pio_intr(ide_drive_t *);
ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd *cmd = &hwif->cmd;
struct ide_taskfile *tf = &cmd->tf;
ide_handler_t *handler = NULL;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
if (orig_cmd->protocol == ATA_PROT_PIO &&
(orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
drive->mult_count == 0) {
pr_err("%s: multimode not set!\n", drive->name);