Commit 597e6cf4 authored by Jeff Dike's avatar Jeff Dike

Merged the 2.5.44 ubd driver changes.

parent 56f2c516
......@@ -68,7 +68,7 @@ static struct block_device_operations ubd_blops = {
};
/* Protected by the queue_lock */
static request_queue_t *ubd_queue;
static request_queue_t ubd_queue;
/* Protected by ubd_lock */
static int fake_major = 0;
......@@ -347,30 +347,31 @@ int thread_fd = -1;
*/
int intr_count = 0;
static void ubd_finish(int error)
static void ubd_finish(struct request *req, int error)
{
int nsect;
if(error){
spin_lock(&ubd_io_lock);
end_request(CURRENT, 0);
end_request(req, 0);
spin_unlock(&ubd_io_lock);
return;
}
nsect = CURRENT->current_nr_sectors;
CURRENT->sector += nsect;
CURRENT->buffer += nsect << 9;
CURRENT->errors = 0;
CURRENT->nr_sectors -= nsect;
CURRENT->current_nr_sectors = 0;
nsect = req->current_nr_sectors;
req->sector += nsect;
req->buffer += nsect << 9;
req->errors = 0;
req->nr_sectors -= nsect;
req->current_nr_sectors = 0;
spin_lock(&ubd_io_lock);
end_request(CURRENT, 1);
end_request(req, 1);
spin_unlock(&ubd_io_lock);
}
static void ubd_handler(void)
{
struct io_thread_req req;
struct request *rq = elv_next_request(&ubd_queue);
int n;
do_ubd = NULL;
......@@ -380,18 +381,18 @@ static void ubd_handler(void)
printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
"errno = %d\n", os_getpid(), -n);
spin_lock(&ubd_io_lock);
end_request(CURRENT, 0);
end_request(rq, 0);
spin_unlock(&ubd_io_lock);
return;
}
if((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
(req.length != (CURRENT->current_nr_sectors) << 9))
if((req.offset != ((__u64) (rq->sector)) << 9) ||
(req.length != (rq->current_nr_sectors) << 9))
panic("I/O op mismatch");
ubd_finish(req.error);
ubd_finish(rq, req.error);
reactivate_fd(thread_fd, UBD_IRQ);
do_ubd_request(ubd_queue);
do_ubd_request(&ubd_queue);
}
static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
......@@ -504,6 +505,8 @@ static int ubd_new_disk(int major, u64 size, char *name, int unit,
DEVFS_FL_REMOVABLE, major, minor,
S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
S_IWGRP, &ubd_blops, NULL);
disk->private_data = &ubd_dev[unit];
disk->queue = &ubd_queue;
add_disk(disk);
return(0);
}
......@@ -615,9 +618,9 @@ static int ubd_remove(char *str)
}
static struct mc_device ubd_mc = {
name: "ubd",
config: ubd_config,
remove: ubd_remove,
.name = "ubd",
.config = ubd_config,
.remove = ubd_remove,
};
static int ubd_mc_init(void)
......@@ -628,11 +631,6 @@ static int ubd_mc_init(void)
__initcall(ubd_mc_init);
static request_queue_t *ubd_get_queue(kdev_t device)
{
return(ubd_queue);
}
int ubd_init(void)
{
int i;
......@@ -642,9 +640,10 @@ int ubd_init(void)
printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
return -1;
}
ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
blk_init_queue(ubd_queue, do_ubd_request, &ubd_io_lock);
elevator_init(ubd_queue, &elevator_noop);
blk_init_queue(&ubd_queue, do_ubd_request, &ubd_io_lock);
elevator_init(&ubd_queue, &elevator_noop);
if(fake_major != 0){
char name[sizeof("ubd_nnn\0")];
......@@ -655,7 +654,6 @@ int ubd_init(void)
fake_major);
return -1;
}
blk_dev[fake_major].queue = ubd_get_queue;
}
for(i = 0; i < MAX_DEV; i++)
ubd_add(i);
......@@ -692,8 +690,8 @@ device_initcall(ubd_driver_init);
static int ubd_open(struct inode *inode, struct file *filp)
{
int n = DEVICE_NR(inode->i_rdev);
struct ubd *dev = &ubd_dev[n];
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ubd *dev = disk->private_data;
int err = -EISDIR;
if(dev->is_dir == 1)
......@@ -705,8 +703,8 @@ static int ubd_open(struct inode *inode, struct file *filp)
err = ubd_open_dev(dev);
if(err){
printk(KERN_ERR "ubd%d: Can't open \"%s\": "
"errno = %d\n", n, dev->file, -err);
printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
disk->disk_name, dev->file, -err);
goto out;
}
}
......@@ -721,9 +719,11 @@ static int ubd_open(struct inode *inode, struct file *filp)
static int ubd_release(struct inode * inode, struct file * file)
{
int n = DEVICE_NR(inode->i_rdev);
if(--ubd_dev[n].count == 0)
ubd_close(&ubd_dev[n]);
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ubd *dev = disk->private_data;
if(--dev->count == 0)
ubd_close(dev);
return(0);
}
......@@ -767,15 +767,13 @@ void cowify_req(struct io_thread_req *req, struct ubd *dev)
static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
struct ubd *dev;
struct gendisk *disk = req->rq_disk;
struct ubd *dev = disk->private_data;
__u64 block;
int nsect, min, n;
int nsect;
if(req->rq_status == RQ_INACTIVE) return(1);
min = minor(req->rq_dev);
n = min >> UBD_SHIFT;
dev = &ubd_dev[n];
if(dev->is_dir){
strcpy(req->buffer, "HOSTFS:");
strcat(req->buffer, dev->file);
......@@ -786,7 +784,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
}
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %d\n", n);
printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
spin_lock(&ubd_io_lock);
end_request(req, 0);
spin_unlock(&ubd_io_lock);
......@@ -825,7 +824,7 @@ static void do_ubd_request(request_queue_t *q)
err = prepare_request(req, &io_req);
if(!err){
do_io(&io_req);
ubd_finish(io_req.error);
ubd_finish(req, io_req.error);
}
}
}
......@@ -848,21 +847,14 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
struct hd_geometry *loc = (struct hd_geometry *) arg;
struct ubd *dev;
int n, min, err;
struct ubd *dev = inode->i_bdev->bd_disk->private_data;
int err;
struct hd_driveid ubd_id = {
.cyls = 0,
.heads = 128,
.sectors = 32,
};
if(!inode) return(-EINVAL);
min = minor(inode->i_rdev);
n = min >> UBD_SHIFT;
if(n > MAX_DEV)
return(-EINVAL);
dev = &ubd_dev[n];
switch (cmd) {
struct hd_geometry g;
struct cdrom_volctrl volume;
......@@ -876,7 +868,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
case HDIO_SET_UNMASKINTR:
if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
if((arg > 1) || (min & ((1 << UBD_SHIFT) - 1)))
if((arg > 1) || (inode->i_bdev->bd_contains != inode->i_bdev))
return(-EINVAL);
return(0);
......@@ -896,7 +888,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
case HDIO_SET_MULTCOUNT:
if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
if(min & ((1 << UBD_SHIFT) - 1))
if(inode->i_bdev->bd_contains != inode->i_bdev)
return(-EINVAL);
return(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment