fbdev: move FBIO_WAITFORVSYNC to linux/fb.h
[safe/jmp/linux-2.6] / drivers / block / ataflop.c
index 22bda05..e35cf59 100644 (file)
@@ -79,9 +79,7 @@
 #undef DEBUG
 
 static struct request_queue *floppy_queue;
-
-#define QUEUE (floppy_queue)
-#define CURRENT elv_next_request(floppy_queue)
+static struct request *fd_request;
 
 /* Disk types: DD, HD, ED */
 static struct atari_disk_type {
@@ -90,7 +88,7 @@ static struct atari_disk_type {
        unsigned        blocks;         /* total number of blocks */
        unsigned        fdc_speed;      /* fdc_speed setting */
        unsigned        stretch;        /* track doubling ? */
-} disk_type[] = {
+} atari_disk_type[] = {
        { "d360",  9, 720, 0, 0},       /*  0: 360kB diskette */
        { "D360",  9, 720, 0, 1},       /*  1: 360kb in 720k or 1.2MB drive */
        { "D720",  9,1440, 0, 0},       /*  2: 720kb in 720k or 1.2MB drive */
@@ -181,7 +179,7 @@ static struct {
        {  6, TYPE_HD },        /* 31: H1640    <- was H1600 == h1600 for PC */
 };
 
-#define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype))
+#define NUM_DISK_MINORS ARRAY_SIZE(minor2disktype)
 
 /*
  * Maximum disk size (in kilobytes). This default is used whenever the
@@ -271,7 +269,7 @@ unsigned char *DMABuffer;                     /* buffer for writes */
 static unsigned long PhysDMABuffer;   /* physical address */
 
 static int UseTrackbuffer = -1;                  /* Do track buffering? */
-MODULE_PARM(UseTrackbuffer, "i");
+module_param(UseTrackbuffer, int, 0);
 
 unsigned char *TrackBuffer;                      /* buffer for reads */
 static unsigned long PhysTrackBuffer; /* physical address */
@@ -296,7 +294,7 @@ static int MotorOn = 0, MotorOffTrys;
 static int IsFormatting = 0, FormatError;
 
 static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
-MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i");
+module_param_array(UserSteprate, int, NULL, 0);
 
 /* Synchronization of FDC access. */
 static volatile int fdc_busy = 0;
@@ -342,7 +340,7 @@ static void fd_select_drive( int drive );
 static void fd_deselect( void );
 static void fd_motor_off_timer( unsigned long dummy );
 static void check_change( unsigned long dummy );
-static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t floppy_irq (int irq, void *dummy);
 static void fd_error( void );
 static int do_format(int drive, int type, struct atari_format_descr *desc);
 static void do_fd_action( int drive );
@@ -361,13 +359,13 @@ static void finish_fdc( void );
 static void finish_fdc_done( int dummy );
 static void setup_req_params( int drive );
 static void redo_fd_request( void);
-static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
+static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
                      cmd, unsigned long param);
 static void fd_probe( int drive );
 static int fd_test_drive_present( int drive );
 static void config_types( void );
-static int floppy_open( struct inode *inode, struct file *filp );
-static int floppy_release( struct inode * inode, struct file * filp );
+static int floppy_open(struct block_device *bdev, fmode_t mode);
+static int floppy_release(struct gendisk *disk, fmode_t mode);
 
 /************************* End of Prototypes **************************/
 
@@ -376,6 +374,12 @@ static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
 static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
 static DEFINE_TIMER(fd_timer, check_change, 0, 0);
        
+static void fd_end_request_cur(int err)
+{
+       if (!__blk_end_request_cur(fd_request, err))
+               fd_request = NULL;
+}
+
 static inline void start_motor_off_timer(void)
 {
        mod_timer(&motor_off_timer, jiffies + FD_MOTOR_OFF_DELAY);
@@ -573,7 +577,7 @@ static inline void copy_buffer(void *from, void *to)
 
 static void (*FloppyIRQHandler)( int status ) = NULL;
 
-static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t floppy_irq (int irq, void *dummy)
 {
        unsigned char status;
        void (*handler)( int );
@@ -606,15 +610,15 @@ static void fd_error( void )
                return;
        }
 
-       if (!CURRENT)
+       if (!fd_request)
                return;
 
-       CURRENT->errors++;
-       if (CURRENT->errors >= MAX_ERRORS) {
+       fd_request->errors++;
+       if (fd_request->errors >= MAX_ERRORS) {
                printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive );
-               end_request(CURRENT, 0);
+               fd_end_request_cur(-EIO);
        }
-       else if (CURRENT->errors == RECALIBRATE_ERRORS) {
+       else if (fd_request->errors == RECALIBRATE_ERRORS) {
                printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive );
                if (SelectedDrive != -1)
                        SUD.track = -1;
@@ -658,7 +662,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
                        return -EINVAL;
                }
                type = minor2disktype[type].index;
-               UDT = &disk_type[type];
+               UDT = &atari_disk_type[type];
        }
 
        if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) {
@@ -725,16 +729,14 @@ static void do_fd_action( int drive )
            if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
                if (ReqCmd == READ) {
                    copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
-                   if (++ReqCnt < CURRENT->current_nr_sectors) {
+                   if (++ReqCnt < blk_rq_cur_sectors(fd_request)) {
                        /* read next sector */
                        setup_req_params( drive );
                        goto repeat;
                    }
                    else {
                        /* all sectors finished */
-                       CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
-                       CURRENT->sector += CURRENT->current_nr_sectors;
-                       end_request(CURRENT, 1);
+                       fd_end_request_cur(0);
                        redo_fd_request();
                        return;
                    }
@@ -1064,7 +1066,7 @@ static void fd_rwsec_done1(int status)
               searched for a non-existent sector! */
            !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) {
                if (Probing) {
-                       if (SUDT > disk_type) {
+                       if (SUDT > atari_disk_type) {
                            if (SUDT[-1].blocks > ReqBlock) {
                                /* try another disk type */
                                SUDT--;
@@ -1082,7 +1084,7 @@ static void fd_rwsec_done1(int status)
                } else {        
 /* record not found, but not probing. Maybe stretch wrong ? Restart probing */
                        if (SUD.autoprobe) {
-                               SUDT = disk_type + StartDiskType[DriveType];
+                               SUDT = atari_disk_type + StartDiskType[DriveType];
                                set_capacity(unit[SelectedDrive].disk,
                                                        SUDT->blocks);
                                Probing = 1;
@@ -1132,16 +1134,14 @@ static void fd_rwsec_done1(int status)
                }
        }
   
-       if (++ReqCnt < CURRENT->current_nr_sectors) {
+       if (++ReqCnt < blk_rq_cur_sectors(fd_request)) {
                /* read next sector */
                setup_req_params( SelectedDrive );
                do_fd_action( SelectedDrive );
        }
        else {
                /* all sectors finished */
-               CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
-               CURRENT->sector += CURRENT->current_nr_sectors;
-               end_request(CURRENT, 1);
+               fd_end_request_cur(0);
                redo_fd_request();
        }
        return;
@@ -1361,7 +1361,7 @@ static int floppy_revalidate(struct gendisk *disk)
                   formats, for 'permanent user-defined' parameter:
                   restore default_params[] here if flagged valid! */
                if (default_params[drive].blocks == 0)
-                       UDT = 0;
+                       UDT = NULL;
                else
                        UDT = &default_params[drive];
        }
@@ -1382,7 +1382,7 @@ static void setup_req_params( int drive )
        ReqData = ReqBuffer + 512 * ReqCnt;
 
        if (UseTrackbuffer)
-               read_track = (ReqCmd == READ && CURRENT->errors == 0);
+               read_track = (ReqCmd == READ && fd_request->errors == 0);
        else
                read_track = 0;
 
@@ -1396,32 +1396,34 @@ static void redo_fd_request(void)
        int drive, type;
        struct atari_floppy_struct *floppy;
 
-       DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n",
-               CURRENT, CURRENT ? CURRENT->rq_disk->disk_name : "",
-               CURRENT ? CURRENT->sector : 0 ));
+       DPRINT(("redo_fd_request: fd_request=%p dev=%s fd_request->sector=%ld\n",
+               fd_request, fd_request ? fd_request->rq_disk->disk_name : "",
+               fd_request ? blk_rq_pos(fd_request) : 0 ));
 
        IsFormatting = 0;
 
 repeat:
+       if (!fd_request) {
+               fd_request = blk_fetch_request(floppy_queue);
+               if (!fd_request)
+                       goto the_end;
+       }
 
-       if (!CURRENT)
-               goto the_end;
-
-       floppy = CURRENT->rq_disk->private_data;
+       floppy = fd_request->rq_disk->private_data;
        drive = floppy - unit;
        type = floppy->type;
        
        if (!UD.connected) {
                /* drive not connected */
                printk(KERN_ERR "Unknown Device: fd%d\n", drive );
-               end_request(CURRENT, 0);
+               fd_end_request_cur(-EIO);
                goto repeat;
        }
                
        if (type == 0) {
                if (!UDT) {
                        Probing = 1;
-                       UDT = disk_type + StartDiskType[DriveType];
+                       UDT = atari_disk_type + StartDiskType[DriveType];
                        set_capacity(floppy->disk, UDT->blocks);
                        UD.autoprobe = 1;
                }
@@ -1430,22 +1432,22 @@ repeat:
                /* user supplied disk type */
                if (--type >= NUM_DISK_MINORS) {
                        printk(KERN_WARNING "fd%d: invalid disk format", drive );
-                       end_request(CURRENT, 0);
+                       fd_end_request_cur(-EIO);
                        goto repeat;
                }
                if (minor2disktype[type].drive_types > DriveType)  {
                        printk(KERN_WARNING "fd%d: unsupported disk format", drive );
-                       end_request(CURRENT, 0);
+                       fd_end_request_cur(-EIO);
                        goto repeat;
                }
                type = minor2disktype[type].index;
-               UDT = &disk_type[type];
+               UDT = &atari_disk_type[type];
                set_capacity(floppy->disk, UDT->blocks);
                UD.autoprobe = 0;
        }
        
-       if (CURRENT->sector + 1 > UDT->blocks) {
-               end_request(CURRENT, 0);
+       if (blk_rq_pos(fd_request) + 1 > UDT->blocks) {
+               fd_end_request_cur(-EIO);
                goto repeat;
        }
 
@@ -1453,9 +1455,9 @@ repeat:
        del_timer( &motor_off_timer );
                
        ReqCnt = 0;
-       ReqCmd = rq_data_dir(CURRENT);
-       ReqBlock = CURRENT->sector;
-       ReqBuffer = CURRENT->buffer;
+       ReqCmd = rq_data_dir(fd_request);
+       ReqBlock = blk_rq_pos(fd_request);
+       ReqBuffer = fd_request->buffer;
        setup_req_params( drive );
        do_fd_action( drive );
 
@@ -1466,27 +1468,22 @@ repeat:
 }
 
 
-void do_fd_request(request_queue_t * q)
+void do_fd_request(struct request_queue * q)
 {
-       unsigned long flags;
-
        DPRINT(("do_fd_request for pid %d\n",current->pid));
        while( fdc_busy ) sleep_on( &fdc_wait );
        fdc_busy = 1;
        stdma_lock(floppy_irq, NULL);
 
        atari_disable_irq( IRQ_MFP_FDC );
-       local_save_flags(flags);        /* The request function is called with ints
-       local_irq_disable();             * disabled... so must save the IPL for later */ 
        redo_fd_request();
-       local_irq_restore(flags);
        atari_enable_irq( IRQ_MFP_FDC );
 }
 
-static int fd_ioctl(struct inode *inode, struct file *filp,
+static int fd_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long param)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        struct atari_floppy_struct *floppy = disk->private_data;
        int drive = floppy - unit;
        int type = floppy->type;
@@ -1495,6 +1492,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
        struct floppy_struct getprm;
        int settype;
        struct floppy_struct setprm;
+       void __user *argp = (void __user *)param;
 
        switch (cmd) {
        case FDGETPRM:
@@ -1504,7 +1502,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                        if (minor2disktype[type].drive_types > DriveType)
                                return -ENODEV;
                        type = minor2disktype[type].index;
-                       dtp = &disk_type[type];
+                       dtp = &atari_disk_type[type];
                        if (UD.flags & FTD_MSG)
                            printk (KERN_ERR "floppy%d: found dtp %p name %s!\n",
                                drive, dtp, dtp->name);
@@ -1521,7 +1519,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                getprm.head = 2;
                getprm.track = dtp->blocks/dtp->spt/2;
                getprm.stretch = dtp->stretch;
-               if (copy_to_user((void *)param, &getprm, sizeof(getprm)))
+               if (copy_to_user(argp, &getprm, sizeof(getprm)))
                        return -EFAULT;
                return 0;
        }
@@ -1540,7 +1538,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                /* get the parameters from user space */
                if (floppy->ref != 1 && floppy->ref != -1)
                        return -EBUSY;
-               if (copy_from_user(&setprm, (void *) param, sizeof(setprm)))
+               if (copy_from_user(&setprm, argp, sizeof(setprm)))
                        return -EFAULT;
                /* 
                 * first of all: check for floppy change and revalidate, 
@@ -1575,7 +1573,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                                continue;
                        }
                        setidx = minor2disktype[settype].index;
-                       dtp = &disk_type[setidx];
+                       dtp = &atari_disk_type[setidx];
 
                        /* found matching entry ?? */
                        if (   dtp->blocks  == setprm.size 
@@ -1624,7 +1622,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                                drive, dtp->blocks, dtp->spt, dtp->stretch);
 
                /* sanity check */
-               if (!dtp || setprm.track != dtp->blocks/dtp->spt/2 ||
+               if (setprm.track != dtp->blocks/dtp->spt/2 ||
                    setprm.head != 2) {
                        redo_fd_request();
                        return -EINVAL;
@@ -1647,7 +1645,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
        case FDFMTTRK:
                if (floppy->ref != 1 && floppy->ref != -1)
                        return -EBUSY;
-               if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc)))
+               if (copy_from_user(&fmt_desc, argp, sizeof(fmt_desc)))
                        return -EFAULT;
                return do_format(drive, type, &fmt_desc);
        case FDCLRPRM:
@@ -1660,7 +1658,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                /* invalidate the buffer track to force a reread */
                BufferDrive = -1;
                set_bit(drive, &fake_change);
-               check_disk_change(inode->i_bdev);
+               check_disk_change(bdev);
                return 0;
        default:
                return -EINVAL;
@@ -1729,7 +1727,7 @@ static int __init fd_test_drive_present( int drive )
 
        timeout = jiffies + 2*HZ+HZ/2;
        while (time_before(jiffies, timeout))
-               if (!(mfp.par_dt_reg & 0x20))
+               if (!(st_mfp.par_dt_reg & 0x20))
                        break;
 
        status = FDC_READ( FDCREG_STATUS );
@@ -1746,7 +1744,7 @@ static int __init fd_test_drive_present( int drive )
                /* dummy seek command to make WP bit accessible */
                FDC_WRITE( FDCREG_DATA, 0 );
                FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
-               while( mfp.par_dt_reg & 0x20 )
+               while( st_mfp.par_dt_reg & 0x20 )
                        ;
                status = FDC_READ( FDCREG_STATUS );
        }
@@ -1803,37 +1801,36 @@ static void __init config_types( void )
  * 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)
 {
-       struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
-       int type  = iminor(inode) >> 2;
+       struct atari_floppy_struct *p = bdev->bd_disk->private_data;
+       int type  = MINOR(bdev->bd_dev) >> 2;
 
        DPRINT(("fd_open: type=%d\n",type));
        if (p->ref && p->type != type)
                return -EBUSY;
 
-       if (p->ref == -1 || (p->ref && filp->f_flags & O_EXCL))
+       if (p->ref == -1 || (p->ref && mode & FMODE_EXCL))
                return -EBUSY;
 
-       if (filp->f_flags & O_EXCL)
+       if (mode & FMODE_EXCL)
                p->ref = -1;
        else
                p->ref++;
 
        p->type = type;
 
-       if (filp->f_flags & O_NDELAY)
+       if (mode & FMODE_NDELAY)
                return 0;
 
-       if (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) {
                        if (p->wpstat) {
                                if (p->ref < 0)
                                        p->ref = 0;
                                else
                                        p->ref--;
-                               floppy_release(inode, filp);
                                return -EROFS;
                        }
                }
@@ -1842,9 +1839,9 @@ 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 gendisk *disk, fmode_t mode)
 {
-       struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
+       struct atari_floppy_struct *p = disk->private_data;
        if (p->ref < 0)
                p->ref = 0;
        else if (!p->ref--) {
@@ -1854,11 +1851,11 @@ static int floppy_release( struct inode * inode, struct file * filp )
        return 0;
 }
 
-static struct block_device_operations floppy_fops = {
+static const struct block_device_operations floppy_fops = {
        .owner          = THIS_MODULE,
        .open           = floppy_open,
        .release        = floppy_release,
-       .ioctl          = fd_ioctl,
+       .locked_ioctl   = fd_ioctl,
        .media_changed  = check_floppy_change,
        .revalidate_disk= floppy_revalidate,
 };
@@ -1879,11 +1876,7 @@ static int __init atari_floppy_init (void)
 
        if (!MACH_IS_ATARI)
                /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
-               return -ENXIO;
-
-       if (MACH_IS_HADES)
-               /* Hades doesn't have Atari-compatible floppy */
-               return -ENXIO;
+               return -ENODEV;
 
        if (register_blkdev(FLOPPY_MAJOR,"fd"))
                return -EBUSY;
@@ -1950,14 +1943,20 @@ Enomem:
        return -ENOMEM;
 }
 
-
-void __init atari_floppy_setup( char *str, int *ints )
+#ifndef MODULE
+static int __init atari_floppy_setup(char *str)
 {
+       int ints[3 + FD_MAX_UNITS];
        int i;
+
+       if (!MACH_IS_ATARI)
+               return 0;
+
+       str = get_options(str, 3 + FD_MAX_UNITS, ints);
        
        if (ints[0] < 1) {
                printk(KERN_ERR "ataflop_setup: no arguments!\n" );
-               return;
+               return 0;
        }
        else if (ints[0] > 2+FD_MAX_UNITS) {
                printk(KERN_ERR "ataflop_setup: too many arguments\n" );
@@ -1977,9 +1976,13 @@ void __init atari_floppy_setup( char *str, int *ints )
                else
                        UserSteprate[i-3] = ints[i];
        }
+       return 1;
 }
 
-static void atari_floppy_exit(void)
+__setup("floppy=", atari_floppy_setup);
+#endif
+
+static void __exit atari_floppy_exit(void)
 {
        int i;
        blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);