From e8a96aa71355edef9f40ce01459acf25c50cb78c Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:41 +0200
Subject: ide: set REQ_PREEMPT request flag in ide_do_drive_cmd() users

* Set REQ_PREEMPT request flag in ide_do_drive_cmd() users
  for ide_preempt and ide_head_wait action types.

* Remove setting REQ_PREEMPT from ide_do_drive_cmd().

While at it:

* Set 'where' variable outside ide_lock.

This is a preparation for converting IDE to use blk_execute_rq().

There should be no functional changes caused by this patch.

Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Borislav Petkov <petkovbb@gmail.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 44d8d5163a1..89ecf013219 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -235,6 +235,7 @@ static int idescsi_check_condition(ide_drive_t *drive,
 	pc->c[0] = REQUEST_SENSE;
 	pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;
 	rq->cmd_type = REQ_TYPE_SENSE;
+	rq->cmd_flags |= REQ_PREEMPT;
 	pc->timeout = jiffies + WAIT_READY;
 	/* NOTE! Save the failed packet command in "rq->buffer" */
 	rq->buffer = (void *) failed_cmd->special;
-- 
cgit v1.2.3


From 124cafc5eb973e748c4ce3dc1caad29274e64613 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Date: Tue, 15 Jul 2008 21:21:44 +0200
Subject: ide: remove ide_init_drive_cmd

ide_init_drive_cmd just calls blk_rq_init. This converts the users of
ide_init_drive_cmd to use blk_rq_init directly and removes
ide_init_drive_cmd.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Borislav Petkov <petkovbb@gmail.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 89ecf013219..da261806d62 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -228,7 +228,7 @@ static int idescsi_check_condition(ide_drive_t *drive,
 		kfree(pc);
 		return -ENOMEM;
 	}
-	ide_init_drive_cmd(rq);
+	blk_rq_init(NULL, rq);
 	rq->special = (char *) pc;
 	pc->rq = rq;
 	pc->buf = buf;
@@ -786,7 +786,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
 		}
 	}
 
-	ide_init_drive_cmd (rq);
+	blk_rq_init(NULL, rq);
 	rq->special = (char *) pc;
 	rq->cmd_type = REQ_TYPE_SPECIAL;
 	spin_unlock_irq(host->host_lock);
-- 
cgit v1.2.3


From 9a410e79b552bacb4481f85618aa7333b7776ed7 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:48 +0200
Subject: ide: remove IDE_TFLAG_NO_SELECT_MASK taskfile flag

Always call SELECT_MASK(..., 0) in ide_tf_load() (needs to be done
to match ide_set_irq(..., 1)) and then remove IDE_TFLAG_NO_SELECT_MASK
taskfile flag.

This change should only affect hpt366 and icside host drivers since
->maskproc(..., 0) for sgiioc4 is equivalent to ide_set_irq(..., 1).

Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index da261806d62..3222aa589db 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -564,7 +564,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
 		hwif->sg_mapped = 0;
 	}
 
-	ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma);
+	ide_pktcmd_tf_load(drive, 0, bcount, dma);
 
 	if (dma)
 		pc->flags |= PC_FLAG_DMA_OK;
-- 
cgit v1.2.3


From f8c4bd0ab2b8783c0f080957781e9f70bee48eaa Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:49 +0200
Subject: ide: pass 'hwif *' instead of 'drive *' to ->OUTBSYNC method

There should be no functional changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 3222aa589db..d7fd5e550a2 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -257,7 +257,7 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 
 	if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
 		/* force an abort */
-		hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+		hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
 			       hwif->io_ports.command_addr);
 
 	rq->errors++;
-- 
cgit v1.2.3


From 7e12ca11d65f4cb29ed58ea3948f8c5d4f57b35e Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Date: Tue, 15 Jul 2008 21:21:50 +0200
Subject: ide-scsi: replace ide_do_drive_cmd with blk_execute_rq_nowait

All the callers of ide_do_drive_cmd() except for ide-scsi use
ide_preempt action argument. This converts ide-scsi to use
blk_execute_rq_nowait instead of ide_do_drive_cmd so that we can
remove the action argument in ide_do_drive_cmd and ide_action_t
typedef.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index d7fd5e550a2..58e30efe7a7 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -790,8 +790,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
 	rq->special = (char *) pc;
 	rq->cmd_type = REQ_TYPE_SPECIAL;
 	spin_unlock_irq(host->host_lock);
-	rq->rq_disk = scsi->disk;
-	(void) ide_do_drive_cmd (drive, rq, ide_end);
+	blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);
 	spin_lock_irq(host->host_lock);
 	return 0;
 abort:
-- 
cgit v1.2.3


From 63f5abb0959337db0d5bece9cefba03cdcadec51 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Date: Tue, 15 Jul 2008 21:21:51 +0200
Subject: ide: remove action argument in ide_do_drive_cmd

ide_do_drive_cmd is called only with ide_preempt action argument. So
we can remove the action argument in ide_do_drive_cmd and ide_action_t
typedef.

