All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <jens.axboe@oracle.com>
To: Boaz Harrosh <bharrosh@panasas.com>
Cc: Pekka J Enberg <penberg@cs.helsinki.fi>,
	Rene Herman <rene.herman@gmail.com>,
	Al Viro <viro@ftp.linux.org.uk>,
	Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: mcdx -- do_request(): non-read command to cd!!
Date: Mon, 2 Apr 2007 11:42:43 +0200	[thread overview]
Message-ID: <20070402094243.GH11996@kernel.dk> (raw)
In-Reply-To: <4610CDB4.4050708@panasas.com>

On Mon, Apr 02 2007, Boaz Harrosh wrote:
> Pekka J Enberg wrote:
> > On Mon, 2 Apr 2007, Jens Axboe wrote:
> >> But as I wrote earlier, it'll take lots more to make this driver close 
> >> to functional.
> > 
> > Heh, looking at the driver, that's quite an understatement =). Rene, 
> > here's an untested attempt to use a mutex instead of the horribly broken 
> > waitqueue "synchronization" in mcdx. It may or may not help so give it a 
> > spin if you want.
> > 
> > 			Pekka
> > 
> > ---
> >  drivers/cdrom/mcdx.c |  121 ++++++++++++++++++---------------------------------
> >  1 file changed, 44 insertions(+), 77 deletions(-)
> > 
> > Index: 2.6/drivers/cdrom/mcdx.c
> > ===================================================================
> > --- 2.6.orig/drivers/cdrom/mcdx.c	2007-04-02 11:50:40.000000000 +0300
> > +++ 2.6/drivers/cdrom/mcdx.c	2007-04-02 11:51:20.000000000 +0300
> > @@ -58,6 +58,7 @@     = "$Id: mcdx.c,v 1.21 1997/01/26 07:
> >  
> >  #include <linux/module.h>
> >  
> > +#include <linux/delay.h>
> >  #include <linux/errno.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/fs.h>
> > @@ -151,15 +152,14 @@ struct s_version {
> >  /* Per drive/controller stuff **************************************/
> >  
> >  struct s_drive_stuff {
> > +	struct mutex mutex;
> > +
> >  	/* waitqueues */
> >  	wait_queue_head_t busyq;
> > -	wait_queue_head_t lockq;
> > -	wait_queue_head_t sleepq;
> >  
> >  	/* flags */
> >  	volatile int introk;	/* status of last irq operation */
> >  	volatile int busy;	/* drive performs an operation */
> > -	volatile int lock;	/* exclusive usage */
> >  
> >  	/* cd infos */
> >  	struct s_diskinfo di;
> > @@ -266,7 +266,6 @@ static unsigned int uint2bcd(unsigned in
> >  static unsigned int bcd2uint(unsigned char);
> >  static unsigned port(int *);
> >  static int irq(int *);
> > -static void mcdx_delay(struct s_drive_stuff *, long jifs);
> >  static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
> >  			 int nr_sectors);
> >  static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
> > @@ -287,7 +286,7 @@ static int mcdx_requestmultidiskinfo(str
> >  static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
> >  			       int);
> >  static int mcdx_getstatus(struct s_drive_stuff *, int);
> > -static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
> > +static int mcdx_getval(struct s_drive_stuff *, int to, int delay_sec, char *);
> >  static int mcdx_talk(struct s_drive_stuff *,
> >  		     const unsigned char *cmd, size_t,
> >  		     void *buffer, size_t size, unsigned int timeout, int);
> > @@ -577,56 +576,57 @@ static void do_mcdx_request(request_queu
> >  	if (!req)
> >  		return;
> >  
> > +	if (!blk_fs_request(req)) {
> > +		end_request(req, 0);
> > +		goto again;
> > +	}
> > +
> >  	stuffp = req->rq_disk->private_data;
> >  
> >  	if (!stuffp->present) {
> >  		xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
> >  		xtrace(REQUEST, "end_request(0): bad device\n");
> >  		end_request(req, 0);
> > -		return;
> > +		goto again;
> >  	}
> >  
> >  	if (stuffp->audio) {
> >  		xwarn("do_request() attempt to read from audio cd\n");
> >  		xtrace(REQUEST, "end_request(0): read from audio\n");
> >  		end_request(req, 0);
> > -		return;
> > +		goto again;
> >  	}
> >  
> >  	xtrace(REQUEST, "do_request() (%lu + %lu)\n",
> >  	       req->sector, req->nr_sectors);
> >  
> > -	if (req->cmd != READ) {
> > +	if (rq_data_dir(req) != READ) {
> >  		xwarn("do_request(): non-read command to cd!!\n");
> >  		xtrace(REQUEST, "end_request(0): write\n");
> >  		end_request(req, 0);
> > -		return;
> > -	}
> > -	else {
> > -		stuffp->status = 0;
> > -		while (req->nr_sectors) {
> > -			int i;
> > -
> > -			i = mcdx_transfer(stuffp,
> > -					  req->buffer,
> > -					  req->sector,
> > -					  req->nr_sectors);
> > -
> > -			if (i == -1) {
> > -				end_request(req, 0);
> > -				goto again;
> > -			}
> > -			req->sector += i;
> > -			req->nr_sectors -= i;
> > -			req->buffer += (i * 512);
> > -		}
> > -		end_request(req, 1);
> >  		goto again;
> > -
> > -		xtrace(REQUEST, "end_request(1)\n");
> > -		end_request(req, 1);
> >  	}
> >  
> > +	stuffp->status = 0;
> > +	while (req->nr_sectors) {
> > +		int i;
> > +
> > +		spin_unlock_irq(q->queue_lock);
> > +		i = mcdx_transfer(stuffp,
> > +				  req->buffer,
> > +				  req->sector,
> > +				  req->nr_sectors);
> > +		spin_lock_irq(q->queue_lock);
> > +
> > +		if (i == -1) {
> > +			end_request(req, 0);
> > +			goto again;
> > +		}
> > +		req->sector += i;
> > +		req->nr_sectors -= i;
> > +		req->buffer += (i * 512);
> > +	}
> > +	end_request(req, 1);
> >  	goto again;
> >  }
> >  
> > @@ -825,26 +825,6 @@ __setup("mcdx=", mcdx_setup);
> >  
> >  /* DIRTY PART ******************************************************/
> >  
> > -static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
> > -/* This routine is used for sleeping.
> > - * A jifs value <0 means NO sleeping,
> > - *              =0 means minimal sleeping (let the kernel
> > - *                 run for other processes)
> > - *              >0 means at least sleep for that amount.
> > - *	May be we could use a simple count loop w/ jumps to itself, but
> > - *	I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
> > -{
> > -	if (jifs < 0)
> > -		return;
> > -
> > -	xtrace(SLEEP, "*** delay: sleepq\n");
> > -	interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
> > -	xtrace(SLEEP, "delay awoken\n");
> > -	if (signal_pending(current)) {
> > -		xtrace(SLEEP, "got signal\n");
> > -	}
> > -}
> > -
> >  static irqreturn_t mcdx_intr(int irq, void *dev_id)
> >  {
> >  	struct s_drive_stuff *stuffp = dev_id;
> > @@ -902,13 +882,7 @@ static int mcdx_talk(struct s_drive_stuf
> >  	if ((discard = (buffer == NULL)))
> >  		buffer = &c;
> >  
> > -	while (stuffp->lock) {
> > -		xtrace(SLEEP, "*** talk: lockq\n");
> > -		interruptible_sleep_on(&stuffp->lockq);
> > -		xtrace(SLEEP, "talk: awoken\n");
> > -	}
> > -
> > -	stuffp->lock = 1;
> > +	mutex_lock(&stuffp->mutex);
> >  
> >  	/* An operation other then reading data destroys the
> >  	   * data already requested and remembered in stuffp->request, ... */
> > @@ -992,8 +966,7 @@ 			xtrace(TALK, "talk() got 0x%02x\n", *
> >  		xinfo("talk() giving up\n");
> >  #endif
> >  
> > -	stuffp->lock = 0;
> > -	wake_up_interruptible(&stuffp->lockq);
> > +	mutex_unlock(&stuffp->mutex);
> >  
> >  	xtrace(TALK, "talk() done with 0x%02x\n", st);
> >  	return st;
> > @@ -1106,9 +1079,9 @@ 	stuffp->present = 0;	/* this should be 
> >  	stuffp->wreg_hcon = stuffp->wreg_reset + 1;
> >  	stuffp->wreg_chn = stuffp->wreg_hcon + 1;
> >  
> > +	mutex_init(&stuffp->mutex);
> > +
> >  	init_waitqueue_head(&stuffp->busyq);
> > -	init_waitqueue_head(&stuffp->lockq);
> > -	init_waitqueue_head(&stuffp->sleepq);
> >  
> >  	/* check if i/o addresses are available */
> >  	if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
> > @@ -1203,7 +1176,7 @@ 		return 0;
> >  	xtrace(INIT, "init() get garbage\n");
> >  	{
> >  		int i;
> > -		mcdx_delay(stuffp, HZ / 2);
> > +		msleep_interruptible(500);
> >  		for (i = 100; i; i--)
> >  			(void) inb(stuffp->rreg_status);
> >  	}
> > @@ -1327,10 +1300,6 @@ 	int done = 0;
> >  		return -1;
> >  	}
> >  
> > -	while (stuffp->lock) {
> > -		interruptible_sleep_on(&stuffp->lockq);
> > -	}
> > -
> >  	if (stuffp->valid && (sector >= stuffp->pending)
> >  	    && (sector < stuffp->low_border)) {
> >  
> > @@ -1346,7 +1315,7 @@ 	int done = 0;
> >  						sector + nr_sectors)
> >  		    ? stuffp->high_border : border;
> >  
> > -		stuffp->lock = current->pid;
> > +		mutex_lock(&stuffp->mutex);
> >  
> >  		do {
> >  
> > @@ -1366,11 +1335,11 @@ 	int done = 0;
> >  				} else
> >  					continue;
> >  
> > -				stuffp->lock = 0;
> > +				mutex_unlock(&stuffp->mutex);
> > +
> >  				stuffp->busy = 0;
> >  				stuffp->valid = 0;
> >  
> > -				wake_up_interruptible(&stuffp->lockq);
> >  				xtrace(XFER, "transfer() done (-1)\n");
> >  				return -1;
> >  			}
> > @@ -1405,9 +1374,7 @@ 				insb(stuffp->rreg_data, &dummy[0], C
> >  			}
> >  		} while (++(stuffp->pending) < border);
> >  
> > -		stuffp->lock = 0;
> > -		wake_up_interruptible(&stuffp->lockq);
> > -
> > +		mutex_unlock(&stuffp->mutex);
> >  	} else {
> >  
> >  		/* The requested sector(s) is/are out of the
> > @@ -1654,7 +1621,7 @@ 	       cmd[0], cmd[1], cmd[2], cmd[3], 
> >  
> >  	outsb(stuffp->wreg_data, cmd, sizeof cmd);
> >  
> > -	if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
> > +	if (-1 == mcdx_getval(stuffp, 3, 0, NULL)) {
> >  		xwarn("playmsf() timeout\n");
> >  		return -1;
> >  	}
> > @@ -1907,7 +1874,7 @@ 	return mcdx_talk(stuffp, "\x40", 1, NUL
> >  }
> >  
> >  static int
> > -mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
> > +mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay_sec, char *buf)
> >  {
> >  	unsigned long timeout = to + jiffies;
> >  	char c;
> > @@ -1918,7 +1885,7 @@ mcdx_getval(struct s_drive_stuff *stuffp
> >  	while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) {
> >  		if (time_after(jiffies, timeout))
> >  			return -1;
> > -		mcdx_delay(stuffp, delay);
> > +		msleep_interruptible(delay_sec * 1000);
> >  	}
> >  
> >  	*buf = (unsigned char) inb(stuffp->rreg_data) & 0xff;
> > -
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> 
> NACK
> 
> Why are you using req->buffer in new code. req->buffer is a leftover from a
> very old block pc era and is supposed to be killed. Please do not use it in
> any new code.
> you should use bio_data(rq->bio) and if you must have a virtual memory pointer
> hanging around than keep it in private space.

While that is true, this is ancient crap code and there's not much point
in rewriting that part as well. I somehow doubt that the cards are
capable of highmem addressing in the first place :-)

-- 
Jens Axboe


  parent reply	other threads:[~2007-04-02  9:43 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-30 21:21 mcdx -- do_request(): non-read command to cd!! Rene Herman
2007-03-31  6:47 ` Jens Axboe
2007-03-31 18:23   ` Rene Herman
2007-04-01 10:06     ` Pekka Enberg
2007-04-01 10:16       ` Pekka Enberg
2007-04-02  0:02       ` Rene Herman
2007-04-02  0:07         ` Rene Herman
2007-04-02  6:50           ` Pekka J Enberg
2007-04-02  7:10             ` Jens Axboe
2007-04-02  7:37               ` Pekka J Enberg
2007-04-02  8:55               ` Pekka J Enberg
2007-04-02  9:32                 ` Boaz Harrosh
2007-04-02  9:42                   ` Pekka J Enberg
2007-04-02  9:42                   ` Jens Axboe [this message]
2007-04-02 21:02                     ` Rene Herman
2007-04-02 15:18                 ` Rene Herman
2007-04-02 15:45                   ` Rene Herman
     [not found]                   ` <Pine.LNX.4.64.0704021837480.6518@sbz-30.cs.Helsinki.FI>
     [not found]                     ` <46112650.8080208@gmail.com>
     [not found]                       ` <Pine.LNX.4.64.0704021906040.7500@sbz-30.cs.Helsinki.FI>
     [not found]                         ` <461165FD.2010508@gmail.com>
     [not found]                           ` <Pine.LNX.4.64.0704030908420.20080@sbz-30.cs.Helsinki.FI>
     [not found]                             ` <Pine.LNX.4.64.0704030956330.20741@sbz-30.cs.Helsinki.FI>
2007-04-03 14:26                               ` Rene Herman
2007-04-03 17:37                                 ` Pekka J Enberg
     [not found]                               ` <461256C1.4020906@gmail.com>
2007-04-03 14:33                                 ` Pekka J Enberg
2007-04-03 17:31                                   ` Pekka J Enberg
2007-04-03 18:14                                     ` Rene Herman
2007-04-03 18:32                                       ` Pekka J Enberg
2007-04-04  2:10                                         ` Rene Herman
2007-04-04  6:30                                           ` Pekka Enberg
2007-04-04  6:19                                   ` Jens Axboe
2007-04-02 15:39               ` Rene Herman
2007-04-02  6:42         ` Jens Axboe
2007-04-02  7:07         ` Pekka Enberg

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=20070402094243.GH11996@kernel.dk \
    --to=jens.axboe@oracle.com \
    --cc=bharrosh@panasas.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=penberg@cs.helsinki.fi \
    --cc=rene.herman@gmail.com \
    --cc=viro@ftp.linux.org.uk \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.