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

Commit 594c16d8 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

ide: add ide_transfer_pc() helper



* Add ide-atapi.c file for generic ATAPI support together with
  CONFIG_IDE_ATAPI config option.

* Add generic ide_transfer_pc() helper to ide-atapi.c and then
  convert ide-{floppy,tape,scsi} device drivers to use it.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent f83cbc77
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -98,6 +98,9 @@ if BLK_DEV_IDE

comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"

config IDE_ATAPI
	bool

config BLK_DEV_IDE_SATA
	bool "Support for SATA (deprecated; conflicts with libata SATA driver)"
	default n
@@ -201,6 +204,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS

config BLK_DEV_IDETAPE
	tristate "Include IDE/ATAPI TAPE support"
	select IDE_ATAPI
	help
	  If you have an IDE tape drive using the ATAPI protocol, say Y.
	  ATAPI is a newer protocol used by IDE tape and CD-ROM drives,
@@ -223,6 +227,7 @@ config BLK_DEV_IDETAPE

config BLK_DEV_IDEFLOPPY
	tristate "Include IDE/ATAPI FLOPPY support"
	select IDE_ATAPI
	---help---
	  If you have an IDE floppy drive which uses the ATAPI protocol,
	  answer Y.  ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy
@@ -246,6 +251,7 @@ config BLK_DEV_IDEFLOPPY
config BLK_DEV_IDESCSI
	tristate "SCSI emulation support"
	depends on SCSI
	select IDE_ATAPI
	---help---
	  WARNING: ide-scsi is no longer needed for cd writing applications!
	  The 2.6 kernel supports direct writing to ide-cd, which eliminates
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o

# core IDE code
ide-core-$(CONFIG_IDE_ATAPI)		+= ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
ide-core-$(CONFIG_IDE_PROC_FS)		+= ide-proc.o
+70 −0
Original line number Diff line number Diff line
/*
 * ATAPI support.
 */

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>

static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
{
	ide_hwif_t *hwif = drive->hwif;
	int retries = 100;

	while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
		printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
				"a packet command, retrying\n", drive->name);
		udelay(100);
		ireason = hwif->INB(hwif->io_ports.nsect_addr);
		if (retries == 0) {
			printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
					"a packet command, ignoring\n",
					drive->name);
			ireason |= CD;
			ireason &= ~IO;
		}
	}

	return ireason;
}

ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
				ide_handler_t *handler, unsigned int timeout,
				ide_expiry_t *expiry)
{
	ide_hwif_t *hwif = drive->hwif;
	ide_startstop_t startstop;
	u8 ireason;

	if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
		printk(KERN_ERR "%s: Strange, packet command initiated yet "
				"DRQ isn't asserted\n", drive->name);
		return startstop;
	}

	ireason = hwif->INB(hwif->io_ports.nsect_addr);
	if (drive->media == ide_tape && !drive->scsi)
		ireason = ide_wait_ireason(drive, ireason);

	if ((ireason & CD) == 0 || (ireason & IO)) {
		printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
				"a packet command\n", drive->name);
		return ide_do_reset(drive);
	}

	/* Set the interrupt routine */
	ide_set_handler(drive, handler, timeout, expiry);

	/* Begin DMA, if necessary */
	if (pc->flags & PC_FLAG_DMA_OK) {
		pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
		hwif->dma_ops->dma_start(drive);
	}

	/* Send the actual packet */
	if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0)
		hwif->output_data(drive, NULL, pc->c, 12);

	return ide_started;
}
EXPORT_SYMBOL_GPL(ide_transfer_pc);
+1 −27
Original line number Diff line number Diff line
@@ -532,25 +532,11 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive)

static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	idefloppy_floppy_t *floppy = drive->driver_data;
	struct ide_atapi_pc *pc = floppy->pc;
	ide_expiry_t *expiry;
	unsigned int timeout;
	ide_startstop_t startstop;
	u8 ireason;

	if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
		printk(KERN_ERR "%s: Strange, packet command initiated yet "
				"DRQ isn't asserted\n", drive->name);
		return startstop;
	}
	ireason = hwif->INB(hwif->io_ports.nsect_addr);
	if ((ireason & CD) == 0 || (ireason & IO)) {
		printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
				"a packet command\n", drive->name);
		return ide_do_reset(drive);
	}
	/*
	 * The following delay solves a problem with ATAPI Zip 100 drives
	 * where the Busy flag was apparently being deasserted before the
@@ -567,19 +553,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
		expiry = NULL;
	}

	ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry);

	/* Begin DMA, if necessary */
	if (pc->flags & PC_FLAG_DMA_OK) {
		pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
		hwif->dma_ops->dma_start(drive);
	}

	if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0)
		/* Send the actual packet */
		hwif->output_data(drive, NULL, floppy->pc->c, 12);

	return ide_started;
	return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry);
}

static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
+2 −54
Original line number Diff line number Diff line
@@ -947,64 +947,12 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
 * again, the callback function will be called and then we will handle the next
 * request.
 */

static u8 ide_tape_wait_ireason(ide_drive_t *drive, u8 ireason)
{
	ide_hwif_t *hwif = drive->hwif;
	int retries = 100;

	while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
		printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
				"a packet command, retrying\n", drive->name);
		udelay(100);
		ireason = hwif->INB(hwif->io_ports.nsect_addr);
		if (retries == 0) {
			printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
					"a packet command, ignoring\n",
					drive->name);
			ireason |= CD;
			ireason &= ~IO;
		}
	}

	return ireason;
}

static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	idetape_tape_t *tape = drive->driver_data;
	struct ide_atapi_pc *pc = tape->pc;
	ide_startstop_t startstop;
	u8 ireason;

	if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
		printk(KERN_ERR "%s: Strange, packet command initiated yet "
				"DRQ isn't asserted\n", drive->name);
		return startstop;
	}

	ireason = hwif->INB(hwif->io_ports.nsect_addr);
	ireason = ide_tape_wait_ireason(drive, ireason);

	if ((ireason & CD) == 0 || (ireason & IO)) {
		printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
				"a packet command\n", drive->name);
		return ide_do_reset(drive);
	}
	/* Set the interrupt routine */
	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);

	/* Begin DMA, if necessary */
	if (pc->flags & PC_FLAG_DMA_OK) {
		pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
		hwif->dma_ops->dma_start(drive);
	}

	/* Send the actual packet */
	hwif->output_data(drive, NULL, pc->c, 12);

	return ide_started;
	return ide_transfer_pc(drive, tape->pc, idetape_pc_intr,
			       IDETAPE_WAIT_CMD, NULL);
}

static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
Loading