This patch also includes two minor cleanups: 1) ide_do_drive_cmd
always succeeds so we don't need the return value; 2) the callers use
blk_rq_init before ide_do_drive_cmd so there is no need to initialize
rq->errors.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 58e30efe7a7..569ffde6d04 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -245,7 +245,8 @@ static int idescsi_check_condition(ide_drive_t *drive,
 		ide_scsi_hex_dump(pc->c, 6);
 	}
 	rq->rq_disk = scsi->disk;
-	return ide_do_drive_cmd(drive, rq, ide_preempt);
+	ide_do_drive_cmd(drive, rq);
+	return 0;
 }
 
 static int idescsi_end_request(ide_drive_t *, int, int);
-- 
cgit v1.2.3


From b3d96afccf8b5c67b66a61efb88c53ff029c6611 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:51 +0200
Subject: ide-scsi: fix race in idescsi_transfer_pc()

Start DMA engine before sending content of packet command (otherwise
it is possible that IRQ will happen before DMA engine is started).

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 569ffde6d04..2553ef4d5a9 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -494,13 +494,14 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 	/* Set the interrupt routine */
 	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 
-	/* Send the actual packet */
-	hwif->output_data(drive, NULL, scsi->pc->c, 12);
-
 	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, scsi->pc->c, 12);
+
 	return ide_started;
 }
 
-- 
cgit v1.2.3


From e8e25f03e19c2c47834c821511625c0b80567827 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:51 +0200
Subject: ide-scsi: fix DRQ checking for DMA transfers in idescsi_pc_intr()

If DRQ bit of Status Register is not cleared it is an error condition
and should be handled accordingly (disable DMA + reset the device).

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 2553ef4d5a9..e67cf8aa946 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -388,7 +388,6 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		return ide_stopped;
 	}
 	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
-		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
 #if IDESCSI_DEBUG_LOG
 		printk ("ide-scsi: %s: DMA complete\n", drive->name);
 #endif /* IDESCSI_DEBUG_LOG */
@@ -404,12 +403,20 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
 			printk(KERN_INFO "Packet command completed, %d bytes"
 					" transferred\n", pc->xferred);
+		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
 		local_irq_enable_in_hardirq();
 		if (stat & ERR_STAT)
 			rq->errors++;
 		idescsi_end_request (drive, 1, 0);
 		return ide_stopped;
 	}
+	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
+		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
+		printk(KERN_ERR "%s: The device wants to issue more interrupts "
+				"in DMA mode\n", drive->name);
+		ide_dma_off(drive);
+		return ide_do_reset(drive);
+	}
 	bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
 		  hwif->INB(hwif->io_ports.lbam_addr);
 	ireason = hwif->INB(hwif->io_ports.nsect_addr);
-- 
cgit v1.2.3


From c04bbc812b05b304a9118687d0e0a47e35f00d1d Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:51 +0200
Subject: ide-scsi: fix handling of DMA errors in idescsi_pc_intr()

Check return value of ->dma_end method and if there was a DMA error
handle it accordingly (set PC_FLAG_DMA_ERROR pc flag, don't update
pc->xferred and increase rq->errors).

Also move debug message in the right place while at it.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index e67cf8aa946..ed92cf7a768 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -388,11 +388,13 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		return ide_stopped;
 	}
 	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
+		if (hwif->dma_ops->dma_end(drive))
+			pc->flags |= PC_FLAG_DMA_ERROR;
+		else
+			pc->xferred = pc->req_xfer;
 #if IDESCSI_DEBUG_LOG
 		printk ("ide-scsi: %s: DMA complete\n", drive->name);
 #endif /* IDESCSI_DEBUG_LOG */
-		pc->xferred = pc->req_xfer;
-		(void)hwif->dma_ops->dma_end(drive);
 	}
 
 	/* Clear the interrupt */
@@ -405,7 +407,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 					" transferred\n", pc->xferred);
 		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
 		local_irq_enable_in_hardirq();
-		if (stat & ERR_STAT)
+		if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR))
 			rq->errors++;
 		idescsi_end_request (drive, 1, 0);
 		return ide_stopped;
-- 
cgit v1.2.3


From 6c60bd8ea7aa536d67830bc8384ef0ebdfb8aad4 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:52 +0200
Subject: ide-scsi: fix Interrupt Reason checking in idescsi_pc_intr()

Set PC_FLAG_WRITING pc flag in idescsi_queue() (if needed)
and then fix Interrupt Reason checking in idescsi_pc_intr().

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index ed92cf7a768..08807070e08 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -427,7 +427,15 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
 		return ide_do_reset (drive);
 	}
