public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Pekka J Enberg <penberg@cs.helsinki.fi>
Cc: Jens Axboe <jens.axboe@oracle.com>,
	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, 02 Apr 2007 12:32:36 +0300	[thread overview]
Message-ID: <4610CDB4.4050708@panasas.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0704021152280.27165@sbz-30.cs.Helsinki.FI>

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.

Boaz





  reply	other threads:[~2007-04-02 10:12 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 [this message]
2007-04-02  9:42                   ` Pekka J Enberg
2007-04-02  9:42                   ` Jens Axboe
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=4610CDB4.4050708@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=jens.axboe@oracle.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox