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

Commit 2640c9a9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (32 commits)
  ide-atapi: start dma in a drive-specific way
  ide-atapi: put the rest of non-ide-cd code into the else-clause of ide_transfer_pc
  ide-atapi: remove timeout arg to ide_issue_pc
  ide-cd: remove handler wrappers
  ide-cd: remove xferlen arg to cdrom_start_packet_command
  ide-atapi: split drive-specific functionality in ide_issue_pc
  ide-atapi: assign expiry and timeout based on device type
  ide-atapi: compute cmd_len based on device type in ide_transfer_pc
  ide: remove the last ide-scsi remnants
  ide-atapi: remove ide-scsi remnants from ide_pc_intr()
  ide-atapi: remove ide-scsi remnants from ide_transfer_pc()
  ide-atapi: remove ide-scsi remnants from ide_issue_pc
  ide-cd: move cdrom_timer_expiry to ide-atapi.c
  ide-atapi: teach ide atapi about drive->waiting_for_dma
  ide-atapi: accomodate transfer length calculation for ide-cd
  ide-atapi: setup dma for ide-cd
  ide-atapi: combine drive-specific assignments
  ide-atapi: add a dev_is_idecd-inline
  remove ide-scsi
  ide-floppy: allocate only toplevel packet commands
  ...
parents 80618fa8 b16aabc9
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -310,15 +310,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>

---------------------------

What: ide-scsi (BLK_DEV_IDESCSI)
When: 2.6.29
Why:  The 2.6 kernel supports direct writing to ide CD drives, which
      eliminates the need for ide-scsi. The new method is more
      efficient in every way.
Who:  FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>

---------------------------

What:	i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
When:	2.6.29 (ideally) or 2.6.30 (more likely)
Why:	Deprecated by the new (standard) device driver binding model. Use
+0 −5
Original line number Diff line number Diff line
@@ -2152,11 +2152,6 @@ M: Gadi Oxman <gadio@netvision.net.il>
L:	linux-kernel@vger.kernel.org
S:	Maintained

IDE-SCSI DRIVER
L:	linux-ide@vger.kernel.org
L:	linux-scsi@vger.kernel.org
S:	Orphan

IDLE-I7300
P:	Andy Henroid
M:	andrew.d.henroid@intel.com
+1 −17
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ config BLK_DEV_DELKIN

config BLK_DEV_IDECD
	tristate "Include IDE/ATAPI CDROM support"
	select IDE_ATAPI
	---help---
	  If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is
	  a newer protocol used by IDE CD-ROM and TAPE drives, similar to the
@@ -185,23 +186,6 @@ config BLK_DEV_IDETAPE
	  To compile this driver as a module, choose M here: the
	  module will be called ide-tape.

config BLK_DEV_IDESCSI
	tristate "SCSI emulation support (DEPRECATED)"
	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
	  the need for ide-scsi + the entire scsi stack just for writing a
	  cd. The new method is more efficient in every way.

	  This will provide SCSI host adapter emulation for IDE ATAPI devices,
	  and will allow you to use a SCSI device driver instead of a native
	  ATAPI driver.

	  If both this SCSI emulation and native ATAPI support are compiled
	  into the kernel, the native support will be used.

config BLK_DEV_IDEACPI
	bool "IDE ACPI support"
	depends on ACPI
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
EXTRA_CFLAGS				+= -Idrivers/ide

ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
	      ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o
	      ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o

# core IDE code
ide-core-$(CONFIG_IDE_TIMINGS)		+= ide-timings.o
+141 −107
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 */

#include <linux/kernel.h>
#include <linux/cdrom.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <scsi/scsi.h>
@@ -14,6 +15,13 @@
#define debug_log(fmt, args...) do {} while (0)
#endif

#define ATAPI_MIN_CDB_BYTES	12

static inline int dev_is_idecd(ide_drive_t *drive)
{
	return drive->media == ide_cdrom || drive->media == ide_optical;
}

/*
 * Check whether we can support a device,
 * based on the ATAPI IDENTIFY command results.
@@ -233,18 +241,49 @@ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
}
EXPORT_SYMBOL_GPL(ide_retry_pc);

int ide_scsi_expiry(ide_drive_t *drive)
int ide_cd_expiry(ide_drive_t *drive)
{
	struct ide_atapi_pc *pc = drive->pc;
	struct request *rq = HWGROUP(drive)->rq;
	unsigned long wait = 0;

	debug_log("%s called for %lu at %lu\n", __func__,
		  pc->scsi_cmd->serial_number, jiffies);
	debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]);

	pc->flags |= PC_FLAG_TIMEDOUT;
	/*
	 * Some commands are *slow* and normally take a long time to complete.
	 * Usually we can use the ATAPI "disconnect" to bypass this, but not all
	 * commands/drives support that. Let ide_timer_expiry keep polling us
	 * for these.
	 */
	switch (rq->cmd[0]) {
	case GPCMD_BLANK:
	case GPCMD_FORMAT_UNIT:
	case GPCMD_RESERVE_RZONE_TRACK:
	case GPCMD_CLOSE_TRACK:
	case GPCMD_FLUSH_CACHE:
		wait = ATAPI_WAIT_PC;
		break;
	default:
		if (!(rq->cmd_flags & REQ_QUIET))
			printk(KERN_INFO "cmd 0x%x timed out\n",
					 rq->cmd[0]);
		wait = 0;
		break;
	}
	return wait;
}
EXPORT_SYMBOL_GPL(ide_cd_expiry);

	return 0; /* we do not want the IDE subsystem to retry */