-	if (ireason & IO) {
+	if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
+		/* Hopefully, we will never get here */
+		printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
+				"to %s!\n", drive->name,
+				(ireason & IO) ? "Write" : "Read",
+				(ireason & IO) ? "Read" : "Write");
+		return ide_do_reset(drive);
+	}
+	if (!(pc->flags & PC_FLAG_WRITING)) {
 		temp = pc->xferred + bcount;
 		if (temp > pc->req_xfer) {
 			if (temp > pc->buf_size) {
@@ -436,7 +444,6 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 					"- discarding data\n");
 				temp = pc->buf_size - pc->xferred;
 				if (temp) {
-					pc->flags &= ~PC_FLAG_WRITING;
 					if (pc->sg)
 						idescsi_input_buffers(drive, pc,
 									temp);
@@ -457,15 +464,11 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 			printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
 #endif /* IDESCSI_DEBUG_LOG */
 		}
-	}
-	if (ireason & IO) {
-		pc->flags &= ~PC_FLAG_WRITING;
 		if (pc->sg)
 			idescsi_input_buffers(drive, pc, bcount);
 		else
 			hwif->input_data(drive, NULL, pc->cur_pos, bcount);
 	} else {
-		pc->flags |= PC_FLAG_WRITING;
 		if (pc->sg)
 			idescsi_output_buffers(drive, pc, bcount);
 		else
@@ -777,6 +780,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
 
 	memset (pc->c, 0, 12);
 	pc->flags = 0;
+	if (cmd->sc_data_direction == DMA_TO_DEVICE)
+		pc->flags |= PC_FLAG_WRITING;
 	pc->rq = rq;
 	memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
 	pc->buf = NULL;
-- 
cgit v1.2.3


From 3e52fb4d1f4cc9630422982b6c5fa571e30f9889 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:52 +0200
Subject: ide-scsi: merge idescsi_input_buffers() and idescsi_output_buffers()

* Merge idescsi_input_buffers() and idescsi_output_buffers()
  into ide_scsi_io_buffers() helper.

While at it:

* Log device name instead of driver name on error.

* Use xfer_func_t.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 81 +++++++++++++++----------------------------------
 1 file changed, 24 insertions(+), 57 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 08807070e08..36c2c3bf111 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -129,51 +129,15 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
 #define IDESCSI_PC_RQ			90
 
 /*
- *	PIO data transfer routines using the scatter gather table.
+ *	PIO data transfer routine using the scatter gather table.
  */
-static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
-		unsigned int bcount)
+static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+				unsigned int bcount, int write)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	int count;
+	xfer_func_t *xf = write ? hwif->output_data : hwif->input_data;
 	char *buf;
-
-	while (bcount) {
-		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(sg_page(pc->sg))) {
-			unsigned long flags;
-
-			local_irq_save(flags);
-			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
-					pc->sg->offset;
-			hwif->input_data(drive, NULL, buf + pc->b_count, count);
-			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
-			local_irq_restore(flags);
-		} else {
-			buf = sg_virt(pc->sg);
-			hwif->input_data(drive, NULL, buf + pc->b_count, count);
-		}
-		bcount -= count; pc->b_count += count;
-		if (pc->b_count == pc->sg->length) {
-			if (!--pc->sg_cnt)
-				break;
-			pc->sg = sg_next(pc->sg);
-			pc->b_count = 0;
-		}
-	}
-
-	if (bcount) {
-		printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
-		ide_pad_transfer(drive, 0, bcount);
-	}
-}
-
-static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
-		unsigned int bcount)
-{
-	ide_hwif_t *hwif = drive->hwif;
 	int count;
-	char *buf;
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
@@ -182,13 +146,13 @@ static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
 
 			local_irq_save(flags);
 			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
-						pc->sg->offset;
-			hwif->output_data(drive, NULL, buf + pc->b_count, count);
+					  pc->sg->offset;
+			xf(drive, NULL, buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
 			buf = sg_virt(pc->sg);
-			hwif->output_data(drive, NULL, buf + pc->b_count, count);
+			xf(drive, NULL, buf + pc->b_count, count);
 		}
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
@@ -200,8 +164,10 @@ static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
 	}
 
 	if (bcount) {
-		printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
-		ide_pad_transfer(drive, 1, bcount);
+		printk(KERN_ERR "%s: scatter gather table too small, %s\n",
+				drive->name, write ? "padding with zeros"
+						   : "discarding data");
+		ide_pad_transfer(drive, write, bcount);
 	}
 }
 
@@ -370,6 +336,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 	ide_hwif_t *hwif = drive->hwif;
 	struct ide_atapi_pc *pc = scsi->pc;
 	struct request *rq = pc->rq;
+	xfer_func_t *xferfunc;
 	unsigned int temp;
 	u16 bcount;
 	u8 stat, ireason;
@@ -445,8 +412,8 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 				temp = pc->buf_size - pc->xferred;
 				if (temp) {
 					if (pc->sg)
-						idescsi_input_buffers(drive, pc,
-									temp);
+						ide_scsi_io_buffers(drive, pc,
+								    temp, 0);
 					else
 						hwif->input_data(drive, NULL,
 							pc->cur_pos, temp);
@@ -464,16 +431,16 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 			printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
 #endif /* IDESCSI_DEBUG_LOG */
 		}
