regulator: code shrink (v2)
[safe/jmp/linux-2.6] / drivers / block / floppy.c
index 26e7694..cf29cc4 100644 (file)
@@ -217,7 +217,6 @@ static int use_virtual_dma;
  */
 
 static DEFINE_SPINLOCK(floppy_lock);
-static struct completion device_release;
 
 static unsigned short virtual_dma_port = 0x3f0;
 irqreturn_t floppy_interrupt(int irq, void *dev_id);
@@ -424,8 +423,15 @@ static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
  * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
  * side 0 is on physical side 0 (but with the misnamed sector IDs).
  * 'stretch' should probably be renamed to something more general, like
- * 'options'.  Other parameters should be self-explanatory (see also
- * setfdprm(8)).
+ * 'options'.
+ *
+ * Bits 2 through 9 of 'stretch' tell the number of the first sector.
+ * The LSB (bit 2) is flipped. For most disks, the first sector
+ * is 1 (represented by 0x00<<2).  For some CP/M and music sampler
+ * disks (such as Ensoniq EPS 16plus) it is 0 (represented as 0x01<<2).
+ * For Amstrad CPC disks it is 0xC1 (represented as 0xC0<<2).
+ *
+ * Other parameters should be self-explanatory (see also setfdprm(8)).
  */
 /*
            Size
@@ -783,7 +789,10 @@ static inline int is_selected(int dor, int unit)
 
 static int set_dor(int fdc, char mask, char data)
 {
-       register unsigned char drive, unit, newdor, olddor;
+       unsigned char unit;
+       unsigned char drive;
+       unsigned char newdor;
+       unsigned char olddor;
 
        if (FDCS->address == -1)
                return -1;
@@ -937,7 +946,7 @@ static void motor_off_callback(unsigned long nr)
 static void floppy_off(unsigned int drive)
 {
        unsigned long volatile delta;
-       register int fdc = FDC(drive);
+       int fdc = FDC(drive);
 
        if (!(FDCS->dor & (0x10 << UNIT(drive))))
                return;
@@ -1353,20 +1362,20 @@ static void fdc_specify(void)
        }
 
        /* Convert step rate from microseconds to milliseconds and 4 bits */
-       srt = 16 - (DP->srt * scale_dtr / 1000 + NOMINAL_DTR - 1) / NOMINAL_DTR;
+       srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR);
        if (slow_floppy) {
                srt = srt / 4;
        }
        SUPBOUND(srt, 0xf);
        INFBOUND(srt, 0);
 
-       hlt = (DP->hlt * scale_dtr / 2 + NOMINAL_DTR - 1) / NOMINAL_DTR;
+       hlt = DIV_ROUND_UP(DP->hlt * scale_dtr / 2, NOMINAL_DTR);
        if (hlt < 0x01)
                hlt = 0x01;
        else if (hlt > 0x7f)
                hlt = hlt_max_code;
 
-       hut = (DP->hut * scale_dtr / 16 + NOMINAL_DTR - 1) / NOMINAL_DTR;
+       hut = DIV_ROUND_UP(DP->hut * scale_dtr / 16, NOMINAL_DTR);
        if (hut < 0x1)
                hut = 0x1;
        else if (hut > 0xf)
@@ -2234,9 +2243,9 @@ static void setup_format_params(int track)
                        }
                }
        }
-       if (_floppy->stretch & FD_ZEROBASED) {
+       if (_floppy->stretch & FD_SECTBASEMASK) {
                for (count = 0; count < F_SECT_PER_TRACK; count++)
-                       here[count].sect--;
+                       here[count].sect += FD_SECTBASE(_floppy) - 1;
        }
 }
 
@@ -2284,21 +2293,19 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
  * =============================
  */
 
-static void floppy_end_request(struct request *req, int uptodate)
+static void floppy_end_request(struct request *req, int error)
 {
        unsigned int nr_sectors = current_count_sectors;
+       unsigned int drive = (unsigned long)req->rq_disk->private_data;
 
        /* current_count_sectors can be zero if transfer failed */
-       if (!uptodate)
+       if (error)
                nr_sectors = req->current_nr_sectors;
-       if (end_that_request_first(req, uptodate, nr_sectors))
+       if (__blk_end_request(req, error, nr_sectors << 9))
                return;
-       add_disk_randomness(req->rq_disk);
-       floppy_off((long)req->rq_disk->private_data);
-       blkdev_dequeue_request(req);
-       end_that_request_last(req, uptodate);
 
        /* We're done with the request */
+       floppy_off(drive);
        current_req = NULL;
 }
 
@@ -2329,7 +2336,7 @@ static void request_done(int uptodate)
 
                /* unlock chained buffers */
                spin_lock_irqsave(q->queue_lock, flags);
-               floppy_end_request(req, 1);
+               floppy_end_request(req, 0);
                spin_unlock_irqrestore(q->queue_lock, flags);
        } else {
                if (rq_data_dir(req) == WRITE) {
@@ -2343,7 +2350,7 @@ static void request_done(int uptodate)
                        DRWE->last_error_generation = DRS->generation;
                }
                spin_lock_irqsave(q->queue_lock, flags);
-               floppy_end_request(req, 0);
+               floppy_end_request(req, -EIO);
                spin_unlock_irqrestore(q->queue_lock, flags);
        }
 }
@@ -2385,7 +2392,7 @@ static void rw_interrupt(void)
 
 #ifdef FLOPPY_SANITY_CHECK
        if (nr_sectors / ssize >
-           (in_sector_offset + current_count_sectors + ssize - 1) / ssize) {
+           DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) {
                DPRINT("long rw: %x instead of %lx\n",
                       nr_sectors, current_count_sectors);
                printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
@@ -2649,7 +2656,7 @@ static int make_raw_rw_request(void)
        }
        HEAD = fsector_t / _floppy->sect;
 
-       if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) ||
+       if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) ||
             TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
                max_sector = _floppy->sect;
 
@@ -2679,7 +2686,7 @@ static int make_raw_rw_request(void)
        CODE2SIZE;
        SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
        SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) +
-           ((_floppy->stretch & FD_ZEROBASED) ? 0 : 1);
+           FD_SECTBASE(_floppy);
 
        /* tracksize describes the size which can be filled up with sectors
         * of size ssize.
@@ -3311,7 +3318,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
            g->head <= 0 ||
            g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
            /* check if reserved bits are set */
-           (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_ZEROBASED)) != 0)
+           (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
                return -EINVAL;
        if (type) {
                if (!capable(CAP_SYS_ADMIN))
@@ -3356,7 +3363,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
                if (DRS->maxblock > user_params[drive].sect ||
                    DRS->maxtrack ||
                    ((user_params[drive].sect ^ oldStretch) &
-                    (FD_SWAPSIDES | FD_ZEROBASED)))
+                    (FD_SWAPSIDES | FD_SECTBASEMASK)))
                        invalidate_drive(bdev);
                else
                        process_fd_request();
@@ -3443,14 +3450,14 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
                    unsigned long param)
 {
-#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+#define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL))
 #define OUT(c,x) case c: outparam = (const char *) (x); break
 #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
 
-       int drive = (long)inode->i_bdev->bd_disk->private_data;
+       int drive = (long)bdev->bd_disk->private_data;
        int type = ITYPE(UDRS->fd_device);
        int i;
        int ret;
@@ -3509,11 +3516,11 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                        current_type[drive] = NULL;
                        floppy_sizes[drive] = MAX_DISK_SIZE << 1;
                        UDRS->keep_data = 0;
-                       return invalidate_drive(inode->i_bdev);
+                       return invalidate_drive(bdev);
                case FDSETPRM:
                case FDDEFPRM:
                        return set_geometry(cmd, &inparam.g,
-                                           drive, type, inode->i_bdev);
+                                           drive, type, bdev);
                case FDGETPRM:
                        ECALL(get_floppy_geometry(drive, type,
                                                  (struct floppy_struct **)
@@ -3544,7 +3551,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                case FDFMTEND:
                case FDFLUSH:
                        LOCK_FDC(drive, 1);
-                       return invalidate_drive(inode->i_bdev);
+                       return invalidate_drive(bdev);
 
                case FDSETEMSGTRESH:
                        UDP->max_errors.reporting =
@@ -3652,9 +3659,9 @@ static void __init config_types(void)
                printk("\n");
 }
 
-static int floppy_release(struct inode *inode, struct file *filp)
+static int floppy_release(struct gendisk *disk, fmode_t mode)
 {
-       int drive = (long)inode->i_bdev->bd_disk->private_data;
+       int drive = (long)disk->private_data;
 
        mutex_lock(&open_lock);
        if (UDRS->fd_ref < 0)
@@ -3675,18 +3682,17 @@ static int floppy_release(struct inode *inode, struct file *filp)
  * /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 = (long)inode->i_bdev->bd_disk->private_data;
-       int old_dev;
+       int drive = (long)bdev->bd_disk->private_data;
+       int old_dev, new_dev;
        int try;
        int res = -EBUSY;
        char *tmp;
 
-       filp->private_data = (void *)0;
        mutex_lock(&open_lock);
        old_dev = UDRS->fd_device;
-       if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
+       if (opened_bdev[drive] && opened_bdev[drive] != bdev)
                goto out2;
 
        if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) {
@@ -3694,15 +3700,15 @@ static int floppy_open(struct inode *inode, struct file *filp)
                USETF(FD_VERIFY);
        }
 
-       if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
+       if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL)))
                goto out2;
 
