LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Jens Axboe <axboe@suse.de>
To: Philip Dodd <phil.lists@two-towers.net>
Cc: linux-kernel@vger.kernel.org,
	Hugo Mills <hugo-lkml@carfax.org.uk>,
	Daniele Bernardini <db@sqbc.com>
Subject: Re: dma ripping
Date: Thu, 20 May 2004 15:34:38 +0200	[thread overview]
Message-ID: <20040520133437.GH1952@suse.de> (raw)
In-Reply-To: <40A9377A.70200@two-towers.net>

On Tue, May 18 2004, Philip Dodd wrote:
> Hugo Mills wrote:
> 8<
> >   Put me down for this latter one, too. I'm using a vanilla 2.6.[56]
> >on amd64. Controller is VIA.
> >
> >   It seems to be related to hard-to-read CDs (dirty/scratched/badly-
> >made) -- I've got a couple here that I'm pretty sure I can use as test
> >cases to trigger the problem instantly.
> 8<
> Hi,
> 
> OK - I don't know if any of this helps, but I guess a little more 
> precision won't do anyone any harm.
> Intel i820 Chipset on P3C-D mobo.
> ide0: BM-DMA at 0xa800-0xa807, BIOS settings: hda:DMA, hdb:pio
> hda: ASUS DVD-ROM E616, ATAPI CD/DVD-ROM drive
> hda: ATAPI 48X DVD-ROM drive, 512kB Cache, UDMA(33)
> 
> ide1: BM-DMA at 0xa808-0xa80f, BIOS settings: hdc:DMA, hdd:pio
> hdc: RICOH CD-R/RW MP7060A, ATAPI CD/DVD-ROM drive
> hdc: ATAPI 24X CD-ROM CD-R/RW drive, 2048kB Cache, DMA
> 
> Now hda is the one that bogs out, ripping silence after the "cdrom:
> dropping to single frame dma" error. hdc can rip for hours and hardly 
> ever get cdparanoia errors - even on "problematic" CDs that would appear 
> to be a declenching factor for the single frame dma switch for hda.

Any chance you can see if this makes any difference (on 2.6.6-BK)?

===== drivers/block/ll_rw_blk.c 1.252 vs edited =====
--- 1.252/drivers/block/ll_rw_blk.c	2004-05-15 08:11:55 +02:00
+++ edited/drivers/block/ll_rw_blk.c	2004-05-20 14:38:53 +02:00
@@ -1760,21 +1760,20 @@
  *    A matching blk_rq_unmap_user() must be issued at the end of io, while
  *    still in process context.
  */