-		if (pc->sg)
-			idescsi_input_buffers(drive, pc, bcount);
-		else
-			hwif->input_data(drive, NULL, pc->cur_pos, bcount);
-	} else {
-		if (pc->sg)
-			idescsi_output_buffers(drive, pc, bcount);
-		else
-			hwif->output_data(drive, NULL, pc->cur_pos, bcount);
-	}
+		xferfunc = hwif->input_data;
+	} else
+		xferfunc = hwif->output_data;
+
+	if (pc->sg)
+		ide_scsi_io_buffers(drive, pc, bcount,
+				    !!(pc->flags & PC_FLAG_WRITING));
+	else
+		xferfunc(drive, NULL, pc->cur_pos, bcount);
+
 	/* Update the current position */
 	pc->xferred += bcount;
 	pc->cur_pos += bcount;
-- 
cgit v1.2.3


From c8c51129805c0efb32f34afd3af8fe94f5757363 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:52 +0200
Subject: ide-scsi: remove superfluous BUG_ON() from idescsi_transfer_pc()

ide_set_handler() bugs on ->handler == NULL so no need to do it
in idescsi_transfer_pc().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 36c2c3bf111..e9d3dbf596c 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -469,7 +469,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 				"issuing a packet command\n");
 		return ide_do_reset (drive);
 	}
-	BUG_ON(HWGROUP(drive)->handler != NULL);
+
 	/* Set the interrupt routine */
 	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 
-- 
cgit v1.2.3


From 43a2b5b29385a3e0997a47c86f286d3645e5cb44 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:52 +0200
Subject: ide-scsi: add debug_log() macro

Add debug_log() macro and convert the driver to use it.

[ This makes debug messages to be always prefixed with "ide-scsi: "
  and use KERN_INFO level. ]

While at it:

* Change "DMA complete" debug message to "DMA finished" to match
  other ATAPI device drivers.

* Use __func__.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 51 ++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index e9d3dbf596c..d2dad9039e0 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -60,6 +60,13 @@
 
 #define IDESCSI_DEBUG_LOG		0
 
