direct-io.hg

changeset 6456:fb2fae2cc003

blkfront cleanup and retab.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Aug 28 14:21:08 2005 +0000 (2005-08-28)
parents 15d378281a0b
children b26d8e1b4436
files linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sat Aug 27 11:49:35 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sun Aug 28 14:21:08 2005 +0000
     1.3 @@ -32,23 +32,15 @@
     1.4   */
     1.5  
     1.6  #if 1
     1.7 -#define ASSERT(_p) \
     1.8 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
     1.9 -    __LINE__, __FILE__); *(int*)0=0; }
    1.10 +#define ASSERT(p)							   \
    1.11 +	if (!(p)) { printk("Assertion '%s' failed, line %d, file %s", #p , \
    1.12 +	__LINE__, __FILE__); *(int*)0=0; }
    1.13  #else
    1.14  #define ASSERT(_p)
    1.15  #endif
    1.16  
    1.17  #include <linux/version.h>
    1.18 -
    1.19 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    1.20  #include "block.h"
    1.21 -#else
    1.22 -#include "common.h"
    1.23 -#include <linux/blk.h>
    1.24 -#include <linux/tqueue.h>
    1.25 -#endif
    1.26 -
    1.27  #include <linux/cdrom.h>
    1.28  #include <linux/sched.h>
    1.29  #include <linux/interrupt.h>
    1.30 @@ -58,11 +50,6 @@
    1.31  #include <asm-xen/xen-public/grant_table.h>
    1.32  #include <asm-xen/gnttab.h>
    1.33  
    1.34 -typedef unsigned char byte; /* from linux/ide.h */
    1.35 -
    1.36 -/* Control whether runtime update of vbds is enabled. */
    1.37 -#define ENABLE_VBD_UPDATE 1
    1.38 -
    1.39  #define BLKIF_STATE_DISCONNECTED 0
    1.40  #define BLKIF_STATE_CONNECTED    1
    1.41  
    1.42 @@ -75,9 +62,9 @@ static unsigned int blkif_state = BLKIF_
    1.43  #define GRANTREF_INVALID (1<<15)
    1.44  
    1.45  static struct blk_shadow {
    1.46 -    blkif_request_t req;
    1.47 -    unsigned long request;
    1.48 -    unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    1.49 +	blkif_request_t req;
    1.50 +	unsigned long request;
    1.51 +	unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    1.52  } blk_shadow[BLK_RING_SIZE];
    1.53  unsigned long blk_shadow_free;
    1.54  
    1.55 @@ -85,64 +72,42 @@ static int recovery = 0; /* Recovery in 
    1.56  
    1.57  static void kick_pending_request_queues(struct blkfront_info *info);
    1.58  
    1.59 -static int __init xlblk_init(void);
    1.60 -
    1.61  static void blkif_completion(struct blk_shadow *s);
    1.62  
    1.63  static inline int GET_ID_FROM_FREELIST(void)
    1.64  {
    1.65 -    unsigned long free = blk_shadow_free;
    1.66 -    BUG_ON(free > BLK_RING_SIZE);
    1.67 -    blk_shadow_free = blk_shadow[free].req.id;
    1.68 -    blk_shadow[free].req.id = 0x0fffffee; /* debug */
    1.69 -    return free;
    1.70 +	unsigned long free = blk_shadow_free;
    1.71 +	BUG_ON(free > BLK_RING_SIZE);
    1.72 +	blk_shadow_free = blk_shadow[free].req.id;
    1.73 +	blk_shadow[free].req.id = 0x0fffffee; /* debug */
    1.74 +	return free;
    1.75  }
    1.76  
    1.77  static inline void ADD_ID_TO_FREELIST(unsigned long id)
    1.78  {
    1.79 -    blk_shadow[id].req.id  = blk_shadow_free;
    1.80 -    blk_shadow[id].request = 0;
    1.81 -    blk_shadow_free = id;
    1.82 +	blk_shadow[id].req.id  = blk_shadow_free;
    1.83 +	blk_shadow[id].request = 0;
    1.84 +	blk_shadow_free = id;
    1.85  }
    1.86  
    1.87 -
    1.88 -/************************  COMMON CODE  (inlined)  ************************/
    1.89 -
    1.90 -/* Kernel-specific definitions used in the common code */
    1.91 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    1.92 -#define DISABLE_SCATTERGATHER()
    1.93 -#else
    1.94 -static int sg_operation = -1;
    1.95 -#define DISABLE_SCATTERGATHER() (sg_operation = -1)
    1.96 -#endif
    1.97 -
    1.98  static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r)
    1.99  {
   1.100  
   1.101 -    s->req = *r;
   1.102 +	s->req = *r;
   1.103  }
   1.104  
   1.105  static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s)
   1.106  {
   1.107  
   1.108 -    *r = s->req;
   1.109 +	*r = s->req;
   1.110  }
   1.111  
   1.112 -
   1.113  static inline void flush_requests(struct blkfront_info *info)
   1.114  {
   1.115 -    DISABLE_SCATTERGATHER();
   1.116 -    RING_PUSH_REQUESTS(&info->ring);
   1.117 -    notify_via_evtchn(info->evtchn);
   1.118 +	RING_PUSH_REQUESTS(&info->ring);
   1.119 +	notify_via_evtchn(info->evtchn);
   1.120  }
   1.121  
   1.122 -
   1.123 -/**************************  KERNEL VERSION 2.6  **************************/
   1.124 -
   1.125 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   1.126 -
   1.127 -module_init(xlblk_init);
   1.128 -
   1.129  static void kick_pending_request_queues(struct blkfront_info *info)
   1.130  {
   1.131  	if (!RING_FULL(&info->ring)) {
   1.132 @@ -169,50 +134,44 @@ static void blkif_restart_queue_callback
   1.133  
   1.134  int blkif_open(struct inode *inode, struct file *filep)
   1.135  {
   1.136 -	// struct gendisk *gd = inode->i_bdev->bd_disk;
   1.137 -	// struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
   1.138 -
   1.139 -	/* Update of usage count is protected by per-device semaphore. */
   1.140 -	// di->mi->usage++;
   1.141 -
   1.142  	return 0;
   1.143  }
   1.144  
   1.145  
   1.146  int blkif_release(struct inode *inode, struct file *filep)
   1.147  {
   1.148 -    /* FIXME: This is where we can actually free up majors, etc. --RR */
   1.149 -    return 0;
   1.150 +	return 0;
   1.151  }
   1.152  
   1.153  
   1.154  int blkif_ioctl(struct inode *inode, struct file *filep,
   1.155                  unsigned command, unsigned long argument)
   1.156  {
   1.157 -    int i;
   1.158 +	int i;
   1.159  
   1.160 -    DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
   1.161 -                  command, (long)argument, inode->i_rdev);
   1.162 +	DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
   1.163 +		      command, (long)argument, inode->i_rdev);
   1.164  
   1.165 -    switch ( command )
   1.166 -    {
   1.167 -    case HDIO_GETGEO:
   1.168 -        /* return ENOSYS to use defaults */
   1.169 -        return -ENOSYS;
   1.170 +	switch ( command )
   1.171 +	{
   1.172 +	case HDIO_GETGEO:
   1.173 +		/* return ENOSYS to use defaults */
   1.174 +		return -ENOSYS;
   1.175  
   1.176 -    case CDROMMULTISESSION:
   1.177 -        DPRINTK("FIXME: support multisession CDs later\n");
   1.178 -        for ( i = 0; i < sizeof(struct cdrom_multisession); i++ )
   1.179 -            if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT;
   1.180 -        return 0;
   1.181 +	case CDROMMULTISESSION:
   1.182 +		DPRINTK("FIXME: support multisession CDs later\n");
   1.183 +		for (i = 0; i < sizeof(struct cdrom_multisession); i++)
   1.184 +			if (put_user(0, (char *)(argument + i)))
   1.185 +				return -EFAULT;
   1.186 +		return 0;
   1.187  
   1.188 -    default:
   1.189 -        /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
   1.190 -          command);*/
   1.191 -        return -EINVAL; /* same return as native Linux */
   1.192 -    }
   1.193 +	default:
   1.194 +		/*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
   1.195 +		  command);*/
   1.196 +		return -EINVAL; /* same return as native Linux */
   1.197 +	}
   1.198  
   1.199 -    return 0;
   1.200 +	return 0;
   1.201  }
   1.202  
   1.203  
   1.204 @@ -228,76 +187,77 @@ int blkif_ioctl(struct inode *inode, str
   1.205   */
   1.206  static int blkif_queue_request(struct request *req)
   1.207  {
   1.208 -    struct blkfront_info *info = req->rq_disk->private_data;
   1.209 -    unsigned long buffer_ma;
   1.210 -    blkif_request_t *ring_req;
   1.211 -    struct bio *bio;
   1.212 -    struct bio_vec *bvec;
   1.213 -    int idx;
   1.214 -    unsigned long id;
   1.215 -    unsigned int fsect, lsect;
   1.216 -    int ref;
   1.217 -    grant_ref_t gref_head;
   1.218 +	struct blkfront_info *info = req->rq_disk->private_data;
   1.219 +	unsigned long buffer_ma;
   1.220 +	blkif_request_t *ring_req;
   1.221 +	struct bio *bio;
   1.222 +	struct bio_vec *bvec;
   1.223 +	int idx;
   1.224 +	unsigned long id;
   1.225 +	unsigned int fsect, lsect;
   1.226 +	int ref;
   1.227 +	grant_ref_t gref_head;
   1.228  
   1.229 -    if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
   1.230 -        return 1;
   1.231 +	if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
   1.232 +		return 1;
   1.233  
   1.234 -    if (gnttab_alloc_grant_references(BLKIF_MAX_SEGMENTS_PER_REQUEST,
   1.235 -				      &gref_head) < 0) {
   1.236 -	    gnttab_request_free_callback(&info->callback,
   1.237 -					 blkif_restart_queue_callback, info,
   1.238 -					 BLKIF_MAX_SEGMENTS_PER_REQUEST);
   1.239 -	    return 1;
   1.240 -    }
   1.241 +	if (gnttab_alloc_grant_references(
   1.242 +		BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head) < 0) {
   1.243 +		gnttab_request_free_callback(
   1.244 +			&info->callback,
   1.245 +			blkif_restart_queue_callback,
   1.246 +			info,
   1.247 +			BLKIF_MAX_SEGMENTS_PER_REQUEST);
   1.248 +		return 1;
   1.249 +	}
   1.250  
   1.251 -    /* Fill out a communications ring structure. */
   1.252 -    ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
   1.253 -    id = GET_ID_FROM_FREELIST();
   1.254 -    blk_shadow[id].request = (unsigned long)req;
   1.255 +	/* Fill out a communications ring structure. */
   1.256 +	ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
   1.257 +	id = GET_ID_FROM_FREELIST();
   1.258 +	blk_shadow[id].request = (unsigned long)req;
   1.259  
   1.260 -    ring_req->id = id;
   1.261 -    ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ;
   1.262 -    ring_req->sector_number = (blkif_sector_t)req->sector;
   1.263 -    ring_req->handle = info->handle;
   1.264 +	ring_req->id = id;
   1.265 +	ring_req->operation = rq_data_dir(req) ?
   1.266 +		BLKIF_OP_WRITE : BLKIF_OP_READ;
   1.267 +	ring_req->sector_number = (blkif_sector_t)req->sector;
   1.268 +	ring_req->handle = info->handle;
   1.269  
   1.270 -    ring_req->nr_segments = 0;
   1.271 -    rq_for_each_bio(bio, req)
   1.272 -    {
   1.273 -        bio_for_each_segment(bvec, bio, idx)
   1.274 -        {
   1.275 -            if ( ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST )
   1.276 -                BUG();
   1.277 -            buffer_ma = page_to_phys(bvec->bv_page);
   1.278 -            fsect = bvec->bv_offset >> 9;
   1.279 -            lsect = fsect + (bvec->bv_len >> 9) - 1;
   1.280 -            /* install a grant reference. */
   1.281 -            ref = gnttab_claim_grant_reference(&gref_head);
   1.282 -            ASSERT( ref != -ENOSPC );
   1.283 +	ring_req->nr_segments = 0;
   1.284 +	rq_for_each_bio (bio, req) {
   1.285 +		bio_for_each_segment (bvec, bio, idx) {
   1.286 +			BUG_ON(ring_req->nr_segments
   1.287 +			       == BLKIF_MAX_SEGMENTS_PER_REQUEST);
   1.288 +			buffer_ma = page_to_phys(bvec->bv_page);
   1.289 +			fsect = bvec->bv_offset >> 9;
   1.290 +			lsect = fsect + (bvec->bv_len >> 9) - 1;
   1.291 +			/* install a grant reference. */
   1.292 +			ref = gnttab_claim_grant_reference(&gref_head);
   1.293 +			ASSERT(ref != -ENOSPC);
   1.294 +
   1.295 +			gnttab_grant_foreign_access_ref(
   1.296 +				ref,
   1.297 +				info->backend_id,
   1.298 +				buffer_ma >> PAGE_SHIFT,
   1.299 +				rq_data_dir(req) );
   1.300  
   1.301 -            gnttab_grant_foreign_access_ref(
   1.302 -                        ref,
   1.303 -                        info->backend_id,
   1.304 -                        buffer_ma >> PAGE_SHIFT,
   1.305 -                        rq_data_dir(req) );
   1.306 +			blk_shadow[id].frame[ring_req->nr_segments] =
   1.307 +				buffer_ma >> PAGE_SHIFT;
   1.308  
   1.309 -            blk_shadow[id].frame[ring_req->nr_segments] =
   1.310 -                buffer_ma >> PAGE_SHIFT;
   1.311 -
   1.312 -            ring_req->frame_and_sects[ring_req->nr_segments] =
   1.313 -                blkif_fas_from_gref(ref, fsect, lsect);
   1.314 +			ring_req->frame_and_sects[ring_req->nr_segments] =
   1.315 +				blkif_fas_from_gref(ref, fsect, lsect);
   1.316  
   1.317 -	    ring_req->nr_segments++;
   1.318 -        }
   1.319 -    }
   1.320 +			ring_req->nr_segments++;
   1.321 +		}
   1.322 +	}
   1.323  
   1.324 -    info->ring.req_prod_pvt++;
   1.325 +	info->ring.req_prod_pvt++;
   1.326  
   1.327 -    /* Keep a private copy so we can reissue requests when recovering. */
   1.328 -    pickle_request(&blk_shadow[id], ring_req);
   1.329 +	/* Keep a private copy so we can reissue requests when recovering. */
   1.330 +	pickle_request(&blk_shadow[id], ring_req);
   1.331  
   1.332 -    gnttab_free_grant_references(gref_head);
   1.333 +	gnttab_free_grant_references(gref_head);
   1.334  
   1.335 -    return 0;
   1.336 +	return 0;
   1.337  }
   1.338  
   1.339  /*
   1.340 @@ -306,756 +266,197 @@ static int blkif_queue_request(struct re
   1.341   */
   1.342  void do_blkif_request(request_queue_t *rq)
   1.343  {
   1.344 -    struct blkfront_info *info = NULL;
   1.345 -    struct request *req;
   1.346 -    int queued;
   1.347 +	struct blkfront_info *info = NULL;
   1.348 +	struct request *req;
   1.349 +	int queued;
   1.350  
   1.351 -    DPRINTK("Entered do_blkif_request\n");
   1.352 +	DPRINTK("Entered do_blkif_request\n");
   1.353  
   1.354 -    queued = 0;
   1.355 +	queued = 0;
   1.356  
   1.357 -    while ( (req = elv_next_request(rq)) != NULL )
   1.358 -    {
   1.359 -	info = req->rq_disk->private_data;
   1.360 +	while ((req = elv_next_request(rq)) != NULL) {
   1.361 +		info = req->rq_disk->private_data;
   1.362  
   1.363 -        if ( !blk_fs_request(req) )
   1.364 -        {
   1.365 -            end_request(req, 0);
   1.366 -            continue;
   1.367 -        }
   1.368 +		if (!blk_fs_request(req)) {
   1.369 +			end_request(req, 0);
   1.370 +			continue;
   1.371 +		}
   1.372 +
   1.373 +		if (RING_FULL(&info->ring))
   1.374 +			goto wait;
   1.375  
   1.376 -	if (RING_FULL(&info->ring))
   1.377 -		goto wait;
   1.378 -
   1.379 -        DPRINTK("do_blk_req %p: cmd %p, sec %lx, (%u/%li) buffer:%p [%s]\n",
   1.380 -                req, req->cmd, req->sector, req->current_nr_sectors,
   1.381 -                req->nr_sectors, req->buffer,
   1.382 -                rq_data_dir(req) ? "write" : "read");
   1.383 +		DPRINTK("do_blk_req %p: cmd %p, sec %lx, "
   1.384 +			"(%u/%li) buffer:%p [%s]\n",
   1.385 +			req, req->cmd, req->sector, req->current_nr_sectors,
   1.386 +			req->nr_sectors, req->buffer,
   1.387 +			rq_data_dir(req) ? "write" : "read");
   1.388  
   1.389 -        blkdev_dequeue_request(req);
   1.390 -        if (blkif_queue_request(req)) {
   1.391 -		blk_requeue_request(rq, req);
   1.392 -        wait:
   1.393 -		/* Avoid pointless unplugs. */
   1.394 -		blk_stop_queue(rq);
   1.395 -		break;
   1.396 -        }
   1.397 +		blkdev_dequeue_request(req);
   1.398 +		if (blkif_queue_request(req)) {
   1.399 +			blk_requeue_request(rq, req);
   1.400 +		wait:
   1.401 +			/* Avoid pointless unplugs. */
   1.402 +			blk_stop_queue(rq);
   1.403 +			break;
   1.404 +		}
   1.405  
   1.406 -        queued++;
   1.407 -    }
   1.408 +		queued++;
   1.409 +	}
   1.410  
   1.411 -    if ( queued != 0 )
   1.412 -        flush_requests(info);
   1.413 +	if (queued != 0)
   1.414 +		flush_requests(info);
   1.415  }
   1.416  
   1.417  
   1.418  static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
   1.419  {
   1.420 -    struct request *req;
   1.421 -    blkif_response_t *bret;
   1.422 -    RING_IDX i, rp;
   1.423 -    unsigned long flags;
   1.424 -    struct blkfront_info *info = (struct blkfront_info *)dev_id;
   1.425 -
   1.426 -    spin_lock_irqsave(&blkif_io_lock, flags);
   1.427 -
   1.428 -    if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) {
   1.429 -        spin_unlock_irqrestore(&blkif_io_lock, flags);
   1.430 -        return IRQ_HANDLED;
   1.431 -    }
   1.432 -
   1.433 -    rp = info->ring.sring->rsp_prod;
   1.434 -    rmb(); /* Ensure we see queued responses up to 'rp'. */
   1.435 -
   1.436 -    for ( i = info->ring.rsp_cons; i != rp; i++ )
   1.437 -    {
   1.438 -        unsigned long id;
   1.439 -
   1.440 -        bret = RING_GET_RESPONSE(&info->ring, i);
   1.441 -        id   = bret->id;
   1.442 -        req  = (struct request *)blk_shadow[id].request;
   1.443 -
   1.444 -        blkif_completion(&blk_shadow[id]);
   1.445 -
   1.446 -        ADD_ID_TO_FREELIST(id);
   1.447 -
   1.448 -        switch ( bret->operation )
   1.449 -        {
   1.450 -        case BLKIF_OP_READ:
   1.451 -        case BLKIF_OP_WRITE:
   1.452 -            if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
   1.453 -                DPRINTK("Bad return from blkdev data request: %x\n",
   1.454 -                        bret->status);
   1.455 -
   1.456 -            if ( unlikely(end_that_request_first
   1.457 -                          (req,
   1.458 -                           (bret->status == BLKIF_RSP_OKAY),
   1.459 -                           req->hard_nr_sectors)) )
   1.460 -                BUG();
   1.461 -            end_that_request_last(req);
   1.462 -
   1.463 -            break;
   1.464 -        default:
   1.465 -            BUG();
   1.466 -        }
   1.467 -    }
   1.468 -
   1.469 -    info->ring.rsp_cons = i;
   1.470 -
   1.471 -    kick_pending_request_queues(info);
   1.472 -
   1.473 -    spin_unlock_irqrestore(&blkif_io_lock, flags);
   1.474 -
   1.475 -    return IRQ_HANDLED;
   1.476 -}
   1.477 -
   1.478 -#else
   1.479 -/**************************  KERNEL VERSION 2.4  **************************/
   1.480 -
   1.481 -static kdev_t        sg_dev;
   1.482 -static unsigned long sg_next_sect;
   1.483 -
   1.484 -/*
   1.485 - * Request queues with outstanding work, but ring is currently full.
   1.486 - * We need no special lock here, as we always access this with the
   1.487 - * blkif_io_lock held. We only need a small maximum list.
   1.488 - */
   1.489 -#define MAX_PENDING 8
   1.490 -static request_queue_t *pending_queues[MAX_PENDING];
   1.491 -static int nr_pending;
   1.492 +	struct request *req;
   1.493 +	blkif_response_t *bret;
   1.494 +	RING_IDX i, rp;
   1.495 +	unsigned long flags;
   1.496 +	struct blkfront_info *info = (struct blkfront_info *)dev_id;
   1.497  
   1.498 -
   1.499 -#define blkif_io_lock io_request_lock
   1.500 -
   1.501 -/*============================================================================*/
   1.502 -static void kick_pending_request_queues(void)
   1.503 -{
   1.504 -    /* We kick pending request queues if the ring is reasonably empty. */
   1.505 -    if ( (nr_pending != 0) &&
   1.506 -         (RING_PENDING_REQUESTS(&info->ring) < (BLK_RING_SIZE >> 1)) )
   1.507 -    {
   1.508 -        /* Attempt to drain the queue, but bail if the ring becomes full. */
   1.509 -        while ( (nr_pending != 0) && !RING_FULL(&info->ring) )
   1.510 -            do_blkif_request(pending_queues[--nr_pending]);
   1.511 -    }
   1.512 -}
   1.513 -
   1.514 -int blkif_open(struct inode *inode, struct file *filep)
   1.515 -{
   1.516 -    short xldev = inode->i_rdev;
   1.517 -    struct gendisk *gd = get_gendisk(xldev);
   1.518 -    xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
   1.519 -    short minor = MINOR(xldev);
   1.520 -
   1.521 -    if ( gd->part[minor].nr_sects == 0 )
   1.522 -    {
   1.523 -        /*
   1.524 -         * Device either doesn't exist, or has zero capacity; we use a few
   1.525 -         * cheesy heuristics to return the relevant error code
   1.526 -         */
   1.527 -        if ( (gd->sizes[minor >> gd->minor_shift] != 0) ||
   1.528 -             ((minor & (gd->max_p - 1)) != 0) )
   1.529 -        {
   1.530 -            /*
   1.531 -             * We have a real device, but no such partition, or we just have a
   1.532 -             * partition number so guess this is the problem.
   1.533 -             */
   1.534 -            return -ENXIO;     /* no such device or address */
   1.535 -        }
   1.536 -        else if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE )
   1.537 -        {
   1.538 -            /* This is a removable device => assume that media is missing. */
   1.539 -            return -ENOMEDIUM; /* media not present (this is a guess) */
   1.540 -        }
   1.541 -        else
   1.542 -        {
   1.543 -            /* Just go for the general 'no such device' error. */
   1.544 -            return -ENODEV;    /* no such device */
   1.545 -        }
   1.546 -    }
   1.547 -
   1.548 -    /* Update of usage count is protected by per-device semaphore. */
   1.549 -    disk->usage++;
   1.550 -
   1.551 -    return 0;
   1.552 -}
   1.553 -
   1.554 -
   1.555 -int blkif_release(struct inode *inode, struct file *filep)
   1.556 -{
   1.557 -    xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
   1.558 -
   1.559 -    /*
   1.560 -     * When usage drops to zero it may allow more VBD updates to occur.
   1.561 -     * Update of usage count is protected by a per-device semaphore.
   1.562 -     */
   1.563 -    if ( --disk->usage == 0 ) {
   1.564 -        vbd_update();
   1.565 -    }
   1.566 -
   1.567 -    return 0;
   1.568 -}
   1.569 -
   1.570 +	spin_lock_irqsave(&blkif_io_lock, flags);
   1.571  
   1.572 -int blkif_ioctl(struct inode *inode, struct file *filep,
   1.573 -                unsigned command, unsigned long argument)
   1.574 -{
   1.575 -    kdev_t dev = inode->i_rdev;
   1.576 -    struct hd_geometry *geo = (struct hd_geometry *)argument;
   1.577 -    struct gendisk *gd;
   1.578 -    struct hd_struct *part;
   1.579 -    int i;
   1.580 -    unsigned short cylinders;
   1.581 -    byte heads, sectors;
   1.582 -
   1.583 -    /* NB. No need to check permissions. That is done for us. */
   1.584 -
   1.585 -    DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
   1.586 -                  command, (long) argument, dev);
   1.587 -
   1.588 -    gd = get_gendisk(dev);
   1.589 -    part = &gd->part[MINOR(dev)];
   1.590 -
   1.591 -    switch ( command )
   1.592 -    {
   1.593 -    case BLKGETSIZE:
   1.594 -        DPRINTK_IOCTL("   BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects);
   1.595 -        return put_user(part->nr_sects, (unsigned long *) argument);
   1.596 -
   1.597 -    case BLKGETSIZE64:
   1.598 -        DPRINTK_IOCTL("   BLKGETSIZE64: %x %llx\n", BLKGETSIZE64,
   1.599 -                      (u64)part->nr_sects * 512);
   1.600 -        return put_user((u64)part->nr_sects * 512, (u64 *) argument);
   1.601 -
   1.602 -    case BLKRRPART:                               /* re-read partition table */
   1.603 -        DPRINTK_IOCTL("   BLKRRPART: %x\n", BLKRRPART);
   1.604 -        return blkif_revalidate(dev);
   1.605 -
   1.606 -    case BLKSSZGET:
   1.607 -        return hardsect_size[MAJOR(dev)][MINOR(dev)];
   1.608 +	if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) {
   1.609 +		spin_unlock_irqrestore(&blkif_io_lock, flags);
   1.610 +		return IRQ_HANDLED;
   1.611 +	}
   1.612  
   1.613 -    case BLKBSZGET:                                        /* get block size */
   1.614 -        DPRINTK_IOCTL("   BLKBSZGET: %x\n", BLKBSZGET);
   1.615 -        break;
   1.616 -
   1.617 -    case BLKBSZSET:                                        /* set block size */
   1.618 -        DPRINTK_IOCTL("   BLKBSZSET: %x\n", BLKBSZSET);
   1.619 -        break;
   1.620 -
   1.621 -    case BLKRASET:                                         /* set read-ahead */
   1.622 -        DPRINTK_IOCTL("   BLKRASET: %x\n", BLKRASET);
   1.623 -        break;
   1.624 -
   1.625 -    case BLKRAGET:                                         /* get read-ahead */
   1.626 -        DPRINTK_IOCTL("   BLKRAFET: %x\n", BLKRAGET);
   1.627 -        break;
   1.628 -
   1.629 -    case HDIO_GETGEO:
   1.630 -        DPRINTK_IOCTL("   HDIO_GETGEO: %x\n", HDIO_GETGEO);
   1.631 -        if (!argument) return -EINVAL;
   1.632 -
   1.633 -        /* We don't have real geometry info, but let's at least return
   1.634 -           values consistent with the size of the device */
   1.635 -
   1.636 -        heads = 0xff;
   1.637 -        sectors = 0x3f;
   1.638 -        cylinders = part->nr_sects / (heads * sectors);
   1.639 -
   1.640 -        if (put_user(0x00,  (unsigned long *) &geo->start)) return -EFAULT;
   1.641 -        if (put_user(heads,  (byte *)&geo->heads)) return -EFAULT;
   1.642 -        if (put_user(sectors,  (byte *)&geo->sectors)) return -EFAULT;
   1.643 -        if (put_user(cylinders, (unsigned short *)&geo->cylinders)) return -EFAULT;
   1.644 -
   1.645 -        return 0;
   1.646 -
   1.647 -    case HDIO_GETGEO_BIG:
   1.648 -        DPRINTK_IOCTL("   HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG);
   1.649 -        if (!argument) return -EINVAL;
   1.650 -
   1.651 -        /* We don't have real geometry info, but let's at least return
   1.652 -           values consistent with the size of the device */
   1.653 +	rp = info->ring.sring->rsp_prod;
   1.654 +	rmb(); /* Ensure we see queued responses up to 'rp'. */
   1.655  
   1.656 -        heads = 0xff;
   1.657 -        sectors = 0x3f;
   1.658 -        cylinders = part->nr_sects / (heads * sectors);
   1.659 -
   1.660 -        if (put_user(0x00,  (unsigned long *) &geo->start))  return -EFAULT;
   1.661 -        if (put_user(heads,  (byte *)&geo->heads))   return -EFAULT;
   1.662 -        if (put_user(sectors,  (byte *)&geo->sectors)) return -EFAULT;
   1.663 -        if (put_user(cylinders, (unsigned int *) &geo->cylinders)) return -EFAULT;
   1.664 -
   1.665 -        return 0;
   1.666 -
   1.667 -    case CDROMMULTISESSION:
   1.668 -        DPRINTK("FIXME: support multisession CDs later\n");
   1.669 -        for ( i = 0; i < sizeof(struct cdrom_multisession); i++ )
   1.670 -            if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT;
   1.671 -        return 0;
   1.672 -
   1.673 -    case SCSI_IOCTL_GET_BUS_NUMBER:
   1.674 -        DPRINTK("FIXME: SCSI_IOCTL_GET_BUS_NUMBER ioctl in XL blkif");
   1.675 -        return -ENOSYS;
   1.676 -
   1.677 -    default:
   1.678 -        WPRINTK("ioctl %08x not supported by XL blkif\n", command);
   1.679 -        return -ENOSYS;
   1.680 -    }
   1.681 -
   1.682 -    return 0;
   1.683 -}
   1.684 -
   1.685 -
   1.686 -
   1.687 -/* check media change: should probably do something here in some cases :-) */
   1.688 -int blkif_check(kdev_t dev)
   1.689 -{
   1.690 -    DPRINTK("blkif_check\n");
   1.691 -    return 0;
   1.692 -}
   1.693 +	for (i = info->ring.rsp_cons; i != rp; i++) {
   1.694 +		unsigned long id;
   1.695  
   1.696 -int blkif_revalidate(kdev_t dev)
   1.697 -{
   1.698 -    struct block_device *bd;
   1.699 -    struct gendisk *gd;
   1.700 -    xl_disk_t *disk;
   1.701 -    unsigned long capacity;
   1.702 -    int i, rc = 0;
   1.703 -
   1.704 -    if ( (bd = bdget(dev)) == NULL )
   1.705 -        return -EINVAL;
   1.706 -
   1.707 -    /*
   1.708 -     * Update of partition info, and check of usage count, is protected
   1.709 -     * by the per-block-device semaphore.
   1.710 -     */
   1.711 -    down(&bd->bd_sem);
   1.712 +		bret = RING_GET_RESPONSE(&info->ring, i);
   1.713 +		id   = bret->id;
   1.714 +		req  = (struct request *)blk_shadow[id].request;
   1.715  
   1.716 -    if ( ((gd = get_gendisk(dev)) == NULL) ||
   1.717 -         ((disk = xldev_to_xldisk(dev)) == NULL) ||
   1.718 -         ((capacity = gd->part[MINOR(dev)].nr_sects) == 0) )
   1.719 -    {
   1.720 -        rc = -EINVAL;
   1.721 -        goto out;
   1.722 -    }
   1.723 -
   1.724 -    if ( disk->usage > 1 )
   1.725 -    {
   1.726 -        rc = -EBUSY;
   1.727 -        goto out;
   1.728 -    }
   1.729 -
   1.730 -    /* Only reread partition table if VBDs aren't mapped to partitions. */
   1.731 -    if ( !(gd->flags[MINOR(dev) >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) )
   1.732 -    {
   1.733 -        for ( i = gd->max_p - 1; i >= 0; i-- )
   1.734 -        {
   1.735 -            invalidate_device(dev+i, 1);
   1.736 -            gd->part[MINOR(dev+i)].start_sect = 0;
   1.737 -            gd->part[MINOR(dev+i)].nr_sects   = 0;
   1.738 -            gd->sizes[MINOR(dev+i)]           = 0;
   1.739 -        }
   1.740 +		blkif_completion(&blk_shadow[id]);
   1.741  
   1.742 -        grok_partitions(gd, MINOR(dev)>>gd->minor_shift, gd->max_p, capacity);
   1.743 -    }
   1.744 -
   1.745 - out:
   1.746 -    up(&bd->bd_sem);
   1.747 -    bdput(bd);
   1.748 -    return rc;
   1.749 -}
   1.750 -
   1.751 -
   1.752 -/*
   1.753 - * blkif_queue_request
   1.754 - *
   1.755 - * request block io
   1.756 - * 
   1.757 - * id: for guest use only.
   1.758 - * operation: BLKIF_OP_{READ,WRITE,PROBE}
   1.759 - * buffer: buffer to read/write into. this should be a
   1.760 - *   virtual address in the guest os.
   1.761 - */
   1.762 -static int blkif_queue_request(unsigned long   id,
   1.763 -                               int             operation,
   1.764 -                               char *          buffer,
   1.765 -                               unsigned long   sector_number,
   1.766 -                               unsigned short  nr_sectors,
   1.767 -                               kdev_t          device,
   1.768 -			       blkif_vdev_t    handle)
   1.769 -{
   1.770 -    unsigned long       buffer_ma = virt_to_bus(buffer);
   1.771 -    unsigned long       xid;
   1.772 -    struct gendisk     *gd;
   1.773 -    blkif_request_t    *req;
   1.774 -    struct buffer_head *bh;
   1.775 -    unsigned int        fsect, lsect;
   1.776 -    int ref;
   1.777 -
   1.778 -    fsect = (buffer_ma & ~PAGE_MASK) >> 9;
   1.779 -    lsect = fsect + nr_sectors - 1;
   1.780 -
   1.781 -    /* Buffer must be sector-aligned. Extent mustn't cross a page boundary. */
   1.782 -    if ( unlikely((buffer_ma & ((1<<9)-1)) != 0) )
   1.783 -        BUG();
   1.784 -    if ( lsect > ((PAGE_SIZE/512)-1) )
   1.785 -        BUG();
   1.786 -
   1.787 -    buffer_ma &= PAGE_MASK;
   1.788 -
   1.789 -    if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
   1.790 -        return 1;
   1.791 -
   1.792 -    switch ( operation )
   1.793 -    {
   1.794 -
   1.795 -    case BLKIF_OP_READ:
   1.796 -    case BLKIF_OP_WRITE:
   1.797 -        gd = get_gendisk(device);
   1.798 -
   1.799 -        /*
   1.800 -         * Update the sector_number we'll pass down as appropriate; note that
   1.801 -         * we could sanity check that resulting sector will be in this
   1.802 -         * partition, but this will happen in driver backend anyhow.
   1.803 -         */
   1.804 -        sector_number += gd->part[MINOR(device)].start_sect;
   1.805 -
   1.806 -        /*
   1.807 -         * If this unit doesn't consist of virtual partitions then we clear
   1.808 -         * the partn bits from the device number.
   1.809 -         */
   1.810 -        if ( !(gd->flags[MINOR(device)>>gd->minor_shift] &
   1.811 -               GENHD_FL_VIRT_PARTNS) )
   1.812 -            device &= ~(gd->max_p - 1);
   1.813 +		ADD_ID_TO_FREELIST(id);
   1.814  
   1.815 -        if ( (sg_operation == operation) &&
   1.816 -             (sg_dev == device) &&
   1.817 -             (sg_next_sect == sector_number) )
   1.818 -        {
   1.819 -            req = RING_GET_REQUEST(&info->ring,
   1.820 -                                   info->ring.req_prod_pvt - 1);
   1.821 -            bh = (struct buffer_head *)id;
   1.822 -
   1.823 -            bh->b_reqnext = (struct buffer_head *)blk_shadow[req->id].request;
   1.824 -            blk_shadow[req->id].request = (unsigned long)id;
   1.825 -
   1.826 -            /* install a grant reference. */
   1.827 -            ref = gnttab_claim_grant_reference(&gref_head);
   1.828 -            ASSERT( ref != -ENOSPC );
   1.829 -
   1.830 -            gnttab_grant_foreign_access_ref(
   1.831 -                        ref,
   1.832 -                        info->backend_id,
   1.833 -                        buffer_ma >> PAGE_SHIFT,
   1.834 -                        ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
   1.835 -
   1.836 -            blk_shadow[req->id].frame[req->nr_segments] =
   1.837 -                buffer_ma >> PAGE_SHIFT;
   1.838 -
   1.839 -            req->frame_and_sects[req->nr_segments] =
   1.840 -                blkif_fas_from_gref(ref, fsect, lsect);
   1.841 -            if ( ++req->nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST )
   1.842 -                sg_next_sect += nr_sectors;
   1.843 -            else
   1.844 -                DISABLE_SCATTERGATHER();
   1.845 -
   1.846 -            /* Update the copy of the request in the recovery ring. */
   1.847 -            pickle_request(&blk_shadow[req->id], req );
   1.848 -
   1.849 -            return 0;
   1.850 -        }
   1.851 -        else if ( RING_FULL(&info->ring) )
   1.852 -        {
   1.853 -            return 1;
   1.854 -        }
   1.855 -        else
   1.856 -        {
   1.857 -            sg_operation = operation;
   1.858 -            sg_dev       = device;
   1.859 -            sg_next_sect = sector_number + nr_sectors;
   1.860 -        }
   1.861 -        break;
   1.862 -
   1.863 -    default:
   1.864 -        panic("unknown op %d\n", operation);
   1.865 -    }
   1.866 -
   1.867 -    /* Fill out a communications ring structure. */
   1.868 -    req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
   1.869 -
   1.870 -    xid = GET_ID_FROM_FREELIST();
   1.871 -    blk_shadow[xid].request = (unsigned long)id;
   1.872 -
   1.873 -    req->id            = xid;
   1.874 -    req->operation     = operation;
   1.875 -    req->sector_number = (blkif_sector_t)sector_number;
   1.876 -    req->handle        = handle;
   1.877 -    req->nr_segments   = 1;
   1.878 -    /* install a grant reference. */
   1.879 -    ref = gnttab_claim_grant_reference(&gref_head);
   1.880 -    ASSERT( ref != -ENOSPC );
   1.881 -
   1.882 -    gnttab_grant_foreign_access_ref(
   1.883 -                ref,
   1.884 -                info->backend_id,
   1.885 -                buffer_ma >> PAGE_SHIFT,
   1.886 -                ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
   1.887 -
   1.888 -    blk_shadow[xid].frame[0] = buffer_ma >> PAGE_SHIFT;
   1.889 -
   1.890 -    req->frame_and_sects[0] = blkif_fas_from_gref(ref, fsect, lsect);
   1.891 -
   1.892 -    /* Keep a private copy so we can reissue requests when recovering. */
   1.893 -    pickle_request(&blk_shadow[xid], req);
   1.894 +		switch (bret->operation) {
   1.895 +		case BLKIF_OP_READ:
   1.896 +		case BLKIF_OP_WRITE:
   1.897 +			if (unlikely(bret->status != BLKIF_RSP_OKAY))
   1.898 +				DPRINTK("Bad return from blkdev data "
   1.899 +					"request: %x\n", bret->status);
   1.900  
   1.901 -    info->ring.req_prod_pvt++;
   1.902 -
   1.903 -    return 0;
   1.904 -}
   1.905 -
   1.906 -
   1.907 -/*
   1.908 - * do_blkif_request
   1.909 - *  read a block; request is in a request queue
   1.910 - */
   1.911 -void do_blkif_request(request_queue_t *rq)
   1.912 -{
   1.913 -    struct request *req;
   1.914 -    struct buffer_head *bh, *next_bh;
   1.915 -    int rw, nsect, full, queued = 0;
   1.916 -
   1.917 -    DPRINTK("Entered do_blkif_request\n");
   1.918 -
   1.919 -    while ( !rq->plugged && !list_empty(&rq->queue_head))
   1.920 -    {
   1.921 -        if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL )
   1.922 -            goto out;
   1.923 -
   1.924 -        DPRINTK("do_blkif_request %p: cmd %i, sec %lx, (%li/%li) bh:%p\n",
   1.925 -                req, req->cmd, req->sector,
   1.926 -                req->current_nr_sectors, req->nr_sectors, req->bh);
   1.927 -
   1.928 -        rw = req->cmd;
   1.929 -        if ( rw == READA )
   1.930 -            rw = READ;
   1.931 -        if ( unlikely((rw != READ) && (rw != WRITE)) )
   1.932 -            panic("XenoLinux Virtual Block Device: bad cmd: %d\n", rw);
   1.933 -
   1.934 -        req->errors = 0;
   1.935 -
   1.936 -        bh = req->bh;
   1.937 -        while ( bh != NULL )
   1.938 -        {
   1.939 -            next_bh = bh->b_reqnext;
   1.940 -            bh->b_reqnext = NULL;
   1.941 -
   1.942 -            full = blkif_queue_request(
   1.943 -                (unsigned long)bh,
   1.944 -                (rw == READ) ? BLKIF_OP_READ : BLKIF_OP_WRITE,
   1.945 -                bh->b_data, bh->b_rsector, bh->b_size>>9, bh->b_rdev);
   1.946 -
   1.947 -            if ( full )
   1.948 -            {
   1.949 -                bh->b_reqnext = next_bh;
   1.950 -                pending_queues[nr_pending++] = rq;
   1.951 -                if ( unlikely(nr_pending >= MAX_PENDING) )
   1.952 -                    BUG();
   1.953 -                goto out;
   1.954 -            }
   1.955 -
   1.956 -            queued++;
   1.957 -
   1.958 -            /* Dequeue the buffer head from the request. */
   1.959 -            nsect = bh->b_size >> 9;
   1.960 -            bh = req->bh = next_bh;
   1.961 +			BUG_ON(end_that_request_first(
   1.962 +				req, (bret->status == BLKIF_RSP_OKAY),
   1.963 +				req->hard_nr_sectors));
   1.964 +			end_that_request_last(req);
   1.965 +			break;
   1.966 +		default:
   1.967 +			BUG();
   1.968 +		}
   1.969 +	}
   1.970  
   1.971 -            if ( bh != NULL )
   1.972 -            {
   1.973 -                /* There's another buffer head to do. Update the request. */
   1.974 -                req->hard_sector += nsect;
   1.975 -                req->hard_nr_sectors -= nsect;
   1.976 -                req->sector = req->hard_sector;
   1.977 -                req->nr_sectors = req->hard_nr_sectors;
   1.978 -                req->current_nr_sectors = bh->b_size >> 9;
   1.979 -                req->buffer = bh->b_data;
   1.980 -            }
   1.981 -            else
   1.982 -            {
   1.983 -                /* That was the last buffer head. Finalise the request. */
   1.984 -                if ( unlikely(end_that_request_first(req, 1, "XenBlk")) )
   1.985 -                    BUG();
   1.986 -                blkdev_dequeue_request(req);
   1.987 -                end_that_request_last(req);
   1.988 -            }
   1.989 -        }
   1.990 -    }
   1.991 +	info->ring.rsp_cons = i;
   1.992  
   1.993 - out:
   1.994 -    if ( queued != 0 )
   1.995 -        flush_requests();
   1.996 -}
   1.997 -
   1.998 -
   1.999 -static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
  1.1000 -{
  1.1001 -    RING_IDX i, rp;
  1.1002 -    unsigned long flags;
  1.1003 -    struct buffer_head *bh, *next_bh;
  1.1004 -
  1.1005 -    spin_lock_irqsave(&io_request_lock, flags);
  1.1006 -
  1.1007 -    if ( unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery) )
  1.1008 -    {
  1.1009 -        spin_unlock_irqrestore(&io_request_lock, flags);
  1.1010 -        return;
  1.1011 -    }
  1.1012 -
  1.1013 -    rp = info->ring.sring->rsp_prod;
  1.1014 -    rmb(); /* Ensure we see queued responses up to 'rp'. */
  1.1015 +	kick_pending_request_queues(info);
  1.1016  
  1.1017 -    for ( i = info->ring.rsp_cons; i != rp; i++ )
  1.1018 -    {
  1.1019 -        unsigned long id;
  1.1020 -        blkif_response_t *bret;
  1.1021 -
  1.1022 -        bret = RING_GET_RESPONSE(&info->ring, i);
  1.1023 -        id = bret->id;
  1.1024 -        bh = (struct buffer_head *)blk_shadow[id].request;
  1.1025 -
  1.1026 -        blkif_completion(&blk_shadow[id]);
  1.1027 -
  1.1028 -        ADD_ID_TO_FREELIST(id);
  1.1029 +	spin_unlock_irqrestore(&blkif_io_lock, flags);
  1.1030  
  1.1031 -        switch ( bret->operation )
  1.1032 -        {
  1.1033 -        case BLKIF_OP_READ:
  1.1034 -        case BLKIF_OP_WRITE:
  1.1035 -            if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
  1.1036 -                DPRINTK("Bad return from blkdev data request: %lx\n",
  1.1037 -                        bret->status);
  1.1038 -            for ( ; bh != NULL; bh = next_bh )
  1.1039 -            {
  1.1040 -                next_bh = bh->b_reqnext;
  1.1041 -                bh->b_reqnext = NULL;
  1.1042 -                bh->b_end_io(bh, bret->status == BLKIF_RSP_OKAY);
  1.1043 -            }
  1.1044 -
  1.1045 -            break;
  1.1046 -        case BLKIF_OP_PROBE:
  1.1047 -            memcpy(&blkif_control_rsp, bret, sizeof(*bret));
  1.1048 -            blkif_control_rsp_valid = 1;
  1.1049 -            break;
  1.1050 -        default:
  1.1051 -            BUG();
  1.1052 -        }
  1.1053 -
  1.1054 -    }
  1.1055 -    info->ring.rsp_cons = i;
  1.1056 -
  1.1057 -    kick_pending_request_queues();
  1.1058 -
  1.1059 -    spin_unlock_irqrestore(&io_request_lock, flags);
  1.1060 +	return IRQ_HANDLED;
  1.1061  }
  1.1062  
  1.1063 -#endif
  1.1064 -
  1.1065 -/*****************************  COMMON CODE  *******************************/
  1.1066 -
  1.1067  static void blkif_free(struct blkfront_info *info)
  1.1068  {
  1.1069 -    /* Prevent new requests being issued until we fix things up. */
  1.1070 -    spin_lock_irq(&blkif_io_lock);
  1.1071 -    info->connected = BLKIF_STATE_DISCONNECTED;
  1.1072 -    spin_unlock_irq(&blkif_io_lock);
  1.1073 +	/* Prevent new requests being issued until we fix things up. */
  1.1074 +	spin_lock_irq(&blkif_io_lock);
  1.1075 +	info->connected = BLKIF_STATE_DISCONNECTED;
  1.1076 +	spin_unlock_irq(&blkif_io_lock);
  1.1077  
  1.1078 -    /* Free resources associated with old device channel. */
  1.1079 -    if ( info->ring.sring != NULL )
  1.1080 -    {
  1.1081 -        free_page((unsigned long)info->ring.sring);
  1.1082 -        info->ring.sring = NULL;
  1.1083 -    }
  1.1084 -    unbind_evtchn_from_irqhandler(info->evtchn, NULL);
  1.1085 -    info->evtchn = 0;
  1.1086 +	/* Free resources associated with old device channel. */
  1.1087 +	if (info->ring.sring != NULL) {
  1.1088 +		free_page((unsigned long)info->ring.sring);
  1.1089 +		info->ring.sring = NULL;
  1.1090 +	}
  1.1091 +	unbind_evtchn_from_irqhandler(info->evtchn, NULL);
  1.1092 +	info->evtchn = 0;
  1.1093  }
  1.1094  
  1.1095  static void blkif_recover(struct blkfront_info *info)
  1.1096  {
  1.1097 -    int i;
  1.1098 -    blkif_request_t *req;
  1.1099 -    struct blk_shadow *copy;
  1.1100 -    int j;
  1.1101 +	int i;
  1.1102 +	blkif_request_t *req;
  1.1103 +	struct blk_shadow *copy;
  1.1104 +	int j;
  1.1105  
  1.1106 -    /* Stage 1: Make a safe copy of the shadow state. */
  1.1107 -    copy = (struct blk_shadow *)kmalloc(sizeof(blk_shadow), GFP_KERNEL);
  1.1108 -    BUG_ON(copy == NULL);
  1.1109 -    memcpy(copy, blk_shadow, sizeof(blk_shadow));
  1.1110 +	/* Stage 1: Make a safe copy of the shadow state. */
  1.1111 +	copy = (struct blk_shadow *)kmalloc(sizeof(blk_shadow), GFP_KERNEL);
  1.1112 +	BUG_ON(copy == NULL);
  1.1113 +	memcpy(copy, blk_shadow, sizeof(blk_shadow));
  1.1114  
  1.1115 -    /* Stage 2: Set up free list. */
  1.1116 -    memset(&blk_shadow, 0, sizeof(blk_shadow));
  1.1117 -    for ( i = 0; i < BLK_RING_SIZE; i++ )
  1.1118 -        blk_shadow[i].req.id = i+1;
  1.1119 -    blk_shadow_free = info->ring.req_prod_pvt;
  1.1120 -    blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  1.1121 +	/* Stage 2: Set up free list. */
  1.1122 +	memset(&blk_shadow, 0, sizeof(blk_shadow));
  1.1123 +	for (i = 0; i < BLK_RING_SIZE; i++)
  1.1124 +		blk_shadow[i].req.id = i+1;
  1.1125 +	blk_shadow_free = info->ring.req_prod_pvt;
  1.1126 +	blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  1.1127  
  1.1128 -    /* Stage 3: Find pending requests and requeue them. */
  1.1129 -    for ( i = 0; i < BLK_RING_SIZE; i++ )
  1.1130 -    {
  1.1131 -        /* Not in use? */
  1.1132 -        if ( copy[i].request == 0 )
  1.1133 -            continue;
  1.1134 +	/* Stage 3: Find pending requests and requeue them. */
  1.1135 +	for (i = 0; i < BLK_RING_SIZE; i++) {
  1.1136 +		/* Not in use? */
  1.1137 +		if (copy[i].request == 0)
  1.1138 +			continue;
  1.1139  
  1.1140 -        /* Grab a request slot and unpickle shadow state into it. */
  1.1141 -        req = RING_GET_REQUEST(
  1.1142 -            &info->ring, info->ring.req_prod_pvt);
  1.1143 -        unpickle_request(req, &copy[i]);
  1.1144 +		/* Grab a request slot and unpickle shadow state into it. */
  1.1145 +		req = RING_GET_REQUEST(
  1.1146 +			&info->ring, info->ring.req_prod_pvt);
  1.1147 +		unpickle_request(req, &copy[i]);
  1.1148  
  1.1149 -        /* We get a new request id, and must reset the shadow state. */
  1.1150 -        req->id = GET_ID_FROM_FREELIST();
  1.1151 -        memcpy(&blk_shadow[req->id], &copy[i], sizeof(copy[i]));
  1.1152 +		/* We get a new request id, and must reset the shadow state. */
  1.1153 +		req->id = GET_ID_FROM_FREELIST();
  1.1154 +		memcpy(&blk_shadow[req->id], &copy[i], sizeof(copy[i]));
  1.1155  
  1.1156 -        /* Rewrite any grant references invalidated by suspend/resume. */
  1.1157 -        for ( j = 0; j < req->nr_segments; j++ )
  1.1158 -        {
  1.1159 -            if ( req->frame_and_sects[j] & GRANTREF_INVALID )
  1.1160 -                gnttab_grant_foreign_access_ref(
  1.1161 -                    blkif_gref_from_fas(req->frame_and_sects[j]),
  1.1162 -                    info->backend_id,
  1.1163 -                    blk_shadow[req->id].frame[j],
  1.1164 -                    rq_data_dir((struct request *)
  1.1165 -                                blk_shadow[req->id].request));
  1.1166 -            req->frame_and_sects[j] &= ~GRANTREF_INVALID;
  1.1167 -        }
  1.1168 -        blk_shadow[req->id].req = *req;
  1.1169 +		/* Rewrite any grant references invalidated by susp/resume. */
  1.1170 +		for (j = 0; j < req->nr_segments; j++) {
  1.1171 +			if ( req->frame_and_sects[j] & GRANTREF_INVALID )
  1.1172 +				gnttab_grant_foreign_access_ref(
  1.1173 +					blkif_gref_from_fas(
  1.1174 +						req->frame_and_sects[j]),
  1.1175 +					info->backend_id,
  1.1176 +					blk_shadow[req->id].frame[j],
  1.1177 +					rq_data_dir(
  1.1178 +						(struct request *)
  1.1179 +						blk_shadow[req->id].request));
  1.1180 +			req->frame_and_sects[j] &= ~GRANTREF_INVALID;
  1.1181 +		}
  1.1182 +		blk_shadow[req->id].req = *req;
  1.1183  
  1.1184 -        info->ring.req_prod_pvt++;
  1.1185 -    }
  1.1186 +		info->ring.req_prod_pvt++;
  1.1187 +	}
  1.1188  
  1.1189 -    kfree(copy);
  1.1190 +	kfree(copy);
  1.1191  
  1.1192 -    recovery = 0;
  1.1193 +	recovery = 0;
  1.1194  
  1.1195 -    /* info->ring->req_prod will be set when we flush_requests().*/
  1.1196 -    wmb();
  1.1197 +	/* info->ring->req_prod will be set when we flush_requests().*/
  1.1198 +	wmb();
  1.1199  
  1.1200 -    /* Kicks things back into life. */
  1.1201 -    flush_requests(info);
  1.1202 +	/* Kicks things back into life. */
  1.1203 +	flush_requests(info);
  1.1204  
  1.1205 -    /* Now safe to left other people use the interface. */
  1.1206 -    info->connected = BLKIF_STATE_CONNECTED;
  1.1207 +	/* Now safe to left other people use the interface. */
  1.1208 +	info->connected = BLKIF_STATE_CONNECTED;
  1.1209  }
  1.1210  
  1.1211  static void blkif_connect(struct blkfront_info *info, u16 evtchn)
  1.1212  {
  1.1213 -    int err = 0;
  1.1214 +	int err = 0;
  1.1215  
  1.1216 -    info->evtchn = evtchn;
  1.1217 +	info->evtchn = evtchn;
  1.1218  
  1.1219 -    err = bind_evtchn_to_irqhandler(
  1.1220 -        info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
  1.1221 -    if ( err != 0 )
  1.1222 -    {
  1.1223 -        WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  1.1224 -        return;
  1.1225 -    }
  1.1226 +	err = bind_evtchn_to_irqhandler(
  1.1227 +		info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
  1.1228 +	if (err != 0) {
  1.1229 +		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  1.1230 +		return;
  1.1231 +	}
  1.1232  }
  1.1233  
  1.1234  
  1.1235 @@ -1329,55 +730,65 @@ static void __init init_blk_xenbus(void)
  1.1236  
  1.1237  static int wait_for_blkif(void)
  1.1238  {
  1.1239 -    int err = 0;
  1.1240 -    int i;
  1.1241 +	int err = 0;
  1.1242 +	int i;
  1.1243  
  1.1244 -    /*
  1.1245 -     * We should figure out how many and which devices we need to
  1.1246 -     * proceed and only wait for those.  For now, continue once the
  1.1247 -     * first device is around.
  1.1248 -     */
  1.1249 -    for ( i=0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++ )
  1.1250 -    {
  1.1251 -        set_current_state(TASK_INTERRUPTIBLE);
  1.1252 -        schedule_timeout(1);
  1.1253 -    }
  1.1254 +	/*
  1.1255 +	 * We should figure out how many and which devices we need to
  1.1256 +	 * proceed and only wait for those.  For now, continue once the
  1.1257 +	 * first device is around.
  1.1258 +	 */
  1.1259 +	for (i = 0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++) {
  1.1260 +		set_current_state(TASK_INTERRUPTIBLE);
  1.1261 +		schedule_timeout(1);
  1.1262 +	}
  1.1263  
  1.1264 -    if ( blkif_state != BLKIF_STATE_CONNECTED )
  1.1265 -    {
  1.1266 -        WPRINTK("Timeout connecting to device!\n");
  1.1267 -        err = -ENOSYS;
  1.1268 -    }
  1.1269 -    return err;
  1.1270 +	if (blkif_state != BLKIF_STATE_CONNECTED) {
  1.1271 +		WPRINTK("Timeout connecting to device!\n");
  1.1272 +		err = -ENOSYS;
  1.1273 +	}
  1.1274 +	return err;
  1.1275  }
  1.1276  
  1.1277  static int __init xlblk_init(void)
  1.1278  {
  1.1279 -    int i;
  1.1280 +	int i;
  1.1281  
  1.1282 -    if ( (xen_start_info.flags & SIF_INITDOMAIN) ||
  1.1283 -         (xen_start_info.flags & SIF_BLK_BE_DOMAIN) )
  1.1284 -        return 0;
  1.1285 +	if ((xen_start_info.flags & SIF_INITDOMAIN)
  1.1286 +	    || (xen_start_info.flags & SIF_BLK_BE_DOMAIN) )
  1.1287 +		return 0;
  1.1288  
  1.1289 -    IPRINTK("Initialising virtual block device driver\n");
  1.1290 +	IPRINTK("Initialising virtual block device driver\n");
  1.1291  
  1.1292 -    blk_shadow_free = 0;
  1.1293 -    memset(blk_shadow, 0, sizeof(blk_shadow));
  1.1294 -    for ( i = 0; i < BLK_RING_SIZE; i++ )
  1.1295 -        blk_shadow[i].req.id = i+1;
  1.1296 -    blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  1.1297 +	blk_shadow_free = 0;
  1.1298 +	memset(blk_shadow, 0, sizeof(blk_shadow));
  1.1299 +	for (i = 0; i < BLK_RING_SIZE; i++)
  1.1300 +		blk_shadow[i].req.id = i+1;
  1.1301 +	blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  1.1302  
  1.1303 -    init_blk_xenbus();
  1.1304 +	init_blk_xenbus();
  1.1305 +
  1.1306 +	wait_for_blkif();
  1.1307  
  1.1308 -    wait_for_blkif();
  1.1309 +	return 0;
  1.1310 +}
  1.1311  
  1.1312 -    return 0;
  1.1313 -}
  1.1314 +module_init(xlblk_init);
  1.1315  
  1.1316  static void blkif_completion(struct blk_shadow *s)
  1.1317  {
  1.1318 -    int i;
  1.1319 -    for ( i = 0; i < s->req.nr_segments; i++ )
  1.1320 -        gnttab_free_grant_reference(
  1.1321 -		blkif_gref_from_fas(s->req.frame_and_sects[i]));
  1.1322 +	int i;
  1.1323 +	for (i = 0; i < s->req.nr_segments; i++)
  1.1324 +		gnttab_free_grant_reference(
  1.1325 +			blkif_gref_from_fas(s->req.frame_and_sects[i]));
  1.1326  }
  1.1327 +
  1.1328 +/*
  1.1329 + * Local variables:
  1.1330 + *  c-file-style: "linux"
  1.1331 + *  indent-tabs-mode: t
  1.1332 + *  c-indent-level: 8
  1.1333 + *  c-basic-offset: 8
  1.1334 + *  tab-width: 8
  1.1335 + * End:
  1.1336 + */
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Sat Aug 27 11:49:35 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Sun Aug 28 14:21:08 2005 +0000
     2.3 @@ -116,9 +116,7 @@ struct blkfront_info
     2.4  	blkif_front_ring_t ring;
     2.5  	unsigned int evtchn;
     2.6  	struct xlbd_major_info *mi;
     2.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     2.8  	request_queue_t *rq;
     2.9 -#endif
    2.10  	struct work_struct work;
    2.11  	struct gnttab_free_callback callback;
    2.12  };