Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / block / swim3.c
index 5b09cf1..01f042f 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/io.h>
 #include <asm/dbdma.h>
 #include <asm/prom.h>
@@ -176,6 +177,7 @@ struct swim3 {
 
 struct floppy_state {
        enum swim_state state;
+       spinlock_t lock;
        struct swim3 __iomem *swim3;    /* hardware registers */
        struct dbdma_regs __iomem *dma; /* DMA controller registers */
        int     swim3_intr;     /* interrupt number for SWIM3 */
@@ -253,7 +255,7 @@ static int floppy_revalidate(struct gendisk *disk);
 static int swim3_add_device(struct device_node *swims);
 int swim3_init(void);
 
-#ifndef CONFIG_PMAC_PBOOK
+#ifndef CONFIG_PMAC_MEDIABAY
 #define check_media_bay(which, what)   1
 #endif
 
@@ -297,12 +299,13 @@ static void do_fd_request(request_queue_t * q)
        int i;
        for(i=0;i<floppy_count;i++)
        {
+#ifdef CONFIG_PMAC_MEDIABAY
                if (floppy_states[i].media_bay &&
                        check_media_bay(floppy_states[i].media_bay, MB_FD))
                        continue;
+#endif /* CONFIG_PMAC_MEDIABAY */
                start_request(&floppy_states[i]);
        }
-       sti();
 }
 
 static void start_request(struct floppy_state *fs)
@@ -368,7 +371,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
 {
        unsigned long flags;
 
-       save_flags(flags); cli();
+       spin_lock_irqsave(&fs->lock, flags);
        if (fs->timeout_pending)
                del_timer(&fs->timeout);
        fs->timeout.expires = jiffies + nticks;
@@ -376,7 +379,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
        fs->timeout.data = (unsigned long) fs;
        add_timer(&fs->timeout);
        fs->timeout_pending = 1;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&fs->lock, flags);
 }
 
 static inline void scan_track(struct floppy_state *fs)
@@ -788,14 +791,13 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&fs->lock, flags);
        if (fs->state != idle) {
                ++fs->wanted;
                while (fs->state != available) {
                        if (interruptible && signal_pending(current)) {
                                --fs->wanted;
-                               restore_flags(flags);
+                               spin_unlock_irqrestore(&fs->lock, flags);
                                return -EINTR;
                        }
                        interruptible_sleep_on(&fs->wait);
@@ -803,7 +805,7 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
                --fs->wanted;
        }
        fs->state = state;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&fs->lock, flags);
        return 0;
 }
 
@@ -811,11 +813,10 @@ static void release_drive(struct floppy_state *fs)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&fs->lock, flags);
        fs->state = idle;
        start_request(fs);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&fs->lock, flags);
 }
 
 static int fd_eject(struct floppy_state *fs)
@@ -832,8 +833,7 @@ static int fd_eject(struct floppy_state *fs)
                        break;
                }
                swim3_select(fs, RELAX);
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
                if (swim3_readbit(fs, DISK_IN) == 0)
                        break;
        }
@@ -856,8 +856,10 @@ static int floppy_ioctl(struct inode *inode, struct file *filp,
        if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
                return -EPERM;
 
+#ifdef CONFIG_PMAC_MEDIABAY
        if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
                return -ENXIO;
+#endif
 
        switch (cmd) {
        case FDEJECT:
@@ -881,8 +883,10 @@ static int floppy_open(struct inode *inode, struct file *filp)
        int n, err = 0;
 
        if (fs->ref_count == 0) {
+#ifdef CONFIG_PMAC_MEDIABAY
                if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
                        return -ENXIO;
+#endif
                out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
                out_8(&sw->control_bic, 0xff);
                out_8(&sw->mode, 0x95);
@@ -900,8 +904,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
                                break;
                        }
                        swim3_select(fs, RELAX);
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(1);
+                       schedule_timeout_interruptible(1);
                }
                if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
                                 || swim3_readbit(fs, DISK_IN) == 0))
@@ -967,8 +970,10 @@ static int floppy_revalidate(struct gendisk *disk)
        struct swim3 __iomem *sw;
        int ret, n;
 
+#ifdef CONFIG_PMAC_MEDIABAY
        if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
                return -ENXIO;
+#endif
 
        sw = fs->swim3;
        grab_drive(fs, revalidating, 0);
@@ -984,8 +989,7 @@ static int floppy_revalidate(struct gendisk *disk)
                if (signal_pending(current))
                        break;
                swim3_select(fs, RELAX);
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
        }
        ret = swim3_readbit(fs, SEEK_COMPLETE) == 0
                || swim3_readbit(fs, DISK_IN) == 0;
@@ -1079,23 +1083,33 @@ static int swim3_add_device(struct device_node *swim)
 {
        struct device_node *mediabay;
        struct floppy_state *fs = &floppy_states[floppy_count];
+       struct resource res_reg, res_dma;
 
-       if (swim->n_addrs < 2)
-       {
-               printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n",
-                      swim->n_addrs, swim->n_intrs);
+       if (of_address_to_resource(swim, 0, &res_reg) ||
+           of_address_to_resource(swim, 1, &res_dma)) {
+               printk(KERN_ERR "swim3: Can't get addresses\n");
                return -EINVAL;
        }
-
-       if (swim->n_intrs < 2)
-       {
-               printk(KERN_INFO "swim3: expecting 2 intrs (n_addrs:%d, n_intrs:%d)\n",
-                      swim->n_addrs, swim->n_intrs);
+       if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1,
+                              " (reg)") == NULL) {
+               printk(KERN_ERR "swim3: Can't request register space\n");
+               return -EINVAL;
+       }
+       if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1,
+                              " (dma)") == NULL) {
+               release_mem_region(res_reg.start,
+                                  res_reg.end - res_reg.start + 1);
+               printk(KERN_ERR "swim3: Can't request DMA space\n");
                return -EINVAL;
        }
 
-       if (!request_OF_resource(swim, 0, NULL)) {
-               printk(KERN_INFO "swim3: can't request IO resource !\n");
+       if (swim->n_intrs < 2) {
+               printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n",
+                      swim->n_intrs);
+               release_mem_region(res_reg.start,
+                                  res_reg.end - res_reg.start + 1);
+               release_mem_region(res_dma.start,
+                                  res_dma.end - res_dma.start + 1);
                return -EINVAL;
        }
 
@@ -1104,11 +1118,10 @@ static int swim3_add_device(struct device_node *swim)
                pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
        
        memset(fs, 0, sizeof(*fs));
+       spin_lock_init(&fs->lock);
        fs->state = idle;
-       fs->swim3 = (struct swim3 __iomem *)
-               ioremap(swim->addrs[0].address, 0x200);
-       fs->dma = (struct dbdma_regs __iomem *)
-               ioremap(swim->addrs[1].address, 0x200);
+       fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200);
+       fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200);
        fs->swim3_intr = swim->intrs[0].line;
        fs->dma_intr = swim->intrs[1].line;
        fs->cur_cyl = -1;