Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6ff9f64 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

ide: merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr()



* Add 'struct task_s' to ide_hwif_t and init it to the current command
  in do_rw_taskfile().

* Merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr().

Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 0e3d84a5
Loading
Loading
Loading
Loading
+25 −80
Original line number Diff line number Diff line
@@ -53,9 +53,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
}

static ide_startstop_t task_no_data_intr(ide_drive_t *);
static ide_startstop_t set_geometry_intr(ide_drive_t *);
static ide_startstop_t recal_intr(ide_drive_t *);
static ide_startstop_t set_multmode_intr(ide_drive_t *);
static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
static ide_startstop_t task_in_intr(ide_drive_t *);

@@ -79,6 +76,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
	if (task->tf_flags & IDE_TFLAG_FLAGGED)
		task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;

	memcpy(&hwif->task, task, sizeof(*task));

	if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
		ide_tf_dump(drive->name, tf);
		tp_ops->set_irq(hwif, 1);
@@ -99,19 +98,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
	case TASKFILE_NO_DATA:
		if (handler == NULL)
			handler = task_no_data_intr;
		if (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) {
			switch (tf->command) {
			case ATA_CMD_INIT_DEV_PARAMS:
				handler = set_geometry_intr;
				break;
			case ATA_CMD_RESTORE:
				handler = recal_intr;
				break;
			case ATA_CMD_SET_MULTI:
				handler = set_multmode_intr;
				break;
			}
		}
		ide_execute_command(drive, tf->command, handler,
				    WAIT_WORSTCASE, NULL);
		return ide_started;
@@ -127,33 +113,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
EXPORT_SYMBOL_GPL(do_rw_taskfile);

/*
 * set_multmode_intr() is invoked on completion of a ATA_CMD_SET_MULTI cmd.
 */
static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	u8 stat;

	local_irq_enable_in_hardirq();
	stat = hwif->tp_ops->read_status(hwif);

	if (OK_STAT(stat, ATA_DRDY, BAD_STAT))
		drive->mult_count = drive->mult_req;
	else {
		drive->mult_req = drive->mult_count = 0;
		drive->special.b.recalibrate = 1;
		(void) ide_dump_status(drive, "set_multmode", stat);
	}
	return ide_stopped;
}

/*
 * set_geometry_intr() is invoked on completion of a ATA_CMD_INIT_DEV_PARAMS cmd.
 * Handler for commands without a data phase
 */
static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	int retries = 5;
	ide_task_t *task = &hwif->task;
	struct ide_taskfile *tf = &task->tf;
	int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
	int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
	u8 stat;

	local_irq_enable_in_hardirq();
@@ -165,50 +133,27 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
		udelay(10);
	};

	if (OK_STAT(stat, ATA_DRDY, BAD_STAT))
	if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
		if (custom && tf->command == ATA_CMD_SET_MULTI) {
			drive->mult_req = drive->mult_count = 0;
			drive->special.b.recalibrate = 1;
			(void)ide_dump_status(drive, __func__, stat);
			return ide_stopped;

	if (stat & (ATA_ERR | ATA_DRQ))
		return ide_error(drive, "set_geometry_intr", stat);

	ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
		} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
			if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
				ide_set_handler(drive, &task_no_data_intr,
						WAIT_WORSTCASE, NULL);
				return ide_started;
			}

/*
 * recal_intr() is invoked on completion of a ATA_CMD_RESTORE (recalibrate) cmd.
 */
static ide_startstop_t recal_intr(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	u8 stat;

	local_irq_enable_in_hardirq();
	stat = hwif->tp_ops->read_status(hwif);

	if (!OK_STAT(stat, ATA_DRDY, BAD_STAT))
		return ide_error(drive, "recal_intr", stat);
	return ide_stopped;
		}

/*
 * Handler for commands without a data phase
 */
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	ide_task_t *args = hwif->hwgroup->rq->special;
	u8 stat;

	local_irq_enable_in_hardirq();
	stat = hwif->tp_ops->read_status(hwif);

	if (!OK_STAT(stat, ATA_DRDY, BAD_STAT))
		return ide_error(drive, "task_no_data_intr", stat);
		/* calls ide_end_drive_cmd */
	}

	if (args)
	if (!custom)
		ide_end_drive_cmd(drive, stat, ide_read_error(drive));
	else if (tf->command == ATA_CMD_SET_MULTI)
		drive->mult_count = drive->mult_req;

	return ide_stopped;
}
+106 −105
Original line number Diff line number Diff line
@@ -282,6 +282,110 @@ typedef enum {
	ide_started,	/* a drive operation was started, handler was set */
} ide_startstop_t;

