The usage_count was being protected by a lock which was only there to
create an atomic counter.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
#define NEED_1_RECAL -2
#define NEED_2_RECAL -3
#define NEED_1_RECAL -2
#define NEED_2_RECAL -3
+static atomic_t usage_count = ATOMIC_INIT(0);
/* buffer related variables */
static int buffer_track = -1;
/* buffer related variables */
static int buffer_track = -1;
/* locks the driver */
static int _lock_fdc(int drive, bool interruptible, int line)
{
/* locks the driver */
static int _lock_fdc(int drive, bool interruptible, int line)
{
+ if (atomic_read(&usage_count) == 0) {
pr_err("Trying to lock fdc while usage count=0 at line %d\n",
line);
return -1;
pr_err("Trying to lock fdc while usage count=0 at line %d\n",
line);
return -1;
- if (usage_count == 0) {
+ if (atomic_read(&usage_count) == 0) {
pr_info("warning: usage count=0, current_req=%p exiting\n",
current_req);
pr_info("sect=%ld type=%x flags=%x\n",
pr_info("warning: usage count=0, current_req=%p exiting\n",
current_req);
pr_info("sect=%ld type=%x flags=%x\n",
if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
test_bit(drive, &fake_change) || NO_GEOM) {
if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
test_bit(drive, &fake_change) || NO_GEOM) {
- if (usage_count == 0) {
+ if (atomic_read(&usage_count) == 0) {
pr_info("VFS: revalidate called on non-open device.\n");
return -EFAULT;
}
pr_info("VFS: revalidate called on non-open device.\n");
return -EFAULT;
}
platform_device_unregister(&floppy_device[drive]);
out_flush_work:
flush_scheduled_work();
platform_device_unregister(&floppy_device[drive]);
out_flush_work:
flush_scheduled_work();
+ if (atomic_read(&usage_count))
floppy_release_irq_and_dma();
out_unreg_region:
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
floppy_release_irq_and_dma();
out_unreg_region:
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
-static DEFINE_SPINLOCK(floppy_usage_lock);
-
static const struct io_region {
int offset;
int size;
static const struct io_region {
int offset;
int size;
static int floppy_grab_irq_and_dma(void)
{
static int floppy_grab_irq_and_dma(void)
{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_usage_lock, flags);
- if (usage_count++) {
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
+ if (atomic_inc_return(&usage_count) > 1)
- }
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
/*
* We might have scheduled a free_irq(), wait it to
/*
* We might have scheduled a free_irq(), wait it to
if (fd_request_irq()) {
DPRINT("Unable to grab IRQ%d for the floppy driver\n",
FLOPPY_IRQ);
if (fd_request_irq()) {
DPRINT("Unable to grab IRQ%d for the floppy driver\n",
FLOPPY_IRQ);
- spin_lock_irqsave(&floppy_usage_lock, flags);
- usage_count--;
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
+ atomic_dec(&usage_count);
return -1;
}
if (fd_request_dma()) {
return -1;
}
if (fd_request_dma()) {
use_virtual_dma = can_use_virtual_dma = 1;
if (!(can_use_virtual_dma & 1)) {
fd_free_irq();
use_virtual_dma = can_use_virtual_dma = 1;
if (!(can_use_virtual_dma & 1)) {
fd_free_irq();
- spin_lock_irqsave(&floppy_usage_lock, flags);
- usage_count--;
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
+ atomic_dec(&usage_count);
fd_free_dma();
while (--fdc >= 0)
floppy_release_regions(fdc);
fd_free_dma();
while (--fdc >= 0)
floppy_release_regions(fdc);
- spin_lock_irqsave(&floppy_usage_lock, flags);
- usage_count--;
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
+ atomic_dec(&usage_count);
#endif
long tmpsize;
unsigned long tmpaddr;
#endif
long tmpsize;
unsigned long tmpaddr;
- spin_lock_irqsave(&floppy_usage_lock, flags);
- if (--usage_count) {
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
+ if (!atomic_dec_and_test(&usage_count))
- }
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
if (irqdma_allocated) {
fd_disable_dma();
fd_free_dma();
if (irqdma_allocated) {
fd_disable_dma();
fd_free_dma();
del_timer_sync(&fd_timer);
blk_cleanup_queue(floppy_queue);
del_timer_sync(&fd_timer);
blk_cleanup_queue(floppy_queue);
+ if (atomic_read(&usage_count))
floppy_release_irq_and_dma();
/* eject disk, if any */
floppy_release_irq_and_dma();
/* eject disk, if any */