-       if (filp->f_flags & O_EXCL)
+       if (mode & FMODE_EXCL)
                UDRS->fd_ref = -1;
        else
                UDRS->fd_ref++;
 
-       opened_bdev[drive] = inode->i_bdev;
+       opened_bdev[drive] = bdev;
 
        res = -ENXIO;
 
@@ -3737,31 +3743,26 @@ static int floppy_open(struct inode *inode, struct file *filp)
                }
        }
 
-       UDRS->fd_device = iminor(inode);
-       set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
-       if (old_dev != -1 && old_dev != iminor(inode)) {
+       new_dev = MINOR(bdev->bd_dev);
+       UDRS->fd_device = new_dev;
+       set_capacity(disks[drive], floppy_sizes[new_dev]);
+       if (old_dev != -1 && old_dev != new_dev) {
                if (buffer_drive == drive)
                        buffer_track = -1;
        }
 
-       /* Allow ioctls if we have write-permissions even if read-only open.
-        * Needed so that programs such as fdrawcmd still can work on write
-        * protected disks */
-       if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
-               filp->private_data = (void *)8;
-
        if (UFDCS->rawcmd == 1)
                UFDCS->rawcmd = 2;
 
-       if (!(filp->f_flags & O_NDELAY)) {
-               if (filp->f_mode & 3) {
+       if (!(mode & FMODE_NDELAY)) {
+               if (mode & (FMODE_READ|FMODE_WRITE)) {
                        UDRS->last_checked = 0;
-                       check_disk_change(inode->i_bdev);
+                       check_disk_change(bdev);
                        if (UTESTF(FD_DISK_CHANGED))
                                goto out;
                }
                res = -EROFS;
-               if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
+               if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE)))
                        goto out;
        }
        mutex_unlock(&open_lock);
@@ -3904,7 +3905,7 @@ 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          = check_floppy_change,
        .revalidate_disk        = floppy_revalidate,
@@ -4123,7 +4124,7 @@ static int __init floppy_setup(char *str)
                printk("\n");
        } else
                DPRINT("botched floppy option\n");
-       DPRINT("Read Documentation/floppy.txt\n");
+       DPRINT("Read Documentation/blockdev/floppy.txt\n");
        return 0;
 }
 
@@ -4143,7 +4144,6 @@ DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL);
 
 static void floppy_device_release(struct device *dev)
 {
-       complete(&device_release);
 }
 
 static struct platform_device floppy_device[N_DRIVE];
@@ -4166,7 +4166,7 @@ static int __init floppy_init(void)
        int i, unit, drive;
        int err, dr;
 
-#if defined(CONFIG_PPC_MERGE)
+#if defined(CONFIG_PPC)
        if (check_legacy_ioport(FDC1))
                return -ENODEV;
 #endif
@@ -4527,18 +4527,18 @@ static void __init parse_floppy_cfg_string(char *cfg)
        }
 }
 
-int __init init_module(void)
+static int __init floppy_module_init(void)
 {
        if (floppy)
                parse_floppy_cfg_string(floppy);
        return floppy_init();
 }
+module_init(floppy_module_init);
 
-void cleanup_module(void)
+static void __exit floppy_module_exit(void)
 {
        int drive;
 
-       init_completion(&device_release);
        blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 
@@ -4563,9 +4563,8 @@ void cleanup_module(void)
 
        /* eject disk, if any */
        fd_eject(0);
-
-       wait_for_completion(&device_release);
 }
+module_exit(floppy_module_exit);
 
 module_param(floppy, charp, 0);
 module_param(FLOPPY_IRQ, int, 0);