-struct request *blk_rq_map_user(request_queue_t *q, int rw, void __user *ubuf,
-				unsigned int len)
+struct request *blk_rq_map_user(request_queue_t *q, struct rq_map_data *rmd)
 {
 	struct request *rq = NULL;
 	char *buf = NULL;
 	struct bio *bio;
 	int ret;
 
-	rq = blk_get_request(q, rw, __GFP_WAIT);
+	rq = blk_get_request(q, rmd->rw, __GFP_WAIT);
 	if (!rq)
 		return ERR_PTR(-ENOMEM);
 
-	bio = bio_map_user(q, NULL, (unsigned long) ubuf, len, rw == READ);
+	bio = bio_map_user(q, NULL, rmd->userptr, rmd->len, rmd->rw == READ);
 	if (!bio) {
-		int bytes = (len + 511) & ~511;
+		int bytes = (rmd->len + 511) & ~511;
 
 		buf = kmalloc(bytes, q->bounce_gfp | GFP_USER);
 		if (!buf) {
@@ -1782,21 +1781,26 @@
 			goto fault;
 		}
 
-		if (rw == WRITE) {
-			if (copy_from_user(buf, ubuf, len)) {
+		if (rmd->rw == WRITE) {
+			char *userptr = (char *) rmd->userptr;
+
+			if (copy_from_user(buf, userptr, rmd->len)) {
 				ret = -EFAULT;
 				goto fault;
 			}
 		} else
-			memset(buf, 0, len);
+			memset(buf, 0, rmd->len);
 	}
 
 	rq->bio = rq->biotail = bio;
 	if (rq->bio)
 		blk_rq_bio_prep(q, rq, bio);
 
+	rmd->buf = buf;
+	rmd->bio = bio;
+
 	rq->buffer = rq->data = buf;
-	rq->data_len = len;
+	rq->data_len = rmd->len;
 	return rq;
 fault:
 	if (buf)
@@ -1806,6 +1810,8 @@
 	if (rq)
 		blk_put_request(rq);
 
+	rmd->bio = NULL;
+	rmd->buf = NULL;
 	return ERR_PTR(ret);
 }
 
@@ -1820,18 +1826,19 @@
  * Description:
  *    Unmap a request previously mapped by blk_rq_map_user().
  */
-int blk_rq_unmap_user(struct request *rq, void __user *ubuf, struct bio *bio,
-		      unsigned int ulen)
+int blk_rq_unmap_user(struct request *rq, struct rq_map_data *rmd)
 {
-	const int read = rq_data_dir(rq) == READ;
+	const int read = rmd->rw == READ;
 	int ret = 0;
 
-	if (bio)
-		bio_unmap_user(bio, read);
-	if (rq->buffer) {
-		if (read && copy_to_user(ubuf, rq->buffer, ulen))
+	if (rmd->bio)
+		bio_unmap_user(rmd->bio, read);
+	else if (rmd->buf) {
+		char *userptr = (char *) rmd->userptr;
+
+		if (read && copy_to_user(userptr, rmd->buf, rmd->len))
 			ret = -EFAULT;
-		kfree(rq->buffer);
+		kfree(rmd->buf);
 	}
 
 	blk_put_request(rq);
===== drivers/block/scsi_ioctl.c 1.42 vs edited =====
--- 1.42/drivers/block/scsi_ioctl.c	2004-04-27 15:20:34 +02:00
+++ edited/drivers/block/scsi_ioctl.c	2004-05-20 15:10:56 +02:00
@@ -110,8 +110,8 @@
 {
 	unsigned long start_time;
 	int reading, writing;
+	struct rq_map_data rmd;
 	struct request *rq;
-	struct bio *bio;
 	char sense[SCSI_SENSE_BUFFERSIZE];
 
 	if (hdr->interface_id != 'S')
@@ -128,6 +128,7 @@
 	if (hdr->dxfer_len > (q->max_sectors << 9))
 		return -EIO;
 
+	memset(&rmd, 0, sizeof(rmd));
 	reading = writing = 0;
 	if (hdr->dxfer_len) {
 		switch (hdr->dxfer_direction) {
@@ -144,8 +145,10 @@
 			break;
 		}
 
-		rq = blk_rq_map_user(q, writing ? WRITE : READ, hdr->dxferp,
-				     hdr->dxfer_len);
+		rmd.userptr = (unsigned long) hdr->dxferp;
+		rmd.len = hdr->dxfer_len;
+		rmd.rw = writing ? WRITE : READ;
+		rq = blk_rq_map_user(q, &rmd);
 
 		if (IS_ERR(rq))
 			return PTR_ERR(rq);
@@ -165,7 +168,6 @@
 	rq->sense_len = 0;
 
 	rq->flags |= REQ_BLOCK_PC;
-	bio = rq->bio;
 
 	rq->timeout = (hdr->timeout * HZ) / 1000;
 	if (!rq->timeout)
@@ -201,7 +203,7 @@
 			hdr->sb_len_wr = len;
 	}
 
-	if (blk_rq_unmap_user(rq, hdr->dxferp, bio, hdr->dxfer_len))
+	if (blk_rq_unmap_user(rq, &rmd))
 		return -EFAULT;
 
 	/* may not have succeeded, but output values written to control
===== drivers/cdrom/cdrom.c 1.52 vs edited =====
--- 1.52/drivers/cdrom/cdrom.c	2004-04-27 15:11:55 +02:00
+++ edited/drivers/cdrom/cdrom.c	2004-05-20 15:13:30 +02:00
@@ -1946,23 +1946,26 @@
 {
 	request_queue_t *q = cdi->disk->queue;
 	struct request *rq;
-	struct bio *bio;
-	unsigned int len;
 	int nr, ret = 0;
 
 	if (!q)
 		return -ENXIO;
 
 	while (nframes) {
+		struct rq_map_data rmd;
+
 		nr = nframes;
 		if (cdi->cdda_method == CDDA_BPC_SINGLE)
 			nr = 1;
 		if (nr * CD_FRAMESIZE_RAW > (q->max_sectors << 9))
 			nr = (q->max_sectors << 9) / CD_FRAMESIZE_RAW;
 
-		len = nr * CD_FRAMESIZE_RAW;
+		memset(&rmd, 0, sizeof(rmd));
+		rmd.userptr = (unsigned long) ubuf;
+		rmd.len = nr * CD_FRAMESIZE_RAW;
+		rmd.rw = READ;
 
-		rq = blk_rq_map_user(q, READ, ubuf, len);
+		rq = blk_rq_map_user(q, &rmd);
 		if (IS_ERR(rq))
 			return PTR_ERR(rq);
 
@@ -1981,7 +1984,6 @@
 		rq->cmd_len = 12;
 		rq->flags |= REQ_BLOCK_PC;
 		rq->timeout = 60 * HZ;
-		bio = rq->bio;
 
 		if (blk_execute_rq(q, cdi->disk, rq)) {
 			struct request_sense *s = rq->sense;
@@ -1989,7 +1991,7 @@
 			cdi->last_sense = s->sense_key;
 		}
 
-		if (blk_rq_unmap_user(rq, ubuf, bio, len))
+		if (blk_rq_unmap_user(rq, &rmd))
 			ret = -EFAULT;
 
 		if (ret)
===== include/linux/blkdev.h 1.145 vs edited =====
--- 1.145/include/linux/blkdev.h	2004-05-19 18:02:45 +02:00
+++ edited/include/linux/blkdev.h	2004-05-20 14:37:09 +02:00
@@ -501,6 +501,24 @@
 	unsigned block_size_bits;
 };
 
+/*
+ * passed in and out of blk_rq_map/unmap_user()
+ */
+struct rq_map_data {
+	/*
+	 * input data
+	 */
+	unsigned long userptr;
+	unsigned int len;
+	int rw;
+
+	/*
+	 * output data
+	 */
+	struct bio *bio;
+	unsigned char *buf;
+};
+
 extern int blk_register_queue(struct gendisk *disk);
 extern void blk_unregister_queue(struct gendisk *disk);
 extern void register_disk(struct gendisk *dev);
@@ -523,8 +541,8 @@
 extern void __blk_stop_queue(request_queue_t *q);
 extern void blk_run_queue(request_queue_t *);
 extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
-extern struct request *blk_rq_map_user(request_queue_t *, int, void __user *, unsigned int);
-extern int blk_rq_unmap_user(struct request *, void __user *, struct bio *, unsigned int);
+extern struct request *blk_rq_map_user(request_queue_t *q, struct rq_map_data *rmd);
+extern int blk_rq_unmap_user(struct request *rq, struct rq_map_data *rmd);
 extern int blk_execute_rq(request_queue_t *, struct gendisk *, struct request *);
 
 static inline request_queue_t *bdev_get_queue(struct block_device *bdev)

-- 
Jens Axboe


  parent reply	other threads:[~2004-05-20 13:35 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-14 15:29 Daniele Bernardini
2004-05-15 10:14 ` Jens Axboe
2004-05-15  8:45   ` Daniele Bernardini
2004-05-15 14:58     ` Jens Axboe
2004-05-15 10:13       ` Daniele Bernardini
2004-05-15 14:03       ` Daniele Bernardini
2004-05-15 21:19         ` Jens Axboe
2004-05-16 15:26           ` Philip Dodd
2004-05-16 15:39             ` Hugo Mills
2004-05-17 22:06               ` Philip Dodd
2004-05-20  2:31                 ` Philip Dodd
2004-05-20 13:34                 ` Jens Axboe [this message]
2004-05-30 17:36                   ` Philip Dodd
2004-05-31  5:19                     ` Tvrtko A. Uršulin
2004-05-17 22:12         ` Bill Davidsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040520133437.GH1952@suse.de \
    --to=axboe@suse.de \
    --cc=db@sqbc.com \
    --cc=hugo-lkml@carfax.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=phil.lists@two-towers.net \
    --subject='Re: dma ripping' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).