Commit 2b0f3d03 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] swim_iop

	* switched to private queue
	* set ->queue and ->private_data
	* switched to new methods
	* switched to use of ->bd_disk
	* fixed the idiocy I'd introduced there during end_request()
	  reshuffling - too many places got hit by search-and-replace ;-/

NOTE: swim_iop (and swim3) are broken for situations when several drives
are present.  Failure mode is rather amusing - the thing does a sort of
load-balancing and if you have two drives even requests end up sent to
the first and odd - to the second ;-) Had been there since they went
into the tree.  Swim3 mentions that support of multiple drives needs to
be fixed, swim_iop (derived from it) had lost even that warning. 
parent a01154a6
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define MAJOR_NR FLOPPY_MAJOR #define MAJOR_NR FLOPPY_MAJOR
#define DEVICE_NAME "floppy" #define DEVICE_NAME "floppy"
#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 )) #define QUEUE (&swim_queue)
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -97,7 +97,7 @@ static char *drive_names[7] = { ...@@ -97,7 +97,7 @@ static char *drive_names[7] = {
int swimiop_init(void); int swimiop_init(void);
static void swimiop_init_request(struct swim_iop_req *); static void swimiop_init_request(struct swim_iop_req *);
static int swimiop_send_request(CURRENT, struct swim_iop_req *); static int swimiop_send_request(struct swim_iop_req *);
static void swimiop_receive(struct iop_msg *, struct pt_regs *); static void swimiop_receive(struct iop_msg *, struct pt_regs *);
static void swimiop_status_update(int, struct swim_drvstatus *); static void swimiop_status_update(int, struct swim_drvstatus *);
static int swimiop_eject(struct floppy_state *fs); static int swimiop_eject(struct floppy_state *fs);
...@@ -106,8 +106,8 @@ static int floppy_ioctl(struct inode *inode, struct file *filp, ...@@ -106,8 +106,8 @@ static int floppy_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long param); unsigned int cmd, unsigned long param);
static int floppy_open(struct inode *inode, struct file *filp); static int floppy_open(struct inode *inode, struct file *filp);
static int floppy_release(struct inode *inode, struct file *filp); static int floppy_release(struct inode *inode, struct file *filp);
static int floppy_check_change(kdev_t dev); static int floppy_check_change(struct gendisk *disk);
static int floppy_revalidate(kdev_t dev); static int floppy_revalidate(struct gendisk *disk);
static int grab_drive(struct floppy_state *fs, enum swim_state state, static int grab_drive(struct floppy_state *fs, enum swim_state state,
int interruptible); int interruptible);
static void release_drive(struct floppy_state *fs); static void release_drive(struct floppy_state *fs);
...@@ -118,13 +118,14 @@ static void do_fd_request(request_queue_t * q); ...@@ -118,13 +118,14 @@ static void do_fd_request(request_queue_t * q);
static void start_request(struct floppy_state *fs); static void start_request(struct floppy_state *fs);
static struct block_device_operations floppy_fops = { static struct block_device_operations floppy_fops = {
open: floppy_open, .open = floppy_open,
release: floppy_release, .release = floppy_release,
ioctl: floppy_ioctl, .ioctl = floppy_ioctl,
check_media_change: floppy_check_change, .media_changed = floppy_check_change,
revalidate: floppy_revalidate, .revalidate_disk= floppy_revalidate,
}; };
static struct request_queue swim_queue;
/* /*
* SWIM IOP initialization * SWIM IOP initialization
*/ */
...@@ -147,8 +148,7 @@ int swimiop_init(void) ...@@ -147,8 +148,7 @@ int swimiop_init(void)
MAJOR_NR); MAJOR_NR);
return -EBUSY; return -EBUSY;
} }
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_fd_request, blk_init_queue(&swim_queue, do_fd_request, &swim_iop_lock);
&swim_iop_lock);
printk("SWIM-IOP: %s by Joshua M. Thompson (funaho@jurai.org)\n", printk("SWIM-IOP: %s by Joshua M. Thompson (funaho@jurai.org)\n",
DRIVER_VERSION); DRIVER_VERSION);
...@@ -166,7 +166,7 @@ int swimiop_init(void) ...@@ -166,7 +166,7 @@ int swimiop_init(void)
swimiop_init_request(&req); swimiop_init_request(&req);
cmd->code = CMD_STATUS; cmd->code = CMD_STATUS;
cmd->drive_num = i + 1; cmd->drive_num = i + 1;
if (swimiop_send_request(CURRENT, &req) != 0) continue; if (swimiop_send_request(&req) != 0) continue;
while (!req.complete); while (!req.complete);
if (cmd->error != 0) { if (cmd->error != 0) {
printk(KERN_ERR "SWIM-IOP: probe on drive %d returned error %d\n", i, (uint) cmd->error); printk(KERN_ERR "SWIM-IOP: probe on drive %d returned error %d\n", i, (uint) cmd->error);
...@@ -195,6 +195,8 @@ int swimiop_init(void) ...@@ -195,6 +195,8 @@ int swimiop_init(void)
disk->first_minor = i; disk->first_minor = i;
disk->fops = &floppy_fops; disk->fops = &floppy_fops;
sprintf(disk->disk_name, "fd%d", i); sprintf(disk->disk_name, "fd%d", i);
disk->private_data = &floppy_states[i];
disk->queue = &swim_queue;
set_capacity(disk, 2880 * 2); set_capacity(disk, 2880 * 2);
add_disk(disk); add_disk(disk);
} }
...@@ -209,7 +211,7 @@ static void swimiop_init_request(struct swim_iop_req *req) ...@@ -209,7 +211,7 @@ static void swimiop_init_request(struct swim_iop_req *req)
req->done = NULL; req->done = NULL;
} }
static int swimiop_send_request(CURRENT, struct swim_iop_req *req) static int swimiop_send_request(struct swim_iop_req *req)
{ {
unsigned long cpu_flags; unsigned long cpu_flags;
int err; int err;
...@@ -324,7 +326,7 @@ static int swimiop_eject(struct floppy_state *fs) ...@@ -324,7 +326,7 @@ static int swimiop_eject(struct floppy_state *fs)
swimiop_init_request(&req); swimiop_init_request(&req);
cmd->code = CMD_EJECT; cmd->code = CMD_EJECT;
cmd->drive_num = fs->drive_num; cmd->drive_num = fs->drive_num;
err = swimiop_send_request(CURRENT, &req); err = swimiop_send_request(&req);
if (err) { if (err) {
release_drive(fs); release_drive(fs);
return err; return err;
...@@ -348,18 +350,12 @@ static struct floppy_struct floppy_type = ...@@ -348,18 +350,12 @@ static struct floppy_struct floppy_type =
static int floppy_ioctl(struct inode *inode, struct file *filp, static int floppy_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long param) unsigned int cmd, unsigned long param)
{ {
struct floppy_state *fs; struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
int err; int err;
int devnum = MINOR(inode->i_rdev);
if (devnum >= floppy_count)
return -ENODEV;
if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)) if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
fs = &floppy_states[devnum];
switch (cmd) { switch (cmd) {
case FDEJECT: case FDEJECT:
if (fs->ref_count != 1) if (fs->ref_count != 1)
...@@ -377,32 +373,19 @@ static int floppy_ioctl(struct inode *inode, struct file *filp, ...@@ -377,32 +373,19 @@ static int floppy_ioctl(struct inode *inode, struct file *filp,
static int floppy_open(struct inode *inode, struct file *filp) static int floppy_open(struct inode *inode, struct file *filp)
{ {
struct floppy_state *fs; struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
int err;
int devnum = MINOR(inode->i_rdev); if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
return -EBUSY;
if (devnum >= floppy_count)
return -ENODEV; if ((filp->f_flags & O_NDELAY) == 0 && (filp->f_mode & 3)) {
if (filp == 0)
return -EIO;
fs = &floppy_states[devnum];
err = 0;
if (fs->ref_count == -1 || filp->f_flags & O_EXCL) return -EBUSY;
if (err == 0 && (filp->f_flags & O_NDELAY) == 0
&& (filp->f_mode & 3)) {
check_disk_change(inode->i_bdev); check_disk_change(inode->i_bdev);
if (fs->ejected) if (fs->ejected)
err = -ENXIO; return -ENXIO;
} }
if (err == 0 && (filp->f_mode & 2)) { if ((filp->f_mode & 2) && fs->write_prot)
if (fs->write_prot) return -EROFS;
err = -EROFS;
}
if (err) return err;
if (filp->f_flags & O_EXCL) if (filp->f_flags & O_EXCL)
fs->ref_count = -1; fs->ref_count = -1;
...@@ -414,43 +397,24 @@ static int floppy_open(struct inode *inode, struct file *filp) ...@@ -414,43 +397,24 @@ static int floppy_open(struct inode *inode, struct file *filp)
static int floppy_release(struct inode *inode, struct file *filp) static int floppy_release(struct inode *inode, struct file *filp)
{ {
struct floppy_state *fs; struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
int devnum = MINOR(inode->i_rdev); if (fs->ref_count > 0)
fs->ref_count--;
if (devnum >= floppy_count)
return -ENODEV;
fs = &floppy_states[devnum];
if (fs->ref_count > 0) fs->ref_count--;
return 0; return 0;
} }
static int floppy_check_change(kdev_t dev) static int floppy_check_change(struct gendisk *disk)
{ {
struct floppy_state *fs; struct floppy_state *fs = disk->private_data;
int devnum = MINOR(dev);
if (MAJOR(dev) != MAJOR_NR || (devnum >= floppy_count))
return 0;
fs = &floppy_states[devnum];
return fs->ejected; return fs->ejected;
} }
static int floppy_revalidate(kdev_t dev) static int floppy_revalidate(struct gendisk *disk)
{ {
struct floppy_state *fs; struct floppy_state *fs = disk->private_data;
int devnum = MINOR(dev);
if (MAJOR(dev) != MAJOR_NR || (devnum >= floppy_count))
return 0;
fs = &floppy_states[devnum];
grab_drive(fs, revalidating, 0); grab_drive(fs, revalidating, 0);
/* yadda, yadda */ /* yadda, yadda */
release_drive(fs); release_drive(fs);
return 0; return 0;
} }
...@@ -604,7 +568,7 @@ static void start_request(struct floppy_state *fs) ...@@ -604,7 +568,7 @@ static void start_request(struct floppy_state *fs)
cmd->first_block = CURRENT->sector; cmd->first_block = CURRENT->sector;
cmd->num_blocks = CURRENT->current_nr_sectors; cmd->num_blocks = CURRENT->current_nr_sectors;
if (swimiop_send_request(CURRENT, &req)) { if (swimiop_send_request(&req)) {
end_request(CURRENT, 0); end_request(CURRENT, 0);
continue; continue;
} }
......
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