enum {
	IDE_TFLAG_LBA48			= (1 << 0),
	IDE_TFLAG_FLAGGED		= (1 << 2),
	IDE_TFLAG_OUT_DATA		= (1 << 3),
	IDE_TFLAG_OUT_HOB_FEATURE	= (1 << 4),
	IDE_TFLAG_OUT_HOB_NSECT		= (1 << 5),
	IDE_TFLAG_OUT_HOB_LBAL		= (1 << 6),
	IDE_TFLAG_OUT_HOB_LBAM		= (1 << 7),
	IDE_TFLAG_OUT_HOB_LBAH		= (1 << 8),
	IDE_TFLAG_OUT_HOB		= IDE_TFLAG_OUT_HOB_FEATURE |
					  IDE_TFLAG_OUT_HOB_NSECT |
					  IDE_TFLAG_OUT_HOB_LBAL |
					  IDE_TFLAG_OUT_HOB_LBAM |
					  IDE_TFLAG_OUT_HOB_LBAH,
	IDE_TFLAG_OUT_FEATURE		= (1 << 9),
	IDE_TFLAG_OUT_NSECT		= (1 << 10),
	IDE_TFLAG_OUT_LBAL		= (1 << 11),
	IDE_TFLAG_OUT_LBAM		= (1 << 12),
	IDE_TFLAG_OUT_LBAH		= (1 << 13),
	IDE_TFLAG_OUT_TF		= IDE_TFLAG_OUT_FEATURE |
					  IDE_TFLAG_OUT_NSECT |
					  IDE_TFLAG_OUT_LBAL |
					  IDE_TFLAG_OUT_LBAM |
					  IDE_TFLAG_OUT_LBAH,
	IDE_TFLAG_OUT_DEVICE		= (1 << 14),
	IDE_TFLAG_WRITE			= (1 << 15),
	IDE_TFLAG_FLAGGED_SET_IN_FLAGS	= (1 << 16),
	IDE_TFLAG_IN_DATA		= (1 << 17),
	IDE_TFLAG_CUSTOM_HANDLER	= (1 << 18),
	IDE_TFLAG_DMA_PIO_FALLBACK	= (1 << 19),
	IDE_TFLAG_IN_HOB_FEATURE	= (1 << 20),
	IDE_TFLAG_IN_HOB_NSECT		= (1 << 21),
	IDE_TFLAG_IN_HOB_LBAL		= (1 << 22),
	IDE_TFLAG_IN_HOB_LBAM		= (1 << 23),
	IDE_TFLAG_IN_HOB_LBAH		= (1 << 24),
	IDE_TFLAG_IN_HOB_LBA		= IDE_TFLAG_IN_HOB_LBAL |
					  IDE_TFLAG_IN_HOB_LBAM |
					  IDE_TFLAG_IN_HOB_LBAH,
	IDE_TFLAG_IN_HOB		= IDE_TFLAG_IN_HOB_FEATURE |
					  IDE_TFLAG_IN_HOB_NSECT |
					  IDE_TFLAG_IN_HOB_LBA,
	IDE_TFLAG_IN_FEATURE		= (1 << 1),
	IDE_TFLAG_IN_NSECT		= (1 << 25),
	IDE_TFLAG_IN_LBAL		= (1 << 26),
	IDE_TFLAG_IN_LBAM		= (1 << 27),
	IDE_TFLAG_IN_LBAH		= (1 << 28),
	IDE_TFLAG_IN_LBA		= IDE_TFLAG_IN_LBAL |
					  IDE_TFLAG_IN_LBAM |
					  IDE_TFLAG_IN_LBAH,
	IDE_TFLAG_IN_TF			= IDE_TFLAG_IN_NSECT |
					  IDE_TFLAG_IN_LBA,
	IDE_TFLAG_IN_DEVICE		= (1 << 29),
	IDE_TFLAG_HOB			= IDE_TFLAG_OUT_HOB |
					  IDE_TFLAG_IN_HOB,
	IDE_TFLAG_TF			= IDE_TFLAG_OUT_TF |
					  IDE_TFLAG_IN_TF,
	IDE_TFLAG_DEVICE		= IDE_TFLAG_OUT_DEVICE |
					  IDE_TFLAG_IN_DEVICE,
	/* force 16-bit I/O operations */
	IDE_TFLAG_IO_16BIT		= (1 << 30),
	/* ide_task_t was allocated using kmalloc() */
	IDE_TFLAG_DYN			= (1 << 31),
};

