x86: pci-swiotlb.c swiotlb_dma_ops should be static
[safe/jmp/linux-2.6] / drivers / block / amiflop.c
index 1468e8c..8df436f 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
+#include <linux/interrupt.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
@@ -131,7 +132,7 @@ static struct fd_drive_type drive_types[] = {
 { FD_DD_5,     "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2},
 { FD_NODRIVE, "No Drive", 0, 0,     0,     0, 0,  0,  0,  0,  0, 0}
 };
-static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
+static int num_dr_types = ARRAY_SIZE(drive_types);
 
 static int amiga_read(int), dos_read(int);
 static void amiga_write(int), dos_write(int);
@@ -155,7 +156,7 @@ static volatile int fdc_busy = -1;
 static volatile int fdc_nested;
 static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
  
-static DECLARE_WAIT_QUEUE_HEAD(motor_wait);
+static DECLARE_COMPLETION(motor_on_completion);
 
 static volatile int selected = -1;     /* currently selected drive */
 
@@ -183,8 +184,7 @@ static unsigned char mfmencode[16]={
 static unsigned char mfmdecode[128];
 
 /* floppy internal millisecond timer stuff */
-static volatile int ms_busy = -1;
-static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
+static DECLARE_COMPLETION(ms_wait_completion);
 #define MS_TICKS ((amiga_eclock+50)/1000)
 
 /*
@@ -194,6 +194,8 @@ static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
  */
 #define MAX_ERRORS 12
 
+#define custom amiga_custom
+
 /* Prevent "aliased" accesses. */
 static int fd_ref[4] = { 0,0,0,0 };
 static int fd_device[4] = { 0, 0, 0, 0 };
@@ -206,10 +208,9 @@ static int fd_device[4] = { 0, 0, 0, 0 };
 
 /* Milliseconds timer */
 
-static irqreturn_t ms_isr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t ms_isr(int irq, void *dummy)
 {
-       ms_busy = -1;
-       wake_up(&ms_wait);
+       complete(&ms_wait_completion);
        return IRQ_HANDLED;
 }
 
@@ -217,19 +218,17 @@ static irqreturn_t ms_isr(int irq, void *dummy, struct pt_regs *fp)
    A more generic routine would do a schedule a la timer.device */
 static void ms_delay(int ms)
 {
-       unsigned long flags;
        int ticks;
+       static DEFINE_MUTEX(mutex);
+
        if (ms > 0) {
-               local_irq_save(flags);
-               while (ms_busy == 0)
-                       sleep_on(&ms_wait);
-               ms_busy = 0;
-               local_irq_restore(flags);
+               mutex_lock(&mutex);
                ticks = MS_TICKS*ms-1;
                ciaa.tblo=ticks%256;
                ciaa.tbhi=ticks/256;
                ciaa.crb=0x19; /*count eclock, force load, one-shoot, start */
-               sleep_on(&ms_wait);
+               wait_for_completion(&ms_wait_completion);
+               mutex_unlock(&mutex);
        }
 }
 
@@ -251,8 +250,7 @@ static void get_fdc(int drive)
        printk("get_fdc: drive %d  fdc_busy %d  fdc_nested %d\n",drive,fdc_busy,fdc_nested);
 #endif
        local_irq_save(flags);
-       while (!try_fdc(drive))
-               sleep_on(&fdc_wait);
+       wait_event(fdc_wait, try_fdc(drive));
        fdc_busy = drive;
        fdc_nested++;
        local_irq_restore(flags);
@@ -327,7 +325,7 @@ static void fd_deselect (int drive)
 static void motor_on_callback(unsigned long nr)
 {
        if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
-               wake_up (&motor_wait);
+               complete_all(&motor_on_completion);
        } else {
                motor_on_timer.expires = jiffies + HZ/10;
                add_timer(&motor_on_timer);
@@ -344,11 +342,12 @@ static int fd_motor_on(int nr)
                unit[nr].motor = 1;
                fd_select(nr);
 
+               INIT_COMPLETION(motor_on_completion);
                motor_on_timer.data = nr;
                mod_timer(&motor_on_timer, jiffies + HZ/2);
 
                on_attempts = 10;
-               sleep_on (&motor_wait);
+               wait_for_completion(&motor_on_completion);
                fd_deselect(nr);
        }
 
@@ -557,7 +556,7 @@ static unsigned long fd_get_drive_id(int drive)
        return (id);
 }
 
-static irqreturn_t fd_block_done(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t fd_block_done(int irq, void *dummy)
 {
        if (block_flag)
                custom.dsklen = 0x4000;
@@ -579,8 +578,7 @@ static void raw_read(int drive)
 {
        drive&=3;
        get_fdc(drive);
-       while (block_flag)
-               sleep_on(&wait_fd_block);
+       wait_event(wait_fd_block, !block_flag);
        fd_select(drive);
        /* setup adkcon bits correctly */
        custom.adkcon = ADK_MSBSYNC;
@@ -595,8 +593,7 @@ static void raw_read(int drive)
 
        block_flag = 1;
 
-       while (block_flag)
-               sleep_on (&wait_fd_block);
+       wait_event(wait_fd_block, !block_flag);
 
        custom.dsklen = 0;
        fd_deselect(drive);
@@ -613,8 +610,7 @@ static int raw_write(int drive)
                rel_fdc();
                return 0;
        }
-       while (block_flag)
-               sleep_on(&wait_fd_block);
+       wait_event(wait_fd_block, !block_flag);
        fd_select(drive);
        /* clear adkcon bits */
        custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
@@ -1291,8 +1287,7 @@ static int non_int_flush_track (unsigned long nr)
                        writepending = 0;
                        return 0;
                }
-               while (block_flag == 2)
-                       sleep_on (&wait_fd_block);
+               wait_event(wait_fd_block, block_flag != 2);
        }
        else {
                local_irq_restore(flags);
@@ -1360,7 +1355,7 @@ static void redo_fd_request(void)
 #ifdef DEBUG
                printk("fd: sector %ld + %d requested for %s\n",
                       CURRENT->sector,cnt,
-                      (CURRENT->cmd==READ)?"read":"write");
+                      (rq_data_dir(CURRENT) == READ) ? "read" : "write");
 #endif
                block = CURRENT->sector + cnt;
                if ((int)block > floppy->blocks) {
@@ -1419,37 +1414,37 @@ static void redo_fd_request(void)
        goto repeat;
 }
 
-static void do_fd_request(request_queue_t * q)
+static void do_fd_request(struct request_queue * q)
 {
        redo_fd_request();
 }
 
-static int fd_ioctl(struct inode *inode, struct file *filp,
+static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+       int drive = MINOR(bdev->bd_dev) & 3;
+
+       geo->heads = unit[drive].type->heads;
+       geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
+       geo->cylinders = unit[drive].type->tracks;
+       return 0;
+}
+
+static int fd_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long param)
 {
-       int drive = iminor(inode) & 3;
+       struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
+       int drive = p - unit;
        static struct floppy_struct getprm;
+       void __user *argp = (void __user *)param;
 
        switch(cmd){
-       case HDIO_GETGEO:
-       {
-               struct hd_geometry loc;
-               loc.heads = unit[drive].type->heads;
-               loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
-               loc.cylinders = unit[drive].type->tracks;
-               loc.start = 0;
-               if (copy_to_user((void *)param, (void *)&loc,
-                                sizeof(struct hd_geometry)))
-                       return -EFAULT;
-               break;
-       }
        case FDFMTBEG:
                get_fdc(drive);
                if (fd_ref[drive] > 1) {
                        rel_fdc();
                        return -EBUSY;
                }
-               fsync_bdev(inode->i_bdev);
+               fsync_bdev(bdev);
                if (fd_motor_on(drive) == 0) {
                        rel_fdc();
                        return -ENODEV;
@@ -1462,12 +1457,12 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                rel_fdc();
                break;
        case FDFMTTRK:
-               if (param < unit[drive].type->tracks * unit[drive].type->heads)
+               if (param < p->type->tracks * p->type->heads)
                {
                        get_fdc(drive);
                        if (fd_seek(drive,param) != 0){
-                               memset(unit[drive].trackbuf, FD_FILL_BYTE,
-                                      unit[drive].dtype->sects * unit[drive].type->sect_mult * 512);
+                               memset(p->trackbuf, FD_FILL_BYTE,
+                                      p->dtype->sects * p->type->sect_mult * 512);
                                non_int_flush_track(drive);
                        }
                        floppy_off(drive);
@@ -1478,17 +1473,15 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                break;
        case FDFMTEND:
                floppy_off(drive);
-               invalidate_bdev(inode->i_bdev, 0);
+               invalidate_bdev(bdev);
                break;
        case FDGETPRM:
                memset((void *)&getprm, 0, sizeof (getprm));
-               getprm.track=unit[drive].type->tracks;
-               getprm.head=unit[drive].type->heads;
-               getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;
-               getprm.size=unit[drive].blocks;
-               if (copy_to_user((void *)param,
-                                (void *)&getprm,
-                                sizeof(struct floppy_struct)))
+               getprm.track=p->type->tracks;
+               getprm.head=p->type->heads;
+               getprm.sect=p->dtype->sects * p->type->sect_mult;
+               getprm.size=p->blocks;
+               if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct)))
                        return -EFAULT;
                break;
        case FDSETPRM:
@@ -1500,11 +1493,10 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                break;
 #ifdef RAW_IOCTL
        case IOCTL_RAW_TRACK:
-               if (copy_to_user((void *)param, raw_buf,
-                                unit[drive].type->read_size))
+               if (copy_to_user(argp, raw_buf, p->type->read_size))
                        return -EFAULT;
                else
-                       return unit[drive].type->read_size;
+                       return p->type->read_size;
 #endif
        default:
                printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",
@@ -1549,10 +1541,10 @@ static void fd_probe(int dev)
  * /dev/PS0 etc), and disallows simultaneous access to the same
  * drive with different device numbers.
  */