int ide_cd_get_xferlen(struct request *rq)
{
	if (blk_fs_request(rq))
		return 32768;
	else if (blk_sense_request(rq) || blk_pc_request(rq) ||
			 rq->cmd_type == REQ_TYPE_ATA_PC)
		return rq->data_len;
	else
		return 0;
}
EXPORT_SYMBOL_GPL(ide_scsi_expiry);
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);

/*
 * This is the usual interrupt handler which will be called during a packet
@@ -258,21 +297,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
	struct request *rq = hwif->hwgroup->rq;
	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
	xfer_func_t *xferfunc;
	ide_expiry_t *expiry;
	unsigned int timeout, temp;
	u16 bcount;
	u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;
	u8 stat, ireason, dsc = 0;

	debug_log("Enter %s - interrupt handler\n", __func__);

	if (scsi) {
		timeout = ide_scsi_get_timeout(pc);
		expiry = ide_scsi_expiry;
	} else {
	timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
					       : WAIT_TAPE_CMD;
		expiry = NULL;
	}

	if (pc->flags & PC_FLAG_TIMEDOUT) {
		drive->pc_callback(drive, 0);
@@ -284,8 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)

	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
		if (hwif->dma_ops->dma_end(drive) ||
		    (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) {
			if (drive->media == ide_floppy && !scsi)
		    (drive->media == ide_tape && (stat & ATA_ERR))) {
			if (drive->media == ide_floppy)
				printk(KERN_ERR "%s: DMA %s error\n",
					drive->name, rq_data_dir(pc->rq)
						     ? "write" : "read");
@@ -307,7 +339,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)

		local_irq_enable_in_hardirq();

		if (drive->media == ide_tape && !scsi &&
		if (drive->media == ide_tape &&
		    (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE)
			stat &= ~ATA_ERR;

@@ -315,11 +347,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
			/* Error detected */
			debug_log("%s: I/O error\n", drive->name);

			if (drive->media != ide_tape || scsi) {
			if (drive->media != ide_tape)
				pc->rq->errors++;
				if (scsi)
					goto cmd_finished;
			}

			if (rq->cmd[0] == REQUEST_SENSE) {
				printk(KERN_ERR "%s: I/O error in request sense"
@@ -335,7 +364,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
			/* queued, but not started */
			return ide_stopped;
		}
cmd_finished:
		pc->error = 0;

		if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
@@ -382,25 +410,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
						"us more data than expected - "
						"discarding data\n",
						drive->name);
				if (scsi)
					temp = pc->buf_size - pc->xferred;
				else
					temp = 0;
				if (temp) {
					if (pc->sg)
						drive->pc_io_buffers(drive, pc,
								     temp, 0);
					else
						tp_ops->input_data(drive, NULL,
							pc->cur_pos, temp);
					printk(KERN_ERR "%s: transferred %d of "
							"%d bytes\n",
							drive->name,
							temp, bcount);
				}
				pc->xferred += temp;
				pc->cur_pos += temp;
				ide_pad_transfer(drive, 0, bcount - temp);

				ide_pad_transfer(drive, 0, bcount);
				goto next_irq;
			}
			debug_log("The device wants to send us more data than "
@@ -410,14 +421,13 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
	} else
		xferfunc = tp_ops->output_data;

	if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
	    (drive->media == ide_tape && !scsi && pc->bh) ||
	    (scsi && pc->sg)) {
	if ((drive->media == ide_floppy && !pc->buf) ||
	    (drive->media == ide_tape && pc->bh)) {
		int done = drive->pc_io_buffers(drive, pc, bcount,
				  !!(pc->flags & PC_FLAG_WRITING));

		/* FIXME: don't do partial completions */
		if (drive->media == ide_floppy && !scsi)
		if (drive->media == ide_floppy)
			ide_end_request(drive, 1, done >> 9);
	} else
		xferfunc(drive, NULL, pc->cur_pos, bcount);
@@ -430,7 +440,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
		  rq->cmd[0], bcount);
next_irq:
	/* And set the interrupt handler again */
	ide_set_handler(drive, ide_pc_intr, timeout, expiry);
	ide_set_handler(drive, ide_pc_intr, timeout, NULL);
	return ide_started;
}

