From 679ef014dcf9ac023130fa4c4339a2d2bba61086 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 25 May 2011 11:03:04 +0200 Subject: [PATCH] --- yaml --- r: 309291 b: refs/heads/master c: ebd2b0cde5a4c02e2999fc3dc4a59fdd8a040fb6 h: refs/heads/master i: 309289: 1757160349bc9ea145a6e92708c51faf05756a26 309287: 5373a417e54e4d1d70401de5411efd8822eeeed7 v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 6 - trunk/drivers/block/drbd/drbd_receiver.c | 2 +- trunk/drivers/block/floppy.c | 161 ++++++++++++----------- trunk/drivers/block/xen-blkfront.c | 44 +++---- 5 files changed, 105 insertions(+), 110 deletions(-) diff --git a/[refs] b/[refs] index f8a37500aba8..9570dcc83f2d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 13828dec457270b48f433142fce0efd1e85f2c5d +refs/heads/master: ebd2b0cde5a4c02e2999fc3dc4a59fdd8a040fb6 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 2c2fba2c37b3..bb76fc42fc42 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2770,12 +2770,6 @@ F: Documentation/firmware_class/ F: drivers/base/firmware*.c F: include/linux/firmware.h -FLOPPY DRIVER -M: Jiri Kosina -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git -S: Odd fixes -F: drivers/block/floppy.c - FPU EMULATOR M: Bill Metzenthen W: http://floatingpoint.sourceforge.net/emulator/index.html diff --git a/trunk/drivers/block/drbd/drbd_receiver.c b/trunk/drivers/block/drbd/drbd_receiver.c index 43beaca53179..e7ed0aa93a16 100644 --- a/trunk/drivers/block/drbd/drbd_receiver.c +++ b/trunk/drivers/block/drbd/drbd_receiver.c @@ -957,7 +957,7 @@ static void drbd_flush(struct drbd_conf *mdev) rv = blkdev_issue_flush(mdev->ldev->backing_bdev, GFP_KERNEL, NULL); if (rv) { - dev_err(DEV, "local disk flush failed with status %d\n", rv); + dev_info(DEV, "local disk flush failed with status %d\n", rv); /* would rather check on EOPNOTSUPP, but that is not reliable. * don't try again for ANY return value != 0 * if (rv == -EOPNOTSUPP) */ diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index cce7df367b79..b0b00d70c166 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -551,7 +551,7 @@ static void floppy_ready(void); static void floppy_start(void); static void process_fd_request(void); static void recalibrate_floppy(void); -static void floppy_shutdown(struct work_struct *); +static void floppy_shutdown(unsigned long); static int floppy_request_regions(int); static void floppy_release_regions(int); @@ -588,8 +588,6 @@ static int buffer_max = -1; static struct floppy_fdc_state fdc_state[N_FDC]; static int fdc; /* current fdc */ -static struct workqueue_struct *floppy_wq; - static struct floppy_struct *_floppy = floppy_type; static unsigned char current_drive; static long current_count_sectors; @@ -631,15 +629,16 @@ static inline void set_debugt(void) { } static inline void debugt(const char *func, const char *msg) { } #endif /* DEBUGT */ +typedef void (*timeout_fn)(unsigned long); +static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); -static DECLARE_DELAYED_WORK(fd_timeout, floppy_shutdown); static const char *timeout_message; static void is_alive(const char *func, const char *message) { /* this routine checks whether the floppy driver is "alive" */ if (test_bit(0, &fdc_busy) && command_status < 2 && - !delayed_work_pending(&fd_timeout)) { + !timer_pending(&fd_timeout)) { DPRINT("%s: timeout handler died. %s\n", func, message); } } @@ -667,18 +666,15 @@ static int output_log_pos; static void __reschedule_timeout(int drive, const char *message) { - unsigned long delay; - if (drive == current_reqD) drive = current_drive; - + del_timer(&fd_timeout); if (drive < 0 || drive >= N_DRIVE) { - delay = 20UL * HZ; + fd_timeout.expires = jiffies + 20UL * HZ; drive = 0; } else - delay = UDP->timeout; - - queue_delayed_work(floppy_wq, &fd_timeout, delay); + fd_timeout.expires = jiffies + UDP->timeout; + add_timer(&fd_timeout); if (UDP->flags & FD_DEBUG) DPRINT("reschedule timeout %s\n", message); timeout_message = message; @@ -876,7 +872,7 @@ static int lock_fdc(int drive, bool interruptible) command_status = FD_COMMAND_NONE; - reschedule_timeout(drive, "lock fdc"); + __reschedule_timeout(drive, "lock fdc"); set_fdc(drive); return 0; } @@ -884,15 +880,23 @@ static int lock_fdc(int drive, bool interruptible) /* unlocks the driver */ static void unlock_fdc(void) { + unsigned long flags; + + raw_cmd = NULL; if (!test_bit(0, &fdc_busy)) DPRINT("FDC access conflict!\n"); - raw_cmd = NULL; + if (do_floppy) + DPRINT("device interrupt still active at FDC release: %pf!\n", + do_floppy); command_status = FD_COMMAND_NONE; - __cancel_delayed_work(&fd_timeout); - do_floppy = NULL; + spin_lock_irqsave(&floppy_lock, flags); + del_timer(&fd_timeout); cont = NULL; clear_bit(0, &fdc_busy); + if (current_req || set_next_request()) + do_fd_request(current_req->q); + spin_unlock_irqrestore(&floppy_lock, flags); wake_up(&fdc_wait); } @@ -964,24 +968,26 @@ static DECLARE_WORK(floppy_work, NULL); static void schedule_bh(void (*handler)(void)) { - WARN_ON(work_pending(&floppy_work)); - PREPARE_WORK(&floppy_work, (work_func_t)handler); - queue_work(floppy_wq, &floppy_work); + schedule_work(&floppy_work); } -static DECLARE_DELAYED_WORK(fd_timer, NULL); +static DEFINE_TIMER(fd_timer, NULL, 0, 0); static void cancel_activity(void) { + unsigned long flags; + + spin_lock_irqsave(&floppy_lock, flags); do_floppy = NULL; - cancel_delayed_work_sync(&fd_timer); - cancel_work_sync(&floppy_work); + PREPARE_WORK(&floppy_work, (work_func_t)empty); + del_timer(&fd_timer); + spin_unlock_irqrestore(&floppy_lock, flags); } /* this function makes sure that the disk stays in the drive during the * transfer */ -static void fd_watchdog(struct work_struct *arg) +static void fd_watchdog(void) { debug_dcl(DP->flags, "calling disk change from watchdog\n"); @@ -991,20 +997,21 @@ static void fd_watchdog(struct work_struct *arg) cont->done(0); reset_fdc(); } else { - cancel_delayed_work(&fd_timer); - PREPARE_DELAYED_WORK(&fd_timer, fd_watchdog); - queue_delayed_work(floppy_wq, &fd_timer, HZ / 10); + del_timer(&fd_timer); + fd_timer.function = (timeout_fn)fd_watchdog; + fd_timer.expires = jiffies + HZ / 10; + add_timer(&fd_timer); } } static void main_command_interrupt(void) { - cancel_delayed_work(&fd_timer); + del_timer(&fd_timer); cont->interrupt(); } /* waits for a delay (spinup or select) to pass */ -static int fd_wait_for_completion(unsigned long expires, work_func_t function) +static int fd_wait_for_completion(unsigned long delay, timeout_fn function) { if (FDCS->reset) { reset_fdc(); /* do the reset during sleep to win time @@ -1013,10 +1020,11 @@ static int fd_wait_for_completion(unsigned long expires, work_func_t function) return 1; } - if (time_before(jiffies, expires)) { - cancel_delayed_work(&fd_timer); - PREPARE_DELAYED_WORK(&fd_timer, function); - queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies); + if (time_before(jiffies, delay)) { + del_timer(&fd_timer); + fd_timer.function = function; + fd_timer.expires = delay; + add_timer(&fd_timer); return 1; } return 0; @@ -1334,7 +1342,7 @@ static int fdc_dtr(void) */ FDCS->dtr = raw_cmd->rate & 3; return fd_wait_for_completion(jiffies + 2UL * HZ / 100, - (work_func_t)floppy_ready); + (timeout_fn)floppy_ready); } /* fdc_dtr */ static void tell_sector(void) @@ -1439,7 +1447,7 @@ static void setup_rw_floppy(void) int flags; int dflags; unsigned long ready_date; - work_func_t function; + timeout_fn function; flags = raw_cmd->flags; if (flags & (FD_RAW_READ | FD_RAW_WRITE)) @@ -1453,9 +1461,9 @@ static void setup_rw_floppy(void) */ if (time_after(ready_date, jiffies + DP->select_delay)) { ready_date -= DP->select_delay; - function = (work_func_t)floppy_start; + function = (timeout_fn)floppy_start; } else - function = (work_func_t)setup_rw_floppy; + function = (timeout_fn)setup_rw_floppy; /* wait until the floppy is spinning fast enough */ if (fd_wait_for_completion(ready_date, function)) @@ -1485,7 +1493,7 @@ static void setup_rw_floppy(void) inr = result(); cont->interrupt(); } else if (flags & FD_RAW_NEED_DISK) - fd_watchdog(NULL); + fd_watchdog(); } static int blind_seek; @@ -1794,22 +1802,20 @@ static void show_floppy(void) pr_info("do_floppy=%pf\n", do_floppy); if (work_pending(&floppy_work)) pr_info("floppy_work.func=%pf\n", floppy_work.func); - if (delayed_work_pending(&fd_timer)) - pr_info("delayed work.function=%p expires=%ld\n", - fd_timer.work.func, - fd_timer.timer.expires - jiffies); - if (delayed_work_pending(&fd_timeout)) - pr_info("timer_function=%p expires=%ld\n", - fd_timeout.work.func, - fd_timeout.timer.expires - jiffies); - + if (timer_pending(&fd_timer)) + pr_info("fd_timer.function=%pf\n", fd_timer.function); + if (timer_pending(&fd_timeout)) { + pr_info("timer_function=%pf\n", fd_timeout.function); + pr_info("expires=%lu\n", fd_timeout.expires - jiffies); + pr_info("now=%lu\n", jiffies); + } pr_info("cont=%p\n", cont); pr_info("current_req=%p\n", current_req); pr_info("command_status=%d\n", command_status); pr_info("\n"); } -static void floppy_shutdown(struct work_struct *arg) +static void floppy_shutdown(unsigned long data) { unsigned long flags; @@ -1862,7 +1868,7 @@ static int start_motor(void (*function)(void)) /* wait_for_completion also schedules reset if needed. */ return fd_wait_for_completion(DRS->select_date + DP->select_delay, - (work_func_t)function); + (timeout_fn)function); } static void floppy_ready(void) @@ -2815,6 +2821,7 @@ static void redo_fd_request(void) spin_lock_irq(&floppy_lock); pending = set_next_request(); spin_unlock_irq(&floppy_lock); + if (!pending) { do_floppy = NULL; unlock_fdc(); @@ -2891,15 +2898,13 @@ static void do_fd_request(struct request_queue *q) current_req->cmd_flags)) return; - if (test_and_set_bit(0, &fdc_busy)) { + if (test_bit(0, &fdc_busy)) { /* fdc busy, this new request will be treated when the current one is done */ is_alive(__func__, "old request running"); return; } - command_status = FD_COMMAND_NONE; - __reschedule_timeout(MAXTIMEOUT, "fd_request"); - set_fdc(0); + lock_fdc(MAXTIMEOUT, false); process_fd_request(); is_alive(__func__, ""); } @@ -3607,7 +3612,9 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) mutex_lock(&floppy_mutex); mutex_lock(&open_lock); - if (!UDRS->fd_ref--) { + if (UDRS->fd_ref < 0) + UDRS->fd_ref = 0; + else if (!UDRS->fd_ref--) { DPRINT("floppy_release with fd_ref == 0"); UDRS->fd_ref = 0; } @@ -3643,7 +3650,13 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) set_bit(FD_VERIFY_BIT, &UDRS->flags); } - UDRS->fd_ref++; + if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) + goto out2; + + if (mode & FMODE_EXCL) + UDRS->fd_ref = -1; + else + UDRS->fd_ref++; opened_bdev[drive] = bdev; @@ -3706,8 +3719,10 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) mutex_unlock(&floppy_mutex); return 0; out: - UDRS->fd_ref--; - + if (UDRS->fd_ref < 0) + UDRS->fd_ref = 0; + else + UDRS->fd_ref--; if (!UDRS->fd_ref) opened_bdev[drive] = NULL; out2: @@ -4144,16 +4159,10 @@ static int __init floppy_init(void) goto out_put_disk; } - floppy_wq = alloc_ordered_workqueue("floppy", 0); - if (!floppy_wq) { - err = -ENOMEM; - goto out_put_disk; - } - disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); if (!disks[dr]->queue) { err = -ENOMEM; - goto out_destroy_workq; + goto out_put_disk; } blk_queue_max_hw_sectors(disks[dr]->queue, 64); @@ -4204,7 +4213,7 @@ static int __init floppy_init(void) use_virtual_dma = can_use_virtual_dma & 1; fdc_state[0].address = FDC1; if (fdc_state[0].address == -1) { - cancel_delayed_work(&fd_timeout); + del_timer_sync(&fd_timeout); err = -ENODEV; goto out_unreg_region; } @@ -4215,7 +4224,7 @@ static int __init floppy_init(void) fdc = 0; /* reset fdc in case of unexpected interrupt */ err = floppy_grab_irq_and_dma(); if (err) { - cancel_delayed_work(&fd_timeout); + del_timer_sync(&fd_timeout); err = -EBUSY; goto out_unreg_region; } @@ -4272,13 +4281,13 @@ static int __init floppy_init(void) user_reset_fdc(-1, FD_RESET_ALWAYS, false); } fdc = 0; - cancel_delayed_work(&fd_timeout); + del_timer_sync(&fd_timeout); current_drive = 0; initialized = true; if (have_no_fdc) { DPRINT("no floppy controllers found\n"); err = have_no_fdc; - goto out_release_dma; + goto out_flush_work; } for (drive = 0; drive < N_DRIVE; drive++) { @@ -4293,7 +4302,7 @@ static int __init floppy_init(void) err = platform_device_register(&floppy_device[drive]); if (err) - goto out_release_dma; + goto out_flush_work; err = device_create_file(&floppy_device[drive].dev, &dev_attr_cmos); @@ -4311,14 +4320,13 @@ static int __init floppy_init(void) out_unreg_platform_dev: platform_device_unregister(&floppy_device[drive]); -out_release_dma: +out_flush_work: + flush_work_sync(&floppy_work); if (atomic_read(&usage_count)) floppy_release_irq_and_dma(); out_unreg_region: blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); platform_driver_unregister(&floppy_driver); -out_destroy_workq: - destroy_workqueue(floppy_wq); out_unreg_blkdev: unregister_blkdev(FLOPPY_MAJOR, "fd"); out_put_disk: @@ -4389,7 +4397,7 @@ static int floppy_grab_irq_and_dma(void) * We might have scheduled a free_irq(), wait it to * drain first: */ - flush_workqueue(floppy_wq); + flush_work_sync(&floppy_work); if (fd_request_irq()) { DPRINT("Unable to grab IRQ%d for the floppy driver\n", @@ -4480,9 +4488,9 @@ static void floppy_release_irq_and_dma(void) pr_info("motor off timer %d still active\n", drive); #endif - if (delayed_work_pending(&fd_timeout)) + if (timer_pending(&fd_timeout)) pr_info("floppy timer still active:%s\n", timeout_message); - if (delayed_work_pending(&fd_timer)) + if (timer_pending(&fd_timer)) pr_info("auxiliary floppy timer still active\n"); if (work_pending(&floppy_work)) pr_info("work still pending\n"); @@ -4552,9 +4560,8 @@ static void __exit floppy_module_exit(void) put_disk(disks[drive]); } - cancel_delayed_work_sync(&fd_timeout); - cancel_delayed_work_sync(&fd_timer); - destroy_workqueue(floppy_wq); + del_timer_sync(&fd_timeout); + del_timer_sync(&fd_timer); if (atomic_read(&usage_count)) floppy_release_irq_and_dma(); diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index 60eed4bdd2e4..4e86393a09cf 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -526,14 +526,6 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) return 0; } -static char *encode_disk_name(char *ptr, unsigned int n) -{ - if (n >= 26) - ptr = encode_disk_name(ptr, n / 26 - 1); - *ptr = 'a' + n % 26; - return ptr + 1; -} - static int xlvbd_alloc_gendisk(blkif_sector_t capacity, struct blkfront_info *info, u16 vdisk_info, u16 sector_size) @@ -544,7 +536,6 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, unsigned int offset; int minor; int nr_parts; - char *ptr; BUG_ON(info->gd != NULL); BUG_ON(info->rq != NULL); @@ -569,11 +560,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, "emulated IDE disks,\n\t choose an xvd device name" "from xvde on\n", info->vdevice); } - if (minor >> MINORBITS) { - pr_warn("blkfront: %#x's minor (%#x) out of range; ignoring\n", - info->vdevice, minor); - return -ENODEV; - } + err = -ENODEV; if ((minor % nr_parts) == 0) nr_minors = nr_parts; @@ -587,14 +574,23 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, if (gd == NULL) goto release; - strcpy(gd->disk_name, DEV_NAME); - ptr = encode_disk_name(gd->disk_name + sizeof(DEV_NAME) - 1, offset); - BUG_ON(ptr >= gd->disk_name + DISK_NAME_LEN); - if (nr_minors > 1) - *ptr = 0; - else - snprintf(ptr, gd->disk_name + DISK_NAME_LEN - ptr, - "%d", minor & (nr_parts - 1)); + if (nr_minors > 1) { + if (offset < 26) + sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); + else + sprintf(gd->disk_name, "%s%c%c", DEV_NAME, + 'a' + ((offset / 26)-1), 'a' + (offset % 26)); + } else { + if (offset < 26) + sprintf(gd->disk_name, "%s%c%d", DEV_NAME, + 'a' + offset, + minor & (nr_parts - 1)); + else + sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME, + 'a' + ((offset / 26) - 1), + 'a' + (offset % 26), + minor & (nr_parts - 1)); + } gd->major = XENVBD_MAJOR; gd->first_minor = minor; @@ -1500,9 +1496,7 @@ module_init(xlblk_init); static void __exit xlblk_exit(void) { - xenbus_unregister_driver(&blkfront_driver); - unregister_blkdev(XENVBD_MAJOR, DEV_NAME); - kfree(minors); + return xenbus_unregister_driver(&blkfront_driver); } module_exit(xlblk_exit);