+#if IDESCSI_DEBUG_LOG
+#define debug_log(fmt, args...) \
+	printk(KERN_INFO "ide-scsi: " fmt, ## args)
+#else
+#define debug_log(fmt, args...) do {} while (0)
+#endif
+
 /*
  *	SCSI command transformation layer
  */
@@ -237,10 +244,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 static ide_startstop_t
 idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
 {
-#if IDESCSI_DEBUG_LOG
-	printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
+	debug_log("%s called for %lu\n", __func__,
 		((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number);
-#endif
+
 	rq->errors |= ERROR_MAX;
 
 	idescsi_end_request(drive, 0, 0);
@@ -319,9 +325,9 @@ static int idescsi_expiry(ide_drive_t *drive)
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	struct ide_atapi_pc   *pc   = scsi->pc;
 
-#if IDESCSI_DEBUG_LOG
-	printk(KERN_WARNING "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies);
-#endif
+	debug_log("%s called for %lu at %lu\n", __func__,
+		  pc->scsi_cmd->serial_number, jiffies);
+
 	pc->flags |= PC_FLAG_TIMEDOUT;
 
 	return 0;					/* we do not want the ide subsystem to retry */
@@ -341,15 +347,11 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 	u16 bcount;
 	u8 stat, ireason;
 
-#if IDESCSI_DEBUG_LOG
-	printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
-#endif /* IDESCSI_DEBUG_LOG */
+	debug_log("Reached %s interrupt handler\n", __func__);
 
 	if (pc->flags & PC_FLAG_TIMEDOUT) {
-#if IDESCSI_DEBUG_LOG
-		printk(KERN_WARNING "idescsi_pc_intr: got timed out packet  %lu at %lu\n",
-				pc->scsi_cmd->serial_number, jiffies);
-#endif
+		debug_log("%s: got timed out packet %lu at %lu\n", __func__,
+			  pc->scsi_cmd->serial_number, jiffies);
 		/* end this request now - scsi should retry it*/
 		idescsi_end_request (drive, 1, 0);
 		return ide_stopped;
@@ -359,9 +361,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 			pc->flags |= PC_FLAG_DMA_ERROR;
 		else
 			pc->xferred = pc->req_xfer;
-#if IDESCSI_DEBUG_LOG
-		printk ("ide-scsi: %s: DMA complete\n", drive->name);
-#endif /* IDESCSI_DEBUG_LOG */
+		debug_log("%s: DMA finished\n", drive->name);
 	}
 
 	/* Clear the interrupt */
@@ -427,9 +427,8 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 				return ide_started;
 			}
-#if IDESCSI_DEBUG_LOG
-			printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
-#endif /* IDESCSI_DEBUG_LOG */
+			debug_log("The scsi wants to send us more data than "
+				  "expected - allowing transfer\n");
 		}
 		xferfunc = hwif->input_data;
 	} else
@@ -566,10 +565,10 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
  */
 static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
 {
-#if IDESCSI_DEBUG_LOG
-	printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors);
-	printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
-#endif /* IDESCSI_DEBUG_LOG */
+	debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,
+		  rq->cmd[0], rq->errors);
+	debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",
+		  rq->sector, rq->nr_sectors, rq->current_nr_sectors);
 
 	if (blk_sense_request(rq) || blk_special_request(rq)) {
 		return idescsi_issue_pc(drive,
@@ -976,10 +975,10 @@ static int ide_scsi_probe(ide_drive_t *drive)
 
 	host->max_id = 1;
 
-#if IDESCSI_DEBUG_LOG
 	if (drive->id->last_lun)
-		printk(KERN_NOTICE "%s: id->last_lun=%u\n", drive->name, drive->id->last_lun);
-#endif
+		debug_log("%s: id->last_lun=%u\n", drive->name,
+			  drive->id->last_lun);
+
 	if ((drive->id->last_lun & 0x7) != 7)
 		host->max_lun = (drive->id->last_lun & 0x7) + 1;
 	else
-- 
cgit v1.2.3


From 568ca92774d2f6be4a7e2f8357559bfdc9424056 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:54 +0200
Subject: ide-{floppy,tape,scsi}: log device name instead of driver name

Log device name instead of driver name in *_pc_intr() and *_transfer_pc*().

While at it:

* Merge two consecutive printk()-s in *_pc_intr() together.

* Replace "floppy"/"tape"/"scsi" references in printk()-s by "device".

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index d2dad9039e0..5b8a1931ac9 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -391,7 +391,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 	ireason = hwif->INB(hwif->io_ports.nsect_addr);
 
 	if (ireason & CD) {
-		printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
+		printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
 		return ide_do_reset (drive);
 	}
 	if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
@@ -406,9 +406,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		temp = pc->xferred + bcount;
 		if (temp > pc->req_xfer) {
 			if (temp > pc->buf_size) {
-				printk(KERN_ERR "ide-scsi: The scsi wants to "
-					"send us more data than expected "
-					"- discarding data\n");
+				printk(KERN_ERR "%s: The device wants to send "
+						"us more data than expected - "
+						"discarding data\n",
+						drive->name);
 				temp = pc->buf_size - pc->xferred;
 				if (temp) {
 					if (pc->sg)
@@ -417,8 +418,9 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 					else
 						hwif->input_data(drive, NULL,
 							pc->cur_pos, temp);
-					printk(KERN_ERR "ide-scsi: transferred"
-							" %d of %d bytes\n",
+					printk(KERN_ERR "%s: transferred %d of "
+							"%d bytes\n",
+							drive->name,
 							temp, bcount);
 				}
 				pc->xferred += temp;
@@ -427,7 +429,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 				return ide_started;
 			}
-			debug_log("The scsi wants to send us more data than "
+			debug_log("The device wants to send us more data than "
 				  "expected - allowing transfer\n");
 		}
 		xferfunc = hwif->input_data;
@@ -458,14 +460,14 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 	u8 ireason;
 
 	if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
-		printk(KERN_ERR "ide-scsi: Strange, packet command "
-			"initiated yet DRQ isn't asserted\n");
+		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 "ide-scsi: (IO,CoD) != (0,1) while "
-				"issuing a packet command\n");
+		printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
+				"a packet command\n", drive->name);
 		return ide_do_reset (drive);
 	}
 
-- 
cgit v1.2.3


From f83cbc77b0d5521b4f0f591ede4870316944481a Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:58 +0200
Subject: ide-scsi: set drive->scsi flag for devices handled by the driver

This is a preparation for adding generic ide_transfer_pc() helper.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 5b8a1931ac9..c9fdf60c9dc 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -629,6 +629,8 @@ static void ide_scsi_remove(ide_drive_t *drive)
 	put_disk(g);
 
 	ide_scsi_put(scsi);
+
+	drive->scsi = 0;
 }
 
 static int ide_scsi_probe(ide_drive_t *);
@@ -969,6 +971,8 @@ static int ide_scsi_probe(ide_drive_t *drive)
 	    !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
 		return -ENODEV;
 
+	drive->scsi = 1;
+
 	g = alloc_disk(1 << PARTN_BITS);
 	if (!g)
 		goto out_host_put;
@@ -1009,6 +1013,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
 
 	put_disk(g);
 out_host_put:
+	drive->scsi = 0;
 	scsi_host_put(host);
 	return err;
 }
-- 
cgit v1.2.3


From 594c16d8dd54cd7b1c5ef1ec3ac0f6bf34301dad Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:58 +0200
Subject: 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: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 30 ++----------------------------
 1 file changed, 2 insertions(+), 28 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index c9fdf60c9dc..d41348f2245 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -453,36 +453,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 
 static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-	struct ide_atapi_pc *pc = scsi->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);
-	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, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
-
-	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, scsi->pc->c, 12);
-
-	return ide_started;
+	return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr,
+			       get_timeout(scsi->pc), idescsi_expiry);
 }
 
 static inline int idescsi_set_direction(struct ide_atapi_pc *pc)
-- 
cgit v1.2.3


