<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Jens Axboe &lt;axboe@suse.de&gt;

idefloppy_input_buffers looks buggy wrt bio traversal, I bet that is the
problem.

This is a first stab at bringing it into line. Also kills pc-&gt;b_data,
noone should do stuff like that. And IDEFLOPPY_MIN and _MAX.



 drivers/ide/ide-floppy.c |   95 ++++++++++++++++++++++-------------------------
 1 files changed, 46 insertions(+), 49 deletions(-)

diff -puN drivers/ide/ide-floppy.c~ide_floppy-maybe-fix drivers/ide/ide-floppy.c
--- 25/drivers/ide/ide-floppy.c~ide_floppy-maybe-fix	2003-09-02 00:28:11.000000000 -0700
+++ 25-akpm/drivers/ide/ide-floppy.c	2003-09-02 00:28:11.000000000 -0700
@@ -156,7 +156,6 @@ typedef struct idefloppy_packet_command_
 	int request_transfer;			/* Bytes to transfer */
 	int actually_transferred;		/* Bytes actually transferred */
 	int buffer_size;			/* Size of our data buffer */
-	char *b_data;				/* Pointer which runs on the buffers */
 	int b_count;				/* Missing/Available data on the current buffer */
 	struct request *rq;			/* The corresponding request */
 	u8 *buffer;				/* Data buffer */
@@ -515,9 +514,6 @@ typedef struct {
 	u8		reserved[4];
 } idefloppy_mode_parameter_header_t;
 
-#define IDEFLOPPY_MIN(a,b)	((a)&lt;(b) ? (a):(b))
-#define	IDEFLOPPY_MAX(a,b)	((a)&gt;(b) ? (a):(b))
-
 /*
  *	Too bad. The drive wants to send us data which we are not ready to accept.
  *	Just throw it away.
@@ -575,28 +571,31 @@ static int idefloppy_do_end_request(ide_
 static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
 {
 	struct request *rq = pc-&gt;rq;
+	struct bio_vec *bvec;
 	struct bio *bio = rq-&gt;bio;
-	int count;
+	unsigned long flags;
+	char *data;
+	int count, i;
+
+	rq_for_each_bio(bio, rq) {
+		bio_for_each_segment(bvec, bio, i) {
+			if (!bcount)
+				break;
+
+			count = min(bvec-&gt;bv_len, bcount);
+			data = bvec_kmap_irq(bvec, &amp;flags);
+			atapi_input_bytes(drive, data, count);
+			bcount -= count;
+			pc-&gt;b_count += count;
+			bvec_kunmap_irq(data, &amp;flags);
 
-	while (bcount) {
-		if (pc-&gt;b_count == bio-&gt;bi_size) {
-			rq-&gt;sector += rq-&gt;current_nr_sectors;
-			rq-&gt;nr_sectors -= rq-&gt;current_nr_sectors;
-			idefloppy_do_end_request(drive, 1, 0);
-			if ((bio = rq-&gt;bio) != NULL)
-				pc-&gt;b_count = 0;
-		}
-		if (bio == NULL) {
-			printk(KERN_ERR "%s: bio == NULL in "
-				"idefloppy_input_buffers, bcount == %d\n",
-				drive-&gt;name, bcount);
-			idefloppy_discard_data(drive, bcount);
-			return;
-		}
-		count = IDEFLOPPY_MIN(bio-&gt;bi_size - pc-&gt;b_count, bcount);
-		atapi_input_bytes(drive, bio_data(bio) + pc-&gt;b_count, count);
-		bcount -= count;
-		pc-&gt;b_count += count;
+			idefloppy_do_end_request(drive, 1, count &gt;&gt; 9);
+		}
+	}
+
+	if (bcount) {
+		printk(KERN_ERR "%s: bio == NULL in idefloppy_input_buffers, bcount == %d\n", drive-&gt;name, bcount);
+		idefloppy_discard_data(drive, bcount);
 	}
 }
 
@@ -604,30 +603,30 @@ static void idefloppy_output_buffers (id
 {
 	struct request *rq = pc-&gt;rq;
 	struct bio *bio = rq-&gt;bio;
-	int count;
-	
-	while (bcount) {
-		if (!pc-&gt;b_count) {
-			rq-&gt;sector += rq-&gt;current_nr_sectors;
-			rq-&gt;nr_sectors -= rq-&gt;current_nr_sectors;
-			idefloppy_do_end_request(drive, 1, 0);
-			if ((bio = rq-&gt;bio) != NULL) {
-				pc-&gt;b_data = bio_data(bio);
-				pc-&gt;b_count = bio-&gt;bi_size;
-			}
+	struct bio_vec *bvec;
+	unsigned long flags;
+	int count, i;
+	char *data;
+
+	rq_for_each_bio(bio, rq) {
+		bio_for_each_segment(bvec, bio, i) {
+			if (!bcount)
+				break;
+
+			count = min(bvec-&gt;bv_len, bcount);
+			data = bvec_kmap_irq(bvec, &amp;flags);
+			atapi_output_bytes(drive, data, count);
+			bcount -= count;
+			pc-&gt;b_count += count;
+			bvec_kunmap_irq(data, &amp;flags);
+
+			idefloppy_do_end_request(drive, 1, count &gt;&gt; 9);
 		}
-		if (bio == NULL) {
-			printk(KERN_ERR "%s: bio == NULL in "
-				"idefloppy_output_buffers, bcount == %d\n",
-				drive-&gt;name, bcount);
-			idefloppy_write_zeros(drive, bcount);
-			return;
-		}
-		count = IDEFLOPPY_MIN(pc-&gt;b_count, bcount);
-		atapi_output_bytes(drive, pc-&gt;b_data, count);
-		bcount -= count;
-		pc-&gt;b_data += count;
-		pc-&gt;b_count -= count;
+	}
+
+	if (bio == NULL) {
+		printk(KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive-&gt;name, bcount);
+		idefloppy_write_zeros(drive, bcount);
 	}
 }
 
@@ -732,7 +731,6 @@ static void idefloppy_init_pc (idefloppy
 	pc-&gt;request_transfer = 0;
 	pc-&gt;buffer = pc-&gt;pc_buffer;
 	pc-&gt;buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
-	pc-&gt;b_data = NULL;
 //	pc-&gt;bio = NULL;
 	pc-&gt;callback = &amp;idefloppy_pc_callback;
 }
@@ -1199,7 +1197,6 @@ static void idefloppy_create_rw_cmd (ide
 	put_unaligned(htonl(block), (unsigned int *) &amp;pc-&gt;c[2]);
 	pc-&gt;callback = &amp;idefloppy_rw_callback;
 	pc-&gt;rq = rq;
-	pc-&gt;b_data = rq-&gt;buffer;
 	pc-&gt;b_count = cmd == READ ? 0 : rq-&gt;bio-&gt;bi_size;
 	if (rq-&gt;flags &amp; REQ_RW)
 		set_bit(PC_WRITING, &amp;pc-&gt;flags);

_
</pre></body></html>