@@ -479,11 +489,12 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive)

static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
{
	struct ide_atapi_pc *pc = drive->pc;
	struct ide_atapi_pc *uninitialized_var(pc);
	ide_hwif_t *hwif = drive->hwif;
	struct request *rq = hwif->hwgroup->rq;
	ide_expiry_t *expiry;
	unsigned int timeout;
	int cmd_len;
	ide_startstop_t startstop;
	u8 ireason;

@@ -493,70 +504,99 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
		return startstop;
	}

	ireason = ide_read_ireason(drive);
	if (drive->media == ide_tape &&
	    (drive->dev_flags & IDE_DFLAG_SCSI) == 0)
		ireason = ide_wait_ireason(drive, ireason);

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

	if (dev_is_idecd(drive)) {
		/* ATAPI commands get padded out to 12 bytes minimum */
		cmd_len = COMMAND_SIZE(rq->cmd[0]);
		if (cmd_len < ATAPI_MIN_CDB_BYTES)
			cmd_len = ATAPI_MIN_CDB_BYTES;

		timeout = rq->timeout;
		expiry  = ide_cd_expiry;
	} else {
		pc = drive->pc;

		cmd_len = ATAPI_MIN_CDB_BYTES;

		/*
		 * If necessary schedule the packet transfer to occur 'timeout'
	 * miliseconds later in ide_delayed_transfer_pc() after the device
	 * says it's ready for a packet.
		 * miliseconds later in ide_delayed_transfer_pc() after the
		 * device says it's ready for a packet.
		 */
		if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
			timeout = drive->pc_delay;
			expiry = &ide_delayed_transfer_pc;
	} else {
		if (drive->dev_flags & IDE_DFLAG_SCSI) {
			timeout = ide_scsi_get_timeout(pc);
			expiry = ide_scsi_expiry;
		} else {
			timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
							       : WAIT_TAPE_CMD;
			expiry = NULL;
		}

		ireason = ide_read_ireason(drive);
		if (drive->media == ide_tape)
			ireason = ide_wait_ireason(drive, ireason);

		if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_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, ide_pc_intr, timeout, expiry);

	/* Begin DMA, if necessary */
	if (dev_is_idecd(drive)) {
		if (drive->dma)
			hwif->dma_ops->dma_start(drive);
	} else {
		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 ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
		hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12);
		hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);

	return ide_started;
}

ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
			     ide_expiry_t *expiry)
ide_startstop_t ide_issue_pc(ide_drive_t *drive)
{
	struct ide_atapi_pc *pc = drive->pc;
	struct ide_atapi_pc *pc;
	ide_hwif_t *hwif = drive->hwif;
	ide_expiry_t *expiry = NULL;
	unsigned int timeout;
	u32 tf_flags;
	u16 bcount;
	u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI);

	if (dev_is_idecd(drive)) {
		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
		bcount = ide_cd_get_xferlen(hwif->hwgroup->rq);
		expiry = ide_cd_expiry;
		timeout = ATAPI_WAIT_PC;

		if (drive->dma)
			drive->dma = !hwif->dma_ops->dma_setup(drive);
	} else {
		pc = drive->pc;

		/* We haven't transferred any data yet */
		pc->xferred = 0;
		pc->cur_pos = pc->buf;

	/* Request to transfer the entire buffer at once */
	if (drive->media == ide_tape && scsi == 0)
		bcount = pc->req_xfer;
	else
		bcount = min(pc->req_xfer, 63 * 1024);
		tf_flags = IDE_TFLAG_OUT_DEVICE;
		bcount = ((drive->media == ide_tape) ?
				pc->req_xfer :
				min(pc->req_xfer, 63 * 1024));

		if (pc->flags & PC_FLAG_DMA_ERROR) {
			pc->flags &= ~PC_FLAG_DMA_ERROR;
@@ -564,30 +604,24 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
		}

		if ((pc->flags & PC_FLAG_DMA_OK) &&
	    (drive->dev_flags & IDE_DFLAG_USING_DMA)) {
		if (scsi)
			hwif->sg_mapped = 1;
		     (drive->dev_flags & IDE_DFLAG_USING_DMA))
			drive->dma = !hwif->dma_ops->dma_setup(drive);
		if (scsi)
			hwif->sg_mapped = 0;
	}

		if (!drive->dma)
			pc->flags &= ~PC_FLAG_DMA_OK;

	if (scsi)
		tf_flags = 0;
	else if (drive->media == ide_cdrom || drive->media == ide_optical)
		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
	else
		tf_flags = IDE_TFLAG_OUT_DEVICE;
		timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
						       : WAIT_TAPE_CMD;
	}

	ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);

	/* Issue the packet command */
	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
		if (drive->dma)
			drive->waiting_for_dma = 0;
		ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
				    timeout, NULL);
				    timeout, expiry);
		return ide_started;
	} else {
		ide_execute_pkt_cmd(drive);
Loading