struct ide_taskfile {
	u8	hob_data;	/*  0: high data byte (for TASKFILE IOCTL) */

	u8	hob_feature;	/*  1-5: additional data to support LBA48 */
	u8	hob_nsect;
	u8	hob_lbal;
	u8	hob_lbam;
	u8	hob_lbah;

	u8	data;		/*  6: low data byte (for TASKFILE IOCTL) */

	union {			/*  7: */
		u8 error;	/*   read:  error */
		u8 feature;	/*  write: feature */
	};

	u8	nsect;		/*  8: number of sectors */
	u8	lbal;		/*  9: LBA low */
	u8	lbam;		/* 10: LBA mid */
	u8	lbah;		/* 11: LBA high */

	u8	device;		/* 12: device select */

	union {			/* 13: */
		u8 status;	/*  read: status  */
		u8 command;	/* write: command */
	};
};

typedef struct ide_task_s {
	union {
		struct ide_taskfile	tf;
		u8			tf_array[14];
	};
	u32			tf_flags;
	int			data_phase;
	struct request		*rq;		/* copy of request */
	void			*special;	/* valid_t generally */
} ide_task_t;

/* ATAPI packet command flags */
enum {
	/* set when an error is considered normal - no retry (ide-tape) */
@@ -567,7 +671,6 @@ typedef struct ide_drive_s ide_drive_t;
#define ide_drv_g(disk, cont_type)	\
	container_of((disk)->private_data, struct cont_type, driver)

struct ide_task_s;
struct ide_port_info;

struct ide_tp_ops {
@@ -694,6 +797,8 @@ typedef struct hwif_s {
	/* data phase of the active command (currently only valid for PIO/DMA) */
	int		data_phase;

	struct ide_task_s task;		/* current command */

	unsigned int nsect;
	unsigned int nleft;
	struct scatterlist *cursg;
@@ -1059,110 +1164,6 @@ extern void ide_do_drive_cmd(ide_drive_t *, struct request *);

extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);

enum {
	IDE_TFLAG_LBA48			= (1 << 0),
	IDE_TFLAG_FLAGGED		= (1 << 2),
	IDE_TFLAG_OUT_DATA		= (1 << 3),
	IDE_TFLAG_OUT_HOB_FEATURE	= (1 << 4),
	IDE_TFLAG_OUT_HOB_NSECT		= (1 << 5),
	IDE_TFLAG_OUT_HOB_LBAL		= (1 << 6),
	IDE_TFLAG_OUT_HOB_LBAM		= (1 << 7),
	IDE_TFLAG_OUT_HOB_LBAH		= (1 << 8),
	IDE_TFLAG_OUT_HOB		= IDE_TFLAG_OUT_HOB_FEATURE |
					  IDE_TFLAG_OUT_HOB_NSECT |
					  IDE_TFLAG_OUT_HOB_LBAL |
					  IDE_TFLAG_OUT_HOB_LBAM |
					  IDE_TFLAG_OUT_HOB_LBAH,
	IDE_TFLAG_OUT_FEATURE		= (1 << 9),
	IDE_TFLAG_OUT_NSECT		= (1 << 10),
	IDE_TFLAG_OUT_LBAL		= (1 << 11),
	IDE_TFLAG_OUT_LBAM		= (1 << 12),
	IDE_TFLAG_OUT_LBAH		= (1 << 13),
	IDE_TFLAG_OUT_TF		= IDE_TFLAG_OUT_FEATURE |
					  IDE_TFLAG_OUT_NSECT |
					  IDE_TFLAG_OUT_LBAL |
					  IDE_TFLAG_OUT_LBAM |
					  IDE_TFLAG_OUT_LBAH,
	IDE_TFLAG_OUT_DEVICE		= (1 << 14),
	IDE_TFLAG_WRITE			= (1 << 15),
	IDE_TFLAG_FLAGGED_SET_IN_FLAGS	= (1 << 16),
	IDE_TFLAG_IN_DATA		= (1 << 17),
	IDE_TFLAG_CUSTOM_HANDLER	= (1 << 18),
	IDE_TFLAG_DMA_PIO_FALLBACK	= (1 << 19),
	IDE_TFLAG_IN_HOB_FEATURE	= (1 << 20),
	IDE_TFLAG_IN_HOB_NSECT		= (1 << 21),
	IDE_TFLAG_IN_HOB_LBAL		= (1 << 22),
	IDE_TFLAG_IN_HOB_LBAM		= (1 << 23),
	IDE_TFLAG_IN_HOB_LBAH		= (1 << 24),
	IDE_TFLAG_IN_HOB_LBA		= IDE_TFLAG_IN_HOB_LBAL |
					  IDE_TFLAG_IN_HOB_LBAM |
					  IDE_TFLAG_IN_HOB_LBAH,
	IDE_TFLAG_IN_HOB		= IDE_TFLAG_IN_HOB_FEATURE |
					  IDE_TFLAG_IN_HOB_NSECT |
					  IDE_TFLAG_IN_HOB_LBA,
	IDE_TFLAG_IN_FEATURE		= (1 << 1),
	IDE_TFLAG_IN_NSECT		= (1 << 25),
	IDE_TFLAG_IN_LBAL		= (1 << 26),
	IDE_TFLAG_IN_LBAM		= (1 << 27),
	IDE_TFLAG_IN_LBAH		= (1 << 28),
	IDE_TFLAG_IN_LBA		= IDE_TFLAG_IN_LBAL |
					  IDE_TFLAG_IN_LBAM |
					  IDE_TFLAG_IN_LBAH,
	IDE_TFLAG_IN_TF			= IDE_TFLAG_IN_NSECT |
					  IDE_TFLAG_IN_LBA,
	IDE_TFLAG_IN_DEVICE		= (1 << 29),
	IDE_TFLAG_HOB			= IDE_TFLAG_OUT_HOB |
					  IDE_TFLAG_IN_HOB,
	IDE_TFLAG_TF			= IDE_TFLAG_OUT_TF |
					  IDE_TFLAG_IN_TF,
	IDE_TFLAG_DEVICE		= IDE_TFLAG_OUT_DEVICE |
					  IDE_TFLAG_IN_DEVICE,
	/* force 16-bit I/O operations */
	IDE_TFLAG_IO_16BIT		= (1 << 30),
	/* ide_task_t was allocated using kmalloc() */
	IDE_TFLAG_DYN			= (1 << 31),
};

struct ide_taskfile {
	u8	hob_data;	/*  0: high data byte (for TASKFILE IOCTL) */

	u8	hob_feature;	/*  1-5: additional data to support LBA48 */
	u8	hob_nsect;
	u8	hob_lbal;
	u8	hob_lbam;
	u8	hob_lbah;

	u8	data;		/*  6: low data byte (for TASKFILE IOCTL) */

	union {			/*  7: */
		u8 error;	/*   read:  error */
		u8 feature;	/*  write: feature */
	};

	u8	nsect;		/*  8: number of sectors */
	u8	lbal;		/*  9: LBA low */
	u8	lbam;		/* 10: LBA mid */
	u8	lbah;		/* 11: LBA high */

	u8	device;		/* 12: device select */

	union {			/* 13: */
		u8 status;	/*  read: status  */
		u8 command;	/* write: command */
	};
};

typedef struct ide_task_s {
	union {
		struct ide_taskfile	tf;
		u8			tf_array[14];
	};
	u32			tf_flags;
	int			data_phase;
	struct request		*rq;		/* copy of request */
	void			*special;	/* valid_t generally */
} ide_task_t;

void ide_tf_dump(const char *, struct ide_taskfile *);

void ide_exec_command(ide_hwif_t *, u8);