From 4cc196897de9e6c02cf86debc5b9f7cf1b69a214 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:58 +0200
Subject: ide-scsi: move idescsi_map_sg() call out from idescsi_issue_pc()

Move idescsi_map_sg() call out from idescsi_issue_pc()
to idescsi_do_request() as a preparation to adding generic
ide_issue_pc() helper.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index d41348f2245..1d261298d61 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -514,16 +514,16 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
 	/* Request to transfer the entire buffer at once */
 	bcount = min(pc->req_xfer, 63 * 1024);
 
-	if (drive->using_dma && !idescsi_map_sg(drive, pc)) {
+	if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) {
 		hwif->sg_mapped = 1;
 		dma = !hwif->dma_ops->dma_setup(drive);
 		hwif->sg_mapped = 0;
 	}
 
-	ide_pktcmd_tf_load(drive, 0, bcount, dma);
+	if (!dma)
+		pc->flags &= ~PC_FLAG_DMA_OK;
 
-	if (dma)
-		pc->flags |= PC_FLAG_DMA_OK;
+	ide_pktcmd_tf_load(drive, 0, bcount, dma);
 
 	if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
 		ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc,
@@ -547,8 +547,12 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
 		  rq->sector, rq->nr_sectors, rq->current_nr_sectors);
 
 	if (blk_sense_request(rq) || blk_special_request(rq)) {
-		return idescsi_issue_pc(drive,
-				(struct ide_atapi_pc *) rq->special);
+		struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
+
+		if (drive->using_dma && !idescsi_map_sg(drive, pc))
+			pc->flags |= PC_FLAG_DMA_OK;
+
+		return idescsi_issue_pc(drive, pc);
 	}
 	blk_dump_rq_flags(rq, "ide-scsi: unsup command");
 	idescsi_end_request (drive, 0, 0);
-- 
cgit v1.2.3


From 28c7214bd8c2bbd4873b8f1e7f58d86d3731124f Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:21:59 +0200
Subject: ide: add PC_FLAG_DRQ_INTERRUPT pc flag

Add PC_FLAG_DRQ_INTERRUPT pc flag, set it in ide*_do_request()
and check for it (instead of checking for IDE*_FLAG_DRQ_INTERRUPT)
in ide*_issue_pc().  This is a preparation for adding generic
ide_issue_pc() helper.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 1d261298d61..b7c5e839157 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -525,7 +525,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
 
 	ide_pktcmd_tf_load(drive, 0, bcount, dma);
 
-	if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
+	if (pc->flags & PC_FLAG_DRQ_INTERRUPT) {
 		ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc,
 				    get_timeout(pc), idescsi_expiry);
 		return ide_started;
@@ -548,6 +548,10 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
 
 	if (blk_sense_request(rq) || blk_special_request(rq)) {
 		struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
+		idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+
+		if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags))
+			pc->flags |= PC_FLAG_DRQ_INTERRUPT;
 
 		if (drive->using_dma && !idescsi_map_sg(drive, pc))
 			pc->flags |= PC_FLAG_DMA_OK;
-- 
cgit v1.2.3


From 6bf1641ca1c7554f0da54aaf89788731b541bacc Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:22:00 +0200
Subject: ide: add ide_issue_pc() helper

Add generic ide_issue_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: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 30 ++----------------------------
 1 file changed, 2 insertions(+), 28 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index b7c5e839157..32415466fbf 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -502,38 +502,12 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
 		struct ide_atapi_pc *pc)
 {
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-	ide_hwif_t *hwif = drive->hwif;
-	u16 bcount;
-	u8 dma = 0;
 
 	/* Set the current packet command */
 	scsi->pc = pc;
-	/* We haven't transferred any data yet */
-	pc->xferred = 0;
-	pc->cur_pos = pc->buf;
-	/* Request to transfer the entire buffer at once */
-	bcount = min(pc->req_xfer, 63 * 1024);
-
-	if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) {
-		hwif->sg_mapped = 1;
-		dma = !hwif->dma_ops->dma_setup(drive);
-		hwif->sg_mapped = 0;
-	}
-
-	if (!dma)
-		pc->flags &= ~PC_FLAG_DMA_OK;
 
