diff options
Diffstat (limited to 'drivers/message/i2o/i2o_block.c')
| -rw-r--r-- | drivers/message/i2o/i2o_block.c | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index e39986a7827..6fc3866965d 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -51,7 +51,9 @@ */ #include <linux/module.h> +#include <linux/slab.h> #include <linux/i2o.h> +#include <linux/mutex.h> #include <linux/mempool.h> @@ -67,6 +69,7 @@ #define OSM_VERSION "1.325" #define OSM_DESCRIPTION "I2O Block Device OSM" +static DEFINE_MUTEX(i2o_block_mutex); static struct i2o_driver i2o_block_driver; /* global Block OSM request mempool */ @@ -306,7 +309,7 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq) * @ireq: I2O block request * @mptr: message body pointer * - * Builds the SG list and map it to be accessable by the controller. + * Builds the SG list and map it to be accessible by the controller. * * Returns 0 on failure or 1 on success. */ @@ -576,6 +579,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) if (!dev->i2o_dev) return -ENODEV; + mutex_lock(&i2o_block_mutex); if (dev->power > 0x1f) i2o_block_device_power(dev, 0x02); @@ -584,6 +588,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) i2o_block_device_lock(dev->i2o_dev, -1); osm_debug("Ready.\n"); + mutex_unlock(&i2o_block_mutex); return 0; }; @@ -595,25 +600,24 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) * * Unlock and unmount the media, and power down the device. Gets called if * the block device is closed. - * - * Returns 0 on success or negative error code on failure. */ -static int i2o_block_release(struct gendisk *disk, fmode_t mode) +static void i2o_block_release(struct gendisk *disk, fmode_t mode) { struct i2o_block_device *dev = disk->private_data; u8 operation; /* - * This is to deail with the case of an application - * opening a device and then the device dissapears while + * This is to deal with the case of an application + * opening a device and then the device disappears while * it's in use, and then the application tries to release * it. ex: Unmounting a deleted RAID volume at reboot. * If we send messages, it will just cause FAILs since * the TID no longer exists. */ if (!dev->i2o_dev) - return 0; + return; + mutex_lock(&i2o_block_mutex); i2o_block_device_flush(dev->i2o_dev); i2o_block_device_unlock(dev->i2o_dev, -1); @@ -624,8 +628,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) operation = 0x24; i2o_block_device_power(dev, operation); - - return 0; + mutex_unlock(&i2o_block_mutex); } static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo) @@ -651,54 +654,66 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode, { struct gendisk *disk = bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; + int ret = -ENOTTY; /* Anyone capable of this syscall can do *real bad* things */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; + mutex_lock(&i2o_block_mutex); switch (cmd) { case BLKI2OGRSTRAT: - return put_user(dev->rcache, (int __user *)arg); + ret = put_user(dev->rcache, (int __user *)arg); + break; case BLKI2OGWSTRAT: - return put_user(dev->wcache, (int __user *)arg); + ret = put_user(dev->wcache, (int __user *)arg); + break; case BLKI2OSRSTRAT: + ret = -EINVAL; if (arg < 0 || arg > CACHE_SMARTFETCH) - return -EINVAL; + break; dev->rcache = arg; + ret = 0; break; case BLKI2OSWSTRAT: + ret = -EINVAL; if (arg != 0 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) - return -EINVAL; + break; dev->wcache = arg; + ret = 0; break; } - return -ENOTTY; + mutex_unlock(&i2o_block_mutex); + + return ret; }; /** - * i2o_block_media_changed - Have we seen a media change? + * i2o_block_check_events - Have we seen a media change? * @disk: gendisk which should be verified + * @clearing: events being cleared * * Verifies if the media has changed. * * Returns 1 if the media was changed or 0 otherwise. */ -static int i2o_block_media_changed(struct gendisk *disk) +static unsigned int i2o_block_check_events(struct gendisk *disk, + unsigned int clearing) { struct i2o_block_device *p = disk->private_data; if (p->media_change_flag) { p->media_change_flag = 0; - return 1; + return DISK_EVENT_MEDIA_CHANGE; } return 0; } /** * i2o_block_transfer - Transfer a request to/from the I2O controller - * @req: the request which should be transfered + * @req: the request which should be transferred * * This function converts the request into a I2O message. The necessary * DMA buffers are allocated and after everything is setup post the message @@ -711,7 +726,7 @@ static int i2o_block_transfer(struct request *req) { struct i2o_block_device *dev = req->rq_disk->private_data; struct i2o_controller *c; - u32 tid = dev->i2o_dev->lct_data.tid; + u32 tid; struct i2o_message *msg; u32 *mptr; struct i2o_block_request *ireq = req->special; @@ -727,6 +742,7 @@ static int i2o_block_transfer(struct request *req) goto exit; } + tid = dev->i2o_dev->lct_data.tid; c = dev->i2o_dev->iop; msg = i2o_msg_get(c); @@ -877,12 +893,8 @@ static void i2o_block_request_fn(struct request_queue *q) { struct request *req; - while (!blk_queue_plugged(q)) { - req = blk_peek_request(q); - if (!req) - break; - - if (blk_fs_request(req)) { + while ((req = blk_peek_request(q)) != NULL) { + if (req->cmd_type == REQ_TYPE_FS) { struct i2o_block_delayed_request *dreq; struct i2o_block_request *ireq = req->special; unsigned int queue_depth; @@ -929,9 +941,10 @@ static const struct block_device_operations i2o_block_fops = { .owner = THIS_MODULE, .open = i2o_block_open, .release = i2o_block_release, - .locked_ioctl = i2o_block_ioctl, + .ioctl = i2o_block_ioctl, + .compat_ioctl = i2o_block_ioctl, .getgeo = i2o_block_getgeo, - .media_changed = i2o_block_media_changed + .check_events = i2o_block_check_events, }; /** @@ -1065,9 +1078,8 @@ static int i2o_block_probe(struct device *dev) queue = gd->queue; queue->queuedata = i2o_blk_dev; - blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS); - blk_queue_max_sectors(queue, max_sectors); - blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size)); + blk_queue_max_hw_sectors(queue, max_sectors); + blk_queue_max_segments(queue, i2o_sg_tablesize(c, body_size)); osm_debug("max sectors = %d\n", queue->max_sectors); osm_debug("phys segments = %d\n", queue->max_phys_segments); |