-static int floppy_open(struct inode *inode, struct file *filp)
+static int floppy_open(struct block_device *bdev, fmode_t mode)
 {
-       int drive = iminor(inode) & 3;
-       int system =  (iminor(inode) & 4) >> 2;
+       int drive = MINOR(bdev->bd_dev) & 3;
+       int system =  (MINOR(bdev->bd_dev) & 4) >> 2;
        int old_dev;
        unsigned long flags;
 
@@ -1561,9 +1553,9 @@ static int floppy_open(struct inode *inode, struct file *filp)
        if (fd_ref[drive] && old_dev != system)
                return -EBUSY;
 
-       if (filp && filp->f_mode & 3) {
-               check_disk_change(inode->i_bdev);
-               if (filp->f_mode & 2 ) {
+       if (mode & (FMODE_READ|FMODE_WRITE)) {
+               check_disk_change(bdev);
+               if (mode & FMODE_WRITE) {
                        int wrprot;
 
                        get_fdc(drive);
@@ -1593,9 +1585,10 @@ static int floppy_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static int floppy_release(struct inode * inode, struct file * filp)
+static int floppy_release(struct gendisk *disk, fmode_t mode)
 {
-       int drive = iminor(inode) & 3;
+       struct amiga_floppy_struct *p = disk->private_data;
+       int drive = p - unit;
 
        if (unit[drive].dirty == 1) {
                del_timer (flush_track_timer + drive);
@@ -1651,16 +1644,11 @@ static struct block_device_operations floppy_fops = {
        .owner          = THIS_MODULE,
        .open           = floppy_open,
        .release        = floppy_release,
-       .ioctl          = fd_ioctl,
+       .locked_ioctl   = fd_ioctl,
+       .getgeo         = fd_getgeo,
        .media_changed  = amiga_floppy_change,
 };
 
-void __init amiga_floppy_setup (char *str, int *ints)
-{
-       printk (KERN_INFO "amiflop: Setting default df0 to %x\n", ints[1]);
-       fd_def_df0 = ints[1];
-}
-
 static int __init fd_probe_drives(void)
 {
        int drive,drives,nomem;
@@ -1715,12 +1703,15 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        return get_disk(unit[drive].gendisk);
 }
 
-int __init amiga_floppy_init(void)
+static int __init amiga_floppy_init(void)
 {
        int i, ret;
 
+       if (!MACH_IS_AMIGA)
+               return -ENODEV;
+
        if (!AMIGAHW_PRESENT(AMI_FLOPPY))
-               return -ENXIO;
+               return -ENODEV;
 
        if (register_blkdev(FLOPPY_MAJOR,"fd"))
                return -EBUSY;
@@ -1758,7 +1749,7 @@ int __init amiga_floppy_init(void)
        if (!floppy_queue)
                goto out_queue;
 
-       ret = -ENXIO;
+       ret = -ENODEV;
        if (fd_probe_drives() < 1) /* No usable drives */
                goto out_probe;
 
@@ -1815,15 +1806,8 @@ out_blkdev:
        return ret;
 }
 
+module_init(amiga_floppy_init);
 #ifdef MODULE
-#include <linux/version.h>
-
-int init_module(void)
-{
-       if (!MACH_IS_AMIGA)
-               return -ENXIO;
-       return amiga_floppy_init();
-}
 
 #if 0 /* not safe to unload */
 void cleanup_module(void)
@@ -1847,4 +1831,19 @@ void cleanup_module(void)
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 }
 #endif
+
+#else
+static int __init amiga_floppy_setup (char *str)
+{
+       int n;
+       if (!MACH_IS_AMIGA)
+               return 0;
+       if (!get_option(&str, &n))
+               return 0;
+       printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n);
+       fd_def_df0 = n;
+       return 1;
+}
+
+__setup("floppy=", amiga_floppy_setup);
 #endif