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 Original line 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"
comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"


config IDE_ATAPI
	bool

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


config BLK_DEV_IDETAPE
config BLK_DEV_IDETAPE
	tristate "Include IDE/ATAPI TAPE support"
	tristate "Include IDE/ATAPI TAPE support"
	select IDE_ATAPI
	help
	help
	  If you have an IDE tape drive using the ATAPI protocol, say Y.
	  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,
	  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
config BLK_DEV_IDEFLOPPY
	tristate "Include IDE/ATAPI FLOPPY support"
	tristate "Include IDE/ATAPI FLOPPY support"
	select IDE_ATAPI
	---help---
	---help---
	  If you have an IDE floppy drive which uses the ATAPI protocol,
	  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
	  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
config BLK_DEV_IDESCSI
	tristate "SCSI emulation support"
	tristate "SCSI emulation support"
	depends on SCSI
	depends on SCSI
	select IDE_ATAPI
	---help---
	---help---
	  WARNING: ide-scsi is no longer needed for cd writing applications!
	  WARNING: ide-scsi is no longer needed for cd writing applications!
	  The 2.6 kernel supports direct writing to ide-cd, which eliminates
	  The 2.6 kernel supports direct writing to ide-cd, which eliminates
+1 −0
Original line number Original line 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
ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o


# core IDE code
# 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_IDEPCI)	+= setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
ide-core-$(CONFIG_IDE_PROC_FS)		+= ide-proc.o
ide-core-$(CONFIG_IDE_PROC_FS)		+= ide-proc.o
+70 −0
Original line number Original line 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 Original line 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)
static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
{
{
	ide_hwif_t *hwif = drive->hwif;
	idefloppy_floppy_t *floppy = drive->driver_data;
	idefloppy_floppy_t *floppy = drive->driver_data;
	struct ide_atapi_pc *pc = floppy->pc;
	struct ide_atapi_pc *pc = floppy->pc;
	ide_expiry_t *expiry;
	ide_expiry_t *expiry;
	unsigned int timeout;
	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
	 * The following delay solves a problem with ATAPI Zip 100 drives
	 * where the Busy flag was apparently being deasserted before the
	 * 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;
		expiry = NULL;
	}
	}


	ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry);
	return ide_transfer_pc(drive, pc, 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;
}
}


static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
+2 −54
Original line number Original line 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
 * again, the callback function will be called and then we will handle the next
 * request.
 * 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)
static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
{
	ide_hwif_t *hwif = drive->hwif;
	idetape_tape_t *tape = drive->driver_data;
	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)) {
	return ide_transfer_pc(drive, tape->pc, idetape_pc_intr,
		printk(KERN_ERR "%s: Strange, packet command initiated yet "
			       IDETAPE_WAIT_CMD, NULL);
				"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;
}
}


static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
Loading