-	ide_pktcmd_tf_load(drive, 0, bcount, dma);
-
-	if (pc->flags & PC_FLAG_DRQ_INTERRUPT) {
-		ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc,
-				    get_timeout(pc), idescsi_expiry);
-		return ide_started;
-	} else {
-		/* Issue the packet command */
-		ide_execute_pkt_cmd(drive);
-		return idescsi_transfer_pc(drive);
-	}
+	return ide_issue_pc(drive, pc, idescsi_transfer_pc,
+			    get_timeout(pc), idescsi_expiry);
 }
 
 /*
-- 
cgit v1.2.3


From c6b2d260b5a7a5ed32aa2ce370d81183fc37eeb1 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:22:02 +0200
Subject: ide-scsi: use pc->callback

* Add ide_scsi_callback() pc->callback implementation, then update
  idescsi_check_condition() and idescsi_queue() to setup ->callback.

* Convert idescsi_pc_intr() to use pc->callback.

This is a preparation for adding generic ide_pc_intr() helper.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 32415466fbf..c0b39b9e5c1 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -183,6 +183,24 @@ static void ide_scsi_hex_dump(u8 *data, int len)
 	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
 }
 
+static int idescsi_end_request(ide_drive_t *, int, int);
+
+static void ide_scsi_callback(ide_drive_t *drive)
+{
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+	struct ide_atapi_pc *pc = scsi->pc;
+
+	if (pc->flags & PC_FLAG_TIMEDOUT)
+		debug_log("%s: got timed out packet %lu at %lu\n", __func__,
+			  pc->scsi_cmd->serial_number, jiffies);
+		/* end this request now - scsi should retry it*/
+	else if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
+		printk(KERN_INFO "Packet command completed, %d bytes"
+				 " transferred\n", pc->xferred);
+
+	idescsi_end_request(drive, 1, 0);
+}
+
 static int idescsi_check_condition(ide_drive_t *drive,
 		struct request *failed_cmd)
 {
@@ -210,6 +228,7 @@ static int idescsi_check_condition(ide_drive_t *drive,
 	rq->cmd_type = REQ_TYPE_SENSE;
 	rq->cmd_flags |= REQ_PREEMPT;
 	pc->timeout = jiffies + WAIT_READY;
+	pc->callback = ide_scsi_callback;
 	/* NOTE! Save the failed packet command in "rq->buffer" */
 	rq->buffer = (void *) failed_cmd->special;
 	pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;
@@ -222,8 +241,6 @@ static int idescsi_check_condition(ide_drive_t *drive,
 	return 0;
 }
 
-static int idescsi_end_request(ide_drive_t *, int, int);
-
 static ide_startstop_t
 idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
@@ -350,10 +367,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 	debug_log("Reached %s interrupt handler\n", __func__);
 
 	if (pc->flags & PC_FLAG_TIMEDOUT) {
-		debug_log("%s: got timed out packet %lu at %lu\n", __func__,
-			  pc->scsi_cmd->serial_number, jiffies);
-		/* end this request now - scsi should retry it*/
-		idescsi_end_request (drive, 1, 0);
+		pc->callback(drive);
 		return ide_stopped;
 	}
 	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
@@ -369,14 +383,11 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 
 	if ((stat & DRQ_STAT) == 0) {
 		/* No more interrupts */
-		if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
-			printk(KERN_INFO "Packet command completed, %d bytes"
-					" transferred\n", pc->xferred);
 		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
 		local_irq_enable_in_hardirq();
 		if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR))
 			rq->errors++;
-		idescsi_end_request (drive, 1, 0);
+		pc->callback(drive);
 		return ide_stopped;
 	}
 	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
@@ -718,6 +729,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
 	pc->scsi_cmd = cmd;
 	pc->done = done;
 	pc->timeout = jiffies + cmd->timeout_per_command;
+	pc->callback = ide_scsi_callback;
 
 	if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
 		printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
-- 
cgit v1.2.3


From cdca5c1f3b769eb2cdfc9cadc254cb74ba73c7d6 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:22:02 +0200
Subject: ide-scsi: add more debugging to idescsi_pc_intr()

Add more debugging to idescsi_pc_intr() to match ide-tape's
idetape_pc_intr().

While at it:

* Correct the first debug message.

This is a preparation for adding generic ide_pc_intr() helper.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index c0b39b9e5c1..ec9a5de2e75 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -364,7 +364,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 	u16 bcount;
 	u8 stat, ireason;
 
-	debug_log("Reached %s interrupt handler\n", __func__);
+	debug_log("Enter %s - interrupt handler\n", __func__);
 
 	if (pc->flags & PC_FLAG_TIMEDOUT) {
 		pc->callback(drive);
@@ -383,10 +383,16 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 
 	if ((stat & DRQ_STAT) == 0) {
 		/* No more interrupts */
+		debug_log("Packet command completed, %d bytes transferred\n",
+			  pc->xferred);
 		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
 		local_irq_enable_in_hardirq();
-		if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR))
+		if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
+			/* Error detected */
+			debug_log("%s: I/O error\n", drive->name);
+
 			rq->errors++;
+		}
 		pc->callback(drive);
 		return ide_stopped;
 	}
@@ -457,6 +463,9 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 	pc->xferred += bcount;
 	pc->cur_pos += bcount;
 
+	debug_log("[cmd %x] transferred %d bytes on that intr.\n",
+		  pc->c[0], bcount);
+
 	/* And set the interrupt handler again */
 	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 	return ide_started;
-- 
cgit v1.2.3


From 55d82bfa6763d6761670d740ab3bac2f1c042d87 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:22:03 +0200
Subject: ide-{floppy,scsi}: read Status Register before stopping DMA engine

Read Status Register before stopping DMA engine to match ide-tape
device driver - it should be safe and shouldn't affect anything.

This is a preparation for adding generic ide_pc_intr() helper.

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index ec9a5de2e75..ada733ca672 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -370,6 +370,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		pc->callback(drive);
 		return ide_stopped;
 	}
