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