+
+	/* Clear the interrupt */
+	stat = ide_read_status(drive);
+
 	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
 		if (hwif->dma_ops->dma_end(drive))
 			pc->flags |= PC_FLAG_DMA_ERROR;
@@ -378,9 +382,6 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 		debug_log("%s: DMA finished\n", drive->name);
 	}
 
-	/* Clear the interrupt */
-	stat = ide_read_status(drive);
-
 	if ((stat & DRQ_STAT) == 0) {
 		/* No more interrupts */
 		debug_log("Packet command completed, %d bytes transferred\n",
-- 
cgit v1.2.3


From 646c0cb6c430f8d3ad3769dd1518fe664ff0ce27 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 15 Jul 2008 21:22:03 +0200
Subject: ide: add ide_pc_intr() helper

* ide-tape.c: add 'drive' argument to idetape_update_buffers().

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

* ide-tape.c: remove no longer needed DBG_PC_INTR.

There should be no functional changes caused by this patch
(unless the debugging is explicitely compiled in).

Cc: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/scsi/ide-scsi.c | 115 ++----------------------------------------------
 1 file changed, 3 insertions(+), 112 deletions(-)

(limited to 'drivers/scsi/ide-scsi.c')

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index ada733ca672..683bce375c7 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -356,120 +356,11 @@ static int idescsi_expiry(ide_drive_t *drive)
 static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 {
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-	ide_hwif_t *hwif = drive->hwif;
 	struct ide_atapi_pc *pc = scsi->pc;
-	struct request *rq = pc->rq;
-	xfer_func_t *xferfunc;
-	unsigned int temp;
-	u16 bcount;
-	u8 stat, ireason;
-
-	debug_log("Enter %s - interrupt handler\n", __func__);
-
-	if (pc->flags & PC_FLAG_TIMEDOUT) {
-		pc->callback(drive);
-		return ide_stopped;
-	}
-
-	/* Clear the interrupt */
-	stat = ide_read_status(drive);
-
-	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
-		if (hwif->dma_ops->dma_end(drive))
-			pc->flags |= PC_FLAG_DMA_ERROR;
-		else
-			pc->xferred = pc->req_xfer;
-		debug_log("%s: DMA finished\n", drive->name);
-	}
-
-	if ((stat & DRQ_STAT) == 0) {
-		/* No more interrupts */
-		debug_log("Packet command completed, %d bytes transferred\n",
-			  pc->xferred);
-		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
-		local_irq_enable_in_hardirq();
-		if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
-			/* Error detected */
-			debug_log("%s: I/O error\n", drive->name);
-
-			rq->errors++;
-		}
-		pc->callback(drive);
-		return ide_stopped;
-	}
-	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
-		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
-		printk(KERN_ERR "%s: The device wants to issue more interrupts "
-				"in DMA mode\n", drive->name);
-		ide_dma_off(drive);
-		return ide_do_reset(drive);
-	}
-	bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
-		  hwif->INB(hwif->io_ports.lbam_addr);
-	ireason = hwif->INB(hwif->io_ports.nsect_addr);
-
-	if (ireason & CD) {
-		printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
-		return ide_do_reset (drive);
-	}
-	if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
-		/* Hopefully, we will never get here */
-		printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
-				"to %s!\n", drive->name,
-				(ireason & IO) ? "Write" : "Read",
-				(ireason & IO) ? "Read" : "Write");
-		return ide_do_reset(drive);
-	}
-	if (!(pc->flags & PC_FLAG_WRITING)) {
-		temp = pc->xferred + bcount;
-		if (temp > pc->req_xfer) {
-			if (temp > pc->buf_size) {
-				printk(KERN_ERR "%s: The device wants to send "
-						"us more data than expected - "
-						"discarding data\n",
-						drive->name);
-				temp = pc->buf_size - pc->xferred;
-				if (temp) {
-					if (pc->sg)
-						ide_scsi_io_buffers(drive, pc,
-								    temp, 0);
-					else
-						hwif->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_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
-				return ide_started;
-			}
-			debug_log("The device wants to send us more data than "
-				  "expected - allowing transfer\n");
-		}
-		xferfunc = hwif->input_data;
-	} else
-		xferfunc = hwif->output_data;
-
-	if (pc->sg)
-		ide_scsi_io_buffers(drive, pc, bcount,
-				    !!(pc->flags & PC_FLAG_WRITING));
-	else
-		xferfunc(drive, NULL, pc->cur_pos, bcount);
-
-	/* Update the current position */
-	pc->xferred += bcount;
-	pc->cur_pos += bcount;
-
-	debug_log("[cmd %x] transferred %d bytes on that intr.\n",
-		  pc->c[0], bcount);
 
-	/* And set the interrupt handler again */
-	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
-	return ide_started;
+	return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
+			   idescsi_expiry, NULL, NULL, NULL,
+			   ide_scsi_io_buffers);
 }
 
 static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
-- 
cgit v1.2.3