diff options
Diffstat (limited to 'drivers/block')
38 files changed, 919 insertions, 832 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 459f1bc..c5f22bb 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -2533,7 +2533,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) Controller->RequestQueue[n] = RequestQueue; blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit); RequestQueue->queuedata = Controller; - blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit); blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit); blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); disk->queue = RequestQueue; diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 0552258..0182a22 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -54,6 +54,7 @@ */ #include <linux/module.h> +#include <linux/slab.h> #include <linux/fd.h> #include <linux/hdreg.h> diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 3af97d4..035cefe 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -9,6 +9,7 @@ #include <linux/backing-dev.h> #include <linux/fs.h> #include <linux/ioctl.h> +#include <linux/slab.h> #include <linux/genhd.h> #include <linux/netdevice.h> #include "aoe.h" diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 62141ec..4a1b9e74 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -8,6 +8,7 @@ #include <linux/blkdev.h> #include <linux/completion.h> #include <linux/delay.h> +#include <linux/slab.h> #include <linux/smp_lock.h> #include <linux/skbuff.h> #include "aoe.h" diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 64a223b..5674bd0 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -5,6 +5,7 @@ */ #include <linux/ata.h> +#include <linux/slab.h> #include <linux/hdreg.h> #include <linux/blkdev.h> #include <linux/skbuff.h> diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index fa67027..0849280 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -8,6 +8,7 @@ #include <linux/blkdev.h> #include <linux/netdevice.h> #include <linux/delay.h> +#include <linux/slab.h> #include "aoe.h" static void dummy_timer(ulong); diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index ce0d62c..4d3bc0d 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -4,6 +4,7 @@ * Ethernet portion of AoE driver */ +#include <linux/gfp.h> #include <linux/hdreg.h> #include <linux/blkdev.h> #include <linux/netdevice.h> diff --git a/drivers/block/brd.c b/drivers/block/brd.c index c6ddeac..6081e81 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -15,9 +15,9 @@ #include <linux/blkdev.h> #include <linux/bio.h> #include <linux/highmem.h> -#include <linux/gfp.h> #include <linux/radix-tree.h> #include <linux/buffer_head.h> /* invalidate_bh_lrus() */ +#include <linux/slab.h> #include <asm/uaccess.h> diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 9e3af30..eb5ff05 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3341,6 +3341,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr); + spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); fail_all_cmds(h->ctlr); return IRQ_HANDLED; } diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 17956ff..df01899 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio, int error) put_ldev(mdev); } +/* sector to word */ #define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL)) + /* activity log to on disk bitmap -- prepare bio unless that sector * is already covered by previously prepared bios */ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, @@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, { struct bio *bio; struct page *page; - sector_t on_disk_sector = enr + mdev->ldev->md.md_offset - + mdev->ldev->md.bm_offset; + sector_t on_disk_sector; unsigned int page_offset = PAGE_SIZE; int offset; int i = 0; int err = -ENOMEM; + /* We always write aligned, full 4k blocks, + * so we can ignore the logical_block_size (for now) */ + enr &= ~7U; + on_disk_sector = enr + mdev->ldev->md.md_offset + + mdev->ldev->md.bm_offset; + + D_ASSERT(!(on_disk_sector & 7U)); + /* Check if that enr is already covered by an already created bio. * Caution, bios[] is not NULL terminated, * but only initialized to all NULL. @@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, offset = S2W(enr); drbd_bm_get_lel(mdev, offset, - min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset), + min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset), kmap(page) + page_offset); kunmap(page); @@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, bio->bi_bdev = mdev->ldev->md_bdev; bio->bi_sector = on_disk_sector; - if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE) + if (bio_add_page(bio, page, 4096, page_offset) != 4096) goto out_put_page; atomic_inc(&wc->count); @@ -1327,7 +1336,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev) /* ok, ->resync is there. */ for (i = 0; i < mdev->resync->nr_elements; i++) { e = lc_element_by_index(mdev->resync, i); - bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL; + bm_ext = lc_entry(e, struct bm_extent, lce); if (bm_ext->lce.lc_number == LC_FREE) continue; if (bm_ext->lce.lc_number == mdev->resync_wenr) { diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index b61057e..3390716 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -26,6 +26,7 @@ #include <linux/vmalloc.h> #include <linux/string.h> #include <linux/drbd.h> +#include <linux/slab.h> #include <asm/kmap_types.h> #include "drbd_int.h" @@ -66,7 +67,7 @@ struct drbd_bitmap { size_t bm_words; size_t bm_number_of_pages; sector_t bm_dev_capacity; - struct semaphore bm_change; /* serializes resize operations */ + struct mutex bm_change; /* serializes resize operations */ atomic_t bm_async_io; wait_queue_head_t bm_io_wait; @@ -114,7 +115,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why) return; } - trylock_failed = down_trylock(&b->bm_change); + trylock_failed = !mutex_trylock(&b->bm_change); if (trylock_failed) { dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n", @@ -125,7 +126,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why) b->bm_task == mdev->receiver.task ? "receiver" : b->bm_task == mdev->asender.task ? "asender" : b->bm_task == mdev->worker.task ? "worker" : "?"); - down(&b->bm_change); + mutex_lock(&b->bm_change); } if (__test_and_set_bit(BM_LOCKED, &b->bm_flags)) dev_err(DEV, "FIXME bitmap already locked in bm_lock\n"); @@ -147,7 +148,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev) b->bm_why = NULL; b->bm_task = NULL; - up(&b->bm_change); + mutex_unlock(&b->bm_change); } /* word offset to long pointer */ @@ -295,7 +296,7 @@ int drbd_bm_init(struct drbd_conf *mdev) if (!b) return -ENOMEM; spin_lock_init(&b->bm_lock); - init_MUTEX(&b->bm_change); + mutex_init(&b->bm_change); init_waitqueue_head(&b->bm_io_wait); mdev->bitmap = b; diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2bf3a6e..e5e86a7 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -95,7 +95,7 @@ extern char usermode_helper[]; /* All EEs on the free list should have ID_VACANT (== 0) * freshly allocated EEs get !ID_VACANT (== 1) - * so if it says "cannot dereference null pointer at adress 0x00000001", + * so if it says "cannot dereference null pointer at address 0x00000001", * it is most likely one of these :( */ #define ID_IN_SYNC (4711ULL) @@ -261,6 +261,9 @@ static inline const char *cmdname(enum drbd_packets cmd) [P_OV_REQUEST] = "OVRequest", [P_OV_REPLY] = "OVReply", [P_OV_RESULT] = "OVResult", + [P_CSUM_RS_REQUEST] = "CsumRSRequest", + [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", + [P_COMPRESSED_BITMAP] = "CBitmap", [P_MAX_CMD] = NULL, }; @@ -443,13 +446,18 @@ struct p_rs_param_89 { char csums_alg[SHARED_SECRET_MAX]; } __packed; +enum drbd_conn_flags { + CF_WANT_LOSE = 1, + CF_DRY_RUN = 2, +}; + struct p_protocol { struct p_header head; u32 protocol; u32 after_sb_0p; u32 after_sb_1p; u32 after_sb_2p; - u32 want_lose; + u32 conn_flags; u32 two_primaries; /* Since protocol version 87 and higher. */ @@ -791,6 +799,8 @@ enum { * while this is set. */ RESIZE_PENDING, /* Size change detected locally, waiting for the response from * the peer, if it changed there as well. */ + CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ + GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ }; struct drbd_bitmap; /* opaque for drbd_conf */ @@ -1171,7 +1181,7 @@ extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf /* Meta data layout We reserve a 128MB Block (4k aligned) * either at the end of the backing device - * or on a seperate meta data device. */ + * or on a separate meta data device. */ #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ /* The following numbers are sectors */ diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index ab871e0..93d1f9b 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc) int drbd_send_protocol(struct drbd_conf *mdev) { struct p_protocol *p; - int size, rv; + int size, cf, rv; size = sizeof(struct p_protocol); @@ -1685,9 +1685,22 @@ int drbd_send_protocol(struct drbd_conf *mdev) p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p); p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p); p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p); - p->want_lose = cpu_to_be32(mdev->net_conf->want_lose); p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries); + cf = 0; + if (mdev->net_conf->want_lose) + cf |= CF_WANT_LOSE; + if (mdev->net_conf->dry_run) { + if (mdev->agreed_pro_version >= 92) + cf |= CF_DRY_RUN; + else { + dev_err(DEV, "--dry-run is not supported by peer"); + kfree(p); + return 0; + } + } + p->conn_flags = cpu_to_be32(cf); + if (mdev->agreed_pro_version >= 87) strcpy(p->integrity_alg, mdev->net_conf->integrity_alg); @@ -3161,14 +3174,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) void drbd_free_sock(struct drbd_conf *mdev) { if (mdev->data.socket) { + mutex_lock(&mdev->data.mutex); kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR); sock_release(mdev->data.socket); mdev->data.socket = NULL; + mutex_unlock(&mdev->data.mutex); } if (mdev->meta.socket) { + mutex_lock(&mdev->meta.mutex); kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR); sock_release(mdev->meta.socket); mdev->meta.socket = NULL; + mutex_unlock(&mdev->meta.mutex); } } diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 4df3b40..6429d2b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) } if (r == SS_NO_UP_TO_DATE_DISK && force && - (mdev->state.disk == D_INCONSISTENT || - mdev->state.disk == D_OUTDATED)) { + (mdev->state.disk < D_UP_TO_DATE && + mdev->state.disk >= D_INCONSISTENT)) { mask.disk = D_MASK; val.disk = D_UP_TO_DATE; forced = 1; @@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, } reply->ret_code = - drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer); + drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force); return 0; } @@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp drbd_md_set_sector_offsets(mdev, nbc); + /* allocate a second IO page if logical_block_size != 512 */ + logical_block_size = bdev_logical_block_size(nbc->md_bdev); + if (logical_block_size == 0) + logical_block_size = MD_SECTOR_SIZE; + + if (logical_block_size != MD_SECTOR_SIZE) { + if (!mdev->md_io_tmpp) { + struct page *page = alloc_page(GFP_NOIO); + if (!page) + goto force_diskless_dec; + + dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", + logical_block_size, MD_SECTOR_SIZE); + dev_warn(DEV, "Workaround engaged (has performance impact).\n"); + + mdev->md_io_tmpp = page; + } + } + if (!mdev->bitmap) { if (drbd_bm_init(mdev)) { retcode = ERR_NOMEM; @@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp goto force_diskless_dec; } - /* allocate a second IO page if logical_block_size != 512 */ - logical_block_size = bdev_logical_block_size(nbc->md_bdev); - if (logical_block_size == 0) - logical_block_size = MD_SECTOR_SIZE; - - if (logical_block_size != MD_SECTOR_SIZE) { - if (!mdev->md_io_tmpp) { - struct page *page = alloc_page(GFP_NOIO); - if (!page) - goto force_diskless_dec; - - dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", - logical_block_size, MD_SECTOR_SIZE); - dev_warn(DEV, "Workaround engaged (has performance impact).\n"); - - mdev->md_io_tmpp = page; - } - } - /* Reset the "barriers don't work" bits here, then force meta data to * be written, to ensure we determine if barriers are supported. */ if (nbc->dc.no_md_flush) diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index df8ad96..be3374b 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -28,7 +28,6 @@ #include <asm/uaccess.h> #include <linux/fs.h> #include <linux/file.h> -#include <linux/slab.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/drbd.h> diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d065c64..3f096e7 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -899,7 +899,8 @@ retry: drbd_thread_start(&mdev->asender); - drbd_send_protocol(mdev); + if (!drbd_send_protocol(mdev)) + return -1; drbd_send_sync_param(mdev, &mdev->sync_conf); drbd_send_sizes(mdev, 0); drbd_send_uuids(mdev); @@ -2513,6 +2514,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol } if (hg == -100) { + /* FIXME this log message is not correct if we end up here + * after an attempted attach on a diskless node. + * We just refuse to attach -- well, we drop the "connection" + * to that disk, in a way... */ dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); drbd_khelper(mdev, "split-brain"); return C_MASK; @@ -2538,6 +2543,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol } } + if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) { + if (hg == 0) + dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n"); + else + dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.", + drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET), + abs(hg) >= 2 ? "full" : "bit-map based"); + return C_MASK; + } + if (abs(hg) >= 2) { dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) @@ -2585,7 +2600,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) struct p_protocol *p = (struct p_protocol *)h; int header_size, data_size; int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; - int p_want_lose, p_two_primaries; + int p_want_lose, p_two_primaries, cf; char p_integrity_alg[SHARED_SECRET_MAX] = ""; header_size = sizeof(*p) - sizeof(*h); @@ -2598,8 +2613,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) p_after_sb_0p = be32_to_cpu(p->after_sb_0p); p_after_sb_1p = be32_to_cpu(p->after_sb_1p); p_after_sb_2p = be32_to_cpu(p->after_sb_2p); - p_want_lose = be32_to_cpu(p->want_lose); p_two_primaries = be32_to_cpu(p->two_primaries); + cf = be32_to_cpu(p->conn_flags); + p_want_lose = cf & CF_WANT_LOSE; + + clear_bit(CONN_DRY_RUN, &mdev->flags); + + if (cf & CF_DRY_RUN) + set_bit(CONN_DRY_RUN, &mdev->flags); if (p_proto != mdev->net_conf->wire_protocol) { dev_err(DEV, "incompatible communication protocols\n"); @@ -3118,13 +3139,16 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h) put_ldev(mdev); if (nconn == C_MASK) { + nconn = C_CONNECTED; if (mdev->state.disk == D_NEGOTIATING) { drbd_force_state(mdev, NS(disk, D_DISKLESS)); - nconn = C_CONNECTED; } else if (peer_state.disk == D_NEGOTIATING) { dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); peer_state.disk = D_DISKLESS; + real_peer_disk = D_DISKLESS; } else { + if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags)) + return FALSE; D_ASSERT(oconn == C_WF_REPORT_PARAMS); drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); return FALSE; @@ -3594,10 +3618,7 @@ static void drbd_disconnect(struct drbd_conf *mdev) /* asender does not clean up anything. it must not interfere, either */ drbd_thread_stop(&mdev->asender); - - mutex_lock(&mdev->data.mutex); drbd_free_sock(mdev); - mutex_unlock(&mdev->data.mutex); spin_lock_irq(&mdev->req_lock); _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); @@ -4054,6 +4075,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h) { /* restore idle timeout */ mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; + if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags)) + wake_up(&mdev->misc_wait); return TRUE; } diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index f22c1bc..16119d7 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -57,7 +57,7 @@ * * It may me handed over to the local disk subsystem. * It may be completed by the local disk subsystem, - * either sucessfully or with io-error. + * either successfully or with io-error. * In case it is a READ request, and it failed locally, * it may be retried remotely. * diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b453c2b..44bf6d1 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) if (eq) { drbd_set_in_sync(mdev, e->sector, e->size); - mdev->rs_same_csum++; + /* rs_same_csums unit is BM_BLOCK_SIZE */ + mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT; ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e); } else { inc_rs_pending(mdev); @@ -1288,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na) return retcode; } +static void ping_peer(struct drbd_conf *mdev) +{ + clear_bit(GOT_PING_ACK, &mdev->flags); + request_ping(mdev); + wait_event(mdev->misc_wait, + test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED); +} + /** * drbd_start_resync() - Start the resync process * @mdev: DRBD device. @@ -1371,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) _drbd_pause_after(mdev); } write_unlock_irq(&global_state_lock); - drbd_state_unlock(mdev); put_ldev(mdev); if (r == SS_SUCCESS) { @@ -1382,11 +1390,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) if (mdev->rs_total == 0) { /* Peer still reachable? Beware of failing before-resync-target handlers! */ - request_ping(mdev); - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */ + ping_peer(mdev); drbd_resync_finished(mdev); - return; } /* ns.conn may already be != mdev->state.conn, @@ -1398,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) drbd_md_sync(mdev); } + drbd_state_unlock(mdev); } int drbd_worker(struct drbd_thread *thi) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index b9b1170..90c4038 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -144,13 +144,23 @@ * Better audit of register_blkdev. */ -#define FLOPPY_SANITY_CHECK #undef FLOPPY_SILENT_DCL_CLEAR #define REALLY_SLOW_IO #define DEBUGT 2 -#define DCL_DEBUG /* debug disk change line */ + +#define DPRINT(format, args...) \ + pr_info("floppy%d: " format, current_drive, ##args) + +#define DCL_DEBUG /* debug disk change line */ +#ifdef DCL_DEBUG +#define debug_dcl(test, fmt, args...) \ + do { if ((test) & FD_DEBUG) DPRINT(fmt, ##args); } while (0) +#else +#define debug_dcl(test, fmt, args...) \ + do { if (0) DPRINT(fmt, ##args); } while (0) +#endif /* do print messages for unexpected interrupts */ static int print_unex = 1; @@ -180,6 +190,8 @@ static int print_unex = 1; #include <linux/mod_devicetable.h> #include <linux/buffer_head.h> /* for invalidate_buffers() */ #include <linux/mutex.h> +#include <linux/io.h> +#include <linux/uaccess.h> /* * PS/2 floppies have much slower step rates than regular floppies. @@ -191,8 +203,6 @@ static int slow_floppy; #include <asm/dma.h> #include <asm/irq.h> #include <asm/system.h> -#include <asm/io.h> -#include <asm/uaccess.h> static int FLOPPY_IRQ = 6; static int FLOPPY_DMA = 2; @@ -241,8 +251,6 @@ static int allowed_drive_mask = 0x33; static int irqdma_allocated; -#define DEVICE_NAME "floppy" - #include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/cdrom.h> /* for the compatibility eject ioctl */ @@ -250,7 +258,7 @@ static int irqdma_allocated; static struct request *current_req; static struct request_queue *floppy_queue; -static void do_fd_request(struct request_queue * q); +static void do_fd_request(struct request_queue *q); #ifndef fd_get_dma_residue #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) @@ -263,7 +271,7 @@ static void do_fd_request(struct request_queue * q); #endif #ifndef fd_dma_mem_alloc -#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size)) +#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL, get_order(size)) #endif static inline void fallback_on_nodma_alloc(char **addr, size_t l) @@ -273,7 +281,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) return; /* we have the memory */ if (can_use_virtual_dma != 2) return; /* no fallback allowed */ - printk("DMA memory shortage. Temporarily falling back on virtual DMA\n"); + pr_info("DMA memory shortage. Temporarily falling back on virtual DMA\n"); *addr = (char *)nodma_mem_alloc(l); #else return; @@ -283,59 +291,50 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) /* End dma memory related stuff */ static unsigned long fake_change; -static int initialising = 1; +static bool initialized; -#define ITYPE(x) (((x)>>2) & 0x1f) -#define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) -#define UNIT(x) ((x) & 0x03) /* drive on fdc */ -#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ +#define ITYPE(x) (((x) >> 2) & 0x1f) +#define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) +#define UNIT(x) ((x) & 0x03) /* drive on fdc */ +#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ /* reverse mapping from unit and fdc to drive */ #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) -#define DP (&drive_params[current_drive]) -#define DRS (&drive_state[current_drive]) -#define DRWE (&write_errors[current_drive]) -#define FDCS (&fdc_state[fdc]) -#define CLEARF(x) clear_bit(x##_BIT, &DRS->flags) -#define SETF(x) set_bit(x##_BIT, &DRS->flags) -#define TESTF(x) test_bit(x##_BIT, &DRS->flags) -#define UDP (&drive_params[drive]) -#define UDRS (&drive_state[drive]) -#define UDRWE (&write_errors[drive]) -#define UFDCS (&fdc_state[FDC(drive)]) -#define UCLEARF(x) clear_bit(x##_BIT, &UDRS->flags) -#define USETF(x) set_bit(x##_BIT, &UDRS->flags) -#define UTESTF(x) test_bit(x##_BIT, &UDRS->flags) +#define DP (&drive_params[current_drive]) +#define DRS (&drive_state[current_drive]) +#define DRWE (&write_errors[current_drive]) +#define FDCS (&fdc_state[fdc]) -#define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args) +#define UDP (&drive_params[drive]) +#define UDRS (&drive_state[drive]) +#define UDRWE (&write_errors[drive]) +#define UFDCS (&fdc_state[FDC(drive)]) -#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2) -#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) - -#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x))) +#define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2) +#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) /* read/write */ -#define COMMAND raw_cmd->cmd[0] -#define DR_SELECT raw_cmd->cmd[1] -#define TRACK raw_cmd->cmd[2] -#define HEAD raw_cmd->cmd[3] -#define SECTOR raw_cmd->cmd[4] -#define SIZECODE raw_cmd->cmd[5] -#define SECT_PER_TRACK raw_cmd->cmd[6] -#define GAP raw_cmd->cmd[7] -#define SIZECODE2 raw_cmd->cmd[8] +#define COMMAND (raw_cmd->cmd[0]) +#define DR_SELECT (raw_cmd->cmd[1]) +#define TRACK (raw_cmd->cmd[2]) +#define HEAD (raw_cmd->cmd[3]) +#define SECTOR (raw_cmd->cmd[4]) +#define SIZECODE (raw_cmd->cmd[5]) +#define SECT_PER_TRACK (raw_cmd->cmd[6]) +#define GAP (raw_cmd->cmd[7]) +#define SIZECODE2 (raw_cmd->cmd[8]) #define NR_RW 9 /* format */ -#define F_SIZECODE raw_cmd->cmd[2] -#define F_SECT_PER_TRACK raw_cmd->cmd[3] -#define F_GAP raw_cmd->cmd[4] -#define F_FILL raw_cmd->cmd[5] +#define F_SIZECODE (raw_cmd->cmd[2]) +#define F_SECT_PER_TRACK (raw_cmd->cmd[3]) +#define F_GAP (raw_cmd->cmd[4]) +#define F_FILL (raw_cmd->cmd[5]) #define NR_F 6 /* - * Maximum disk size (in kilobytes). This default is used whenever the - * current disk size is unknown. + * Maximum disk size (in kilobytes). + * This default is used whenever the current disk size is unknown. * [Now it is rather a minimum] */ #define MAX_DISK_SIZE 4 /* 3984 */ @@ -345,16 +344,17 @@ static int initialising = 1; */ #define MAX_REPLIES 16 static unsigned char reply_buffer[MAX_REPLIES]; -static int inr; /* size of reply buffer, when called from interrupt */ -#define ST0 (reply_buffer[0]) -#define ST1 (reply_buffer[1]) -#define ST2 (reply_buffer[2]) -#define ST3 (reply_buffer[0]) /* result of GETSTATUS */ -#define R_TRACK (reply_buffer[3]) -#define R_HEAD (reply_buffer[4]) -#define R_SECTOR (reply_buffer[5]) -#define R_SIZECODE (reply_buffer[6]) -#define SEL_DLY (2*HZ/100) +static int inr; /* size of reply buffer, when called from interrupt */ +#define ST0 (reply_buffer[0]) +#define ST1 (reply_buffer[1]) +#define ST2 (reply_buffer[2]) +#define ST3 (reply_buffer[0]) /* result of GETSTATUS */ +#define R_TRACK (reply_buffer[3]) +#define R_HEAD (reply_buffer[4]) +#define R_SECTOR (reply_buffer[5]) +#define R_SIZECODE (reply_buffer[6]) + +#define SEL_DLY (2 * HZ / 100) /* * this struct defines the different floppy drive types. @@ -505,9 +505,9 @@ static char floppy_device_name[] = "floppy"; static int probing; /* Synchronization of FDC access. */ -#define FD_COMMAND_NONE -1 -#define FD_COMMAND_ERROR 2 -#define FD_COMMAND_OKAY 3 +#define FD_COMMAND_NONE -1 +#define FD_COMMAND_ERROR 2 +#define FD_COMMAND_OKAY 3 static volatile int command_status = FD_COMMAND_NONE; static unsigned long fdc_busy; @@ -515,11 +515,6 @@ static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); static DECLARE_WAIT_QUEUE_HEAD(command_done); #define NO_SIGNAL (!interruptible || !signal_pending(current)) -#define CALL(x) if ((x) == -EINTR) return -EINTR -#define ECALL(x) if ((ret = (x))) return ret; -#define _WAIT(x,i) CALL(ret=wait_til_done((x),i)) -#define WAIT(x) _WAIT((x),interruptible) -#define IWAIT(x) _WAIT((x),1) /* Errors during formatting are counted here. */ static int format_errors; @@ -545,8 +540,9 @@ static int max_buffer_sectors; static int *errors; typedef void (*done_f)(int); static struct cont_t { - void (*interrupt)(void); /* this is called after the interrupt of the - * main command */ + void (*interrupt)(void); + /* this is called after the interrupt of the + * main command */ void (*redo)(void); /* this is called to retry the operation */ void (*error)(void); /* this is called to tally an error */ done_f done; /* this is called to say if the operation has @@ -571,7 +567,6 @@ static void floppy_release_irq_and_dma(void); * reset doesn't need to be tested before sending commands, because * output_byte is automatically disabled when reset is set. */ -#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } } static void reset_fdc(void); /* @@ -579,9 +574,9 @@ static void reset_fdc(void); * information to interrupts. They are the data used for the current * request. */ -#define NO_TRACK -1 -#define NEED_1_RECAL -2 -#define NEED_2_RECAL -3 +#define NO_TRACK -1 +#define NEED_1_RECAL -2 +#define NEED_2_RECAL -3 static int usage_count; @@ -621,39 +616,35 @@ static inline void set_debugt(void) debugtimer = jiffies; } -static inline void debugt(const char *message) +static inline void debugt(const char *func, const char *msg) { if (DP->flags & DEBUGT) - printk("%s dtime=%lu\n", message, jiffies - debugtimer); + pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer); } #else static inline void set_debugt(void) { } -static inline void debugt(const char *message) { } +static inline void debugt(const char *func, const char *msg) { } #endif /* DEBUGT */ -typedef void (*timeout_fn) (unsigned long); +typedef void (*timeout_fn)(unsigned long); static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); static const char *timeout_message; -#ifdef FLOPPY_SANITY_CHECK -static void is_alive(const char *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 - && !timer_pending(&fd_timeout)) { - DPRINT("timeout handler died: %s\n", message); + if (test_bit(0, &fdc_busy) && command_status < 2 && + !timer_pending(&fd_timeout)) { + DPRINT("%s: timeout handler died. %s\n", func, message); } } -#endif -static void (*do_floppy) (void) = NULL; - -#ifdef FLOPPY_SANITY_CHECK +static void (*do_floppy)(void) = NULL; #define OLOGSIZE 20 -static void (*lasthandler) (void); +static void (*lasthandler)(void); static unsigned long interruptjiffies; static unsigned long resultjiffies; static int resultsize; @@ -666,12 +657,11 @@ static struct output_log { } output_log[OLOGSIZE]; static int output_log_pos; -#endif #define current_reqD -1 #define MAXTIMEOUT -2 -static void __reschedule_timeout(int drive, const char *message, int marg) +static void __reschedule_timeout(int drive, const char *message) { if (drive == current_reqD) drive = current_drive; @@ -682,25 +672,22 @@ static void __reschedule_timeout(int drive, const char *message, int marg) } else fd_timeout.expires = jiffies + UDP->timeout; add_timer(&fd_timeout); - if (UDP->flags & FD_DEBUG) { - DPRINT("reschedule timeout "); - printk(message, marg); - printk("\n"); - } + if (UDP->flags & FD_DEBUG) + DPRINT("reschedule timeout %s\n", message); timeout_message = message; } -static void reschedule_timeout(int drive, const char *message, int marg) +static void reschedule_timeout(int drive, const char *message) { unsigned long flags; spin_lock_irqsave(&floppy_lock, flags); - __reschedule_timeout(drive, message, marg); + __reschedule_timeout(drive, message); spin_unlock_irqrestore(&floppy_lock, flags); } -#define INFBOUND(a,b) (a)=max_t(int, a, b) -#define SUPBOUND(a,b) (a)=min_t(int, a, b) +#define INFBOUND(a, b) (a) = max_t(int, a, b) +#define SUPBOUND(a, b) (a) = min_t(int, a, b) /* * Bottom half floppy driver. @@ -739,7 +726,6 @@ static int disk_change(int drive) { int fdc = FDC(drive); -#ifdef FLOPPY_SANITY_CHECK if (time_before(jiffies, UDRS->select_date + UDP->select_delay)) DPRINT("WARNING disk change called early\n"); if (!(FDCS->dor & (0x10 << UNIT(drive))) || @@ -748,31 +734,27 @@ static int disk_change(int drive) DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive), (unsigned int)FDCS->dor); } -#endif -#ifdef DCL_DEBUG - if (UDP->flags & FD_DEBUG) { - DPRINT("checking disk change line for drive %d\n", drive); - DPRINT("jiffies=%lu\n", jiffies); - DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80); - DPRINT("flags=%lx\n", UDRS->flags); - } -#endif + debug_dcl(UDP->flags, + "checking disk change line for drive %d\n", drive); + debug_dcl(UDP->flags, "jiffies=%lu\n", jiffies); + debug_dcl(UDP->flags, "disk change line=%x\n", fd_inb(FD_DIR) & 0x80); + debug_dcl(UDP->flags, "flags=%lx\n", UDRS->flags); + if (UDP->flags & FD_BROKEN_DCL) - return UTESTF(FD_DISK_CHANGED); + return test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) { - USETF(FD_VERIFY); /* verify write protection */ - if (UDRS->maxblock) { - /* mark it changed */ - USETF(FD_DISK_CHANGED); - } + set_bit(FD_VERIFY_BIT, &UDRS->flags); + /* verify write protection */ + + if (UDRS->maxblock) /* mark it changed */ + set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); /* invalidate its geometry */ if (UDRS->keep_data >= 0) { if ((UDP->flags & FTD_MSG) && current_type[drive] != NULL) - DPRINT("Disk type is undefined after " - "disk change\n"); + DPRINT("Disk type is undefined after disk change\n"); current_type[drive] = NULL; floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; } @@ -780,7 +762,7 @@ static int disk_change(int drive) return 1; } else { UDRS->last_checked = jiffies; - UCLEARF(FD_DISK_NEWCHANGE); + clear_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags); } return 0; } @@ -790,6 +772,12 @@ static inline int is_selected(int dor, int unit) return ((dor & (0x10 << unit)) && (dor & 3) == unit); } +static bool is_ready_state(int status) +{ + int state = status & (STATUS_READY | STATUS_DIR | STATUS_DMA); + return state == STATUS_READY; +} + static int set_dor(int fdc, char mask, char data) { unsigned char unit; @@ -806,11 +794,8 @@ static int set_dor(int fdc, char mask, char data) unit = olddor & 0x3; if (is_selected(olddor, unit) && !is_selected(newdor, unit)) { drive = REVDRIVE(fdc, unit); -#ifdef DCL_DEBUG - if (UDP->flags & FD_DEBUG) { - DPRINT("calling disk change from set_dor\n"); - } -#endif + debug_dcl(UDP->flags, + "calling disk change from set_dor\n"); disk_change(drive); } FDCS->dor = newdor; @@ -834,8 +819,10 @@ static void twaddle(void) DRS->select_date = jiffies; } -/* reset all driver information about the current fdc. This is needed after - * a reset, and after a raw command. */ +/* + * Reset all driver information about the current fdc. + * This is needed after a reset, and after a raw command. + */ static void reset_fdc_info(int mode) { int drive; @@ -857,7 +844,7 @@ static void set_fdc(int drive) current_drive = drive; } if (fdc != 1 && fdc != 0) { - printk("bad fdc value\n"); + pr_info("bad fdc value\n"); return; } set_dor(fdc, ~0, 8); @@ -871,11 +858,10 @@ static void set_fdc(int drive) } /* locks the driver */ -static int _lock_fdc(int drive, int interruptible, int line) +static int _lock_fdc(int drive, bool interruptible, int line) { if (!usage_count) { - printk(KERN_ERR - "Trying to lock fdc while usage count=0 at line %d\n", + pr_err("Trying to lock fdc while usage count=0 at line %d\n", line); return -1; } @@ -904,15 +890,13 @@ static int _lock_fdc(int drive, int interruptible, int line) } command_status = FD_COMMAND_NONE; - __reschedule_timeout(drive, "lock fdc", 0); + __reschedule_timeout(drive, "lock fdc"); set_fdc(drive); return 0; } -#define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__) - -#define LOCK_FDC(drive,interruptible) \ -if (lock_fdc(drive,interruptible)) return -EINTR; +#define lock_fdc(drive, interruptible) \ + _lock_fdc(drive, interruptible, __LINE__) /* unlocks the driver */ static inline void unlock_fdc(void) @@ -924,7 +908,7 @@ static inline void unlock_fdc(void) DPRINT("FDC access conflict!\n"); if (do_floppy) - DPRINT("device interrupt still active at FDC release: %p!\n", + DPRINT("device interrupt still active at FDC release: %pf!\n", do_floppy); command_status = FD_COMMAND_NONE; spin_lock_irqsave(&floppy_lock, flags); @@ -1003,7 +987,7 @@ static void empty(void) static DECLARE_WORK(floppy_work, NULL); -static void schedule_bh(void (*handler) (void)) +static void schedule_bh(void (*handler)(void)) { PREPARE_WORK(&floppy_work, (work_func_t)handler); schedule_work(&floppy_work); @@ -1026,11 +1010,7 @@ static void cancel_activity(void) * transfer */ static void fd_watchdog(void) { -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("calling disk change from watchdog\n"); - } -#endif + debug_dcl(DP->flags, "calling disk change from watchdog\n"); if (disk_change(current_drive)) { DPRINT("disk removed during i/o\n"); @@ -1039,7 +1019,7 @@ static void fd_watchdog(void) reset_fdc(); } else { del_timer(&fd_timer); - fd_timer.function = (timeout_fn) fd_watchdog; + fd_timer.function = (timeout_fn)fd_watchdog; fd_timer.expires = jiffies + HZ / 10; add_timer(&fd_timer); } @@ -1105,25 +1085,23 @@ static void setup_DMA(void) { unsigned long f; -#ifdef FLOPPY_SANITY_CHECK if (raw_cmd->length == 0) { int i; - printk("zero dma transfer size:"); + pr_info("zero dma transfer size:"); for (i = 0; i < raw_cmd->cmd_count; i++) - printk("%x,", raw_cmd->cmd[i]); - printk("\n"); + pr_cont("%x,", raw_cmd->cmd[i]); + pr_cont("\n"); cont->done(0); FDCS->reset = 1; return; } if (((unsigned long)raw_cmd->kernel_data) % 512) { - printk("non aligned address: %p\n", raw_cmd->kernel_data); + pr_info("non aligned address: %p\n", raw_cmd->kernel_data); cont->done(0); FDCS->reset = 1; return; } -#endif f = claim_dma_lock(); fd_disable_dma(); #ifdef fd_dma_setup @@ -1165,7 +1143,7 @@ static int wait_til_ready(void) if (status & STATUS_READY) return status; } - if (!initialising) { + if (initialized) { DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc); show_floppy(); } @@ -1176,22 +1154,21 @@ static int wait_til_ready(void) /* sends a command byte to the fdc */ static int output_byte(char byte) { - int status; + int status = wait_til_ready(); - if ((status = wait_til_ready()) < 0) + if (status < 0) return -1; - if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) { + + if (is_ready_state(status)) { fd_outb(byte, FD_DATA); -#ifdef FLOPPY_SANITY_CHECK output_log[output_log_pos].data = byte; output_log[output_log_pos].status = status; output_log[output_log_pos].jiffies = jiffies; output_log_pos = (output_log_pos + 1) % OLOGSIZE; -#endif return 0; } FDCS->reset = 1; - if (!initialising) { + if (initialized) { DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n", byte, fdc, status); show_floppy(); @@ -1199,8 +1176,6 @@ static int output_byte(char byte) return -1; } -#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;} - /* gets the response from the fdc */ static int result(void) { @@ -1208,14 +1183,13 @@ static int result(void) int status = 0; for (i = 0; i < MAX_REPLIES; i++) { - if ((status = wait_til_ready()) < 0) + status = wait_til_ready(); + if (status < 0) break; status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA; if ((status & ~STATUS_BUSY) == STATUS_READY) { -#ifdef FLOPPY_SANITY_CHECK resultjiffies = jiffies; resultsize = i; -#endif return i; } if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY)) @@ -1223,10 +1197,9 @@ static int result(void) else break; } - if (!initialising) { - DPRINT - ("get result error. Fdc=%d Last status=%x Read bytes=%d\n", - fdc, status, i); + if (initialized) { + DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n", + fdc, status, i); show_floppy(); } FDCS->reset = 1; @@ -1237,12 +1210,14 @@ static int result(void) /* does the fdc need more output? */ static int need_more_output(void) { - int status; + int status = wait_til_ready(); - if ((status = wait_til_ready()) < 0) + if (status < 0) return -1; - if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) + + if (is_ready_state(status)) return MORE_OUTPUT; + return result(); } @@ -1264,9 +1239,12 @@ static inline void perpendicular_mode(void) default: DPRINT("Invalid data rate for perpendicular mode!\n"); cont->done(0); - FDCS->reset = 1; /* convenient way to return to - * redo without to much hassle (deep - * stack et al. */ + FDCS->reset = 1; + /* + * convenient way to return to + * redo without too much hassle + * (deep stack et al.) + */ return; } } else @@ -1366,9 +1344,9 @@ static void fdc_specify(void) /* Convert step rate from microseconds to milliseconds and 4 bits */ srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR); - if (slow_floppy) { + if (slow_floppy) srt = srt / 4; - } + SUPBOUND(srt, 0xf); INFBOUND(srt, 0); @@ -1415,16 +1393,46 @@ static int fdc_dtr(void) * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) */ FDCS->dtr = raw_cmd->rate & 3; - return (fd_wait_for_completion(jiffies + 2UL * HZ / 100, - (timeout_fn) floppy_ready)); + return fd_wait_for_completion(jiffies + 2UL * HZ / 100, + (timeout_fn)floppy_ready); } /* fdc_dtr */ static void tell_sector(void) { - printk(": track %d, head %d, sector %d, size %d", - R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); + pr_cont(": track %d, head %d, sector %d, size %d", + R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); } /* tell_sector */ +static void print_errors(void) +{ + DPRINT(""); + if (ST0 & ST0_ECE) { + pr_cont("Recalibrate failed!"); + } else if (ST2 & ST2_CRC) { + pr_cont("data CRC error"); + tell_sector(); + } else if (ST1 & ST1_CRC) { + pr_cont("CRC error"); + tell_sector(); + } else if ((ST1 & (ST1_MAM | ST1_ND)) || + (ST2 & ST2_MAM)) { + if (!probing) { + pr_cont("sector not found"); + tell_sector(); + } else + pr_cont("probe failed..."); + } else if (ST2 & ST2_WC) { /* seek error */ + pr_cont("wrong cylinder"); + } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ + pr_cont("bad cylinder"); + } else { + pr_cont("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", + ST0, ST1, ST2); + tell_sector(); + } + pr_cont("\n"); +} + /* * OK, this error interpreting routine is called after a * DMA read/write has succeeded @@ -1437,7 +1445,7 @@ static int interpret_errors(void) char bad; if (inr != 7) { - DPRINT("-- FDC reply error"); + DPRINT("-- FDC reply error\n"); FDCS->reset = 1; return 1; } @@ -1450,43 +1458,17 @@ static int interpret_errors(void) bad = 1; if (ST1 & ST1_WP) { DPRINT("Drive is write protected\n"); - CLEARF(FD_DISK_WRITABLE); + clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); cont->done(0); bad = 2; } else if (ST1 & ST1_ND) { - SETF(FD_NEED_TWADDLE); + set_bit(FD_NEED_TWADDLE_BIT, &DRS->flags); } else if (ST1 & ST1_OR) { if (DP->flags & FTD_MSG) DPRINT("Over/Underrun - retrying\n"); bad = 0; } else if (*errors >= DP->max_errors.reporting) { - DPRINT(""); - if (ST0 & ST0_ECE) { - printk("Recalibrate failed!"); - } else if (ST2 & ST2_CRC) { - printk("data CRC error"); - tell_sector(); - } else if (ST1 & ST1_CRC) { - printk("CRC error"); - tell_sector(); - } else if ((ST1 & (ST1_MAM | ST1_ND)) - || (ST2 & ST2_MAM)) { - if (!probing) { - printk("sector not found"); - tell_sector(); - } else - printk("probe failed..."); - } else if (ST2 & ST2_WC) { /* seek error */ - printk("wrong cylinder"); - } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ - printk("bad cylinder"); - } else { - printk - ("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", - ST0, ST1, ST2); - tell_sector(); - } - printk("\n"); + print_errors(); } if (ST2 & ST2_WC || ST2 & ST2_BC) /* wrong cylinder => recal */ @@ -1531,9 +1513,9 @@ static void setup_rw_floppy(void) */ if (time_after(ready_date, jiffies + DP->select_delay)) { ready_date -= DP->select_delay; - function = (timeout_fn) floppy_start; + function = (timeout_fn)floppy_start; } else - function = (timeout_fn) 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)) @@ -1551,7 +1533,7 @@ static void setup_rw_floppy(void) for (i = 0; i < raw_cmd->cmd_count; i++) r |= output_byte(raw_cmd->cmd[i]); - debugt("rw_command: "); + debugt(__func__, "rw_command"); if (r) { cont->error(); @@ -1574,7 +1556,7 @@ static int blind_seek; */ static void seek_interrupt(void) { - debugt("seek interrupt:"); + debugt(__func__, ""); if (inr != 2 || (ST0 & 0xF8) != 0x20) { DPRINT("seek failed\n"); DRS->track = NEED_2_RECAL; @@ -1583,14 +1565,11 @@ static void seek_interrupt(void) return; } if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) { -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT - ("clearing NEWCHANGE flag because of effective seek\n"); - DPRINT("jiffies=%lu\n", jiffies); - } -#endif - CLEARF(FD_DISK_NEWCHANGE); /* effective seek */ + debug_dcl(DP->flags, + "clearing NEWCHANGE flag because of effective seek\n"); + debug_dcl(DP->flags, "jiffies=%lu\n", jiffies); + clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); + /* effective seek */ DRS->select_date = jiffies; } DRS->track = ST1; @@ -1599,26 +1578,23 @@ static void seek_interrupt(void) static void check_wp(void) { - if (TESTF(FD_VERIFY)) { - /* check write protection */ + if (test_bit(FD_VERIFY_BIT, &DRS->flags)) { + /* check write protection */ output_byte(FD_GETSTATUS); output_byte(UNIT(current_drive)); if (result() != 1) { FDCS->reset = 1; return; } - CLEARF(FD_VERIFY); - CLEARF(FD_NEED_TWADDLE); -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("checking whether disk is write protected\n"); - DPRINT("wp=%x\n", ST3 & 0x40); - } -#endif + clear_bit(FD_VERIFY_BIT, &DRS->flags); + clear_bit(FD_NEED_TWADDLE_BIT, &DRS->flags); + debug_dcl(DP->flags, + "checking whether disk is write protected\n"); + debug_dcl(DP->flags, "wp=%x\n", ST3 & 0x40); if (!(ST3 & 0x40)) - SETF(FD_DISK_WRITABLE); + set_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); else - CLEARF(FD_DISK_WRITABLE); + clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); } } @@ -1628,19 +1604,15 @@ static void seek_floppy(void) blind_seek = 0; -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("calling disk change from seek\n"); - } -#endif + debug_dcl(DP->flags, "calling disk change from %s\n", __func__); - if (!TESTF(FD_DISK_NEWCHANGE) && + if (!test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) && disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { /* the media changed flag should be cleared after the seek. * If it isn't, this means that there is really no disk in * the drive. */ - SETF(FD_DISK_CHANGED); + set_bit(FD_DISK_CHANGED_BIT, &DRS->flags); cont->done(0); cont->redo(); return; @@ -1648,7 +1620,7 @@ static void seek_floppy(void) if (DRS->track <= NEED_1_RECAL) { recalibrate_floppy(); return; - } else if (TESTF(FD_DISK_NEWCHANGE) && + } else if (test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) && (raw_cmd->flags & FD_RAW_NEED_DISK) && (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) { /* we seek to clear the media-changed condition. Does anybody @@ -1677,19 +1649,22 @@ static void seek_floppy(void) do_floppy = seek_interrupt; output_byte(FD_SEEK); output_byte(UNIT(current_drive)); - LAST_OUT(track); - debugt("seek command:"); + if (output_byte(track) < 0) { + reset_fdc(); + return; + } + debugt(__func__, ""); } static void recal_interrupt(void) { - debugt("recal interrupt:"); + debugt(__func__, ""); if (inr != 2) FDCS->reset = 1; else if (ST0 & ST0_ECE) { switch (DRS->track) { case NEED_1_RECAL: - debugt("recal interrupt need 1 recal:"); + debugt(__func__, "need 1 recal"); /* after a second recalibrate, we still haven't * reached track 0. Probably no drive. Raise an * error, as failing immediately might upset @@ -1698,25 +1673,21 @@ static void recal_interrupt(void) cont->redo(); return; case NEED_2_RECAL: - debugt("recal interrupt need 2 recal:"); + debugt(__func__, "need 2 recal"); /* If we already did a recalibrate, * and we are not at track 0, this * means we have moved. (The only way * not to move at recalibration is to * be already at track 0.) Clear the * new change flag */ -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT - ("clearing NEWCHANGE flag because of second recalibrate\n"); - } -#endif + debug_dcl(DP->flags, + "clearing NEWCHANGE flag because of second recalibrate\n"); - CLEARF(FD_DISK_NEWCHANGE); + clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); DRS->select_date = jiffies; /* fall through */ default: - debugt("recal interrupt default:"); + debugt(__func__, "default"); /* Recalibrate moves the head by at * most 80 steps. If after one * recalibrate we don't have reached @@ -1738,8 +1709,8 @@ static void print_result(char *message, int inr) DPRINT("%s ", message); if (inr >= 0) for (i = 0; i < inr; i++) - printk("repl[%d]=%x ", i, reply_buffer[i]); - printk("\n"); + pr_cont("repl[%d]=%x ", i, reply_buffer[i]); + pr_cont("\n"); } /* interrupt handler. Note that this can be called externally on the Sparc */ @@ -1760,10 +1731,10 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) do_floppy = NULL; if (fdc >= N_FDC || FDCS->address == -1) { /* we don't even know which FDC is the culprit */ - printk("DOR0=%x\n", fdc_state[0].dor); - printk("floppy interrupt on bizarre fdc %d\n", fdc); - printk("handler=%p\n", handler); - is_alive("bizarre fdc"); + pr_info("DOR0=%x\n", fdc_state[0].dor); + pr_info("floppy interrupt on bizarre fdc %d\n", fdc); + pr_info("handler=%pf\n", handler); + is_alive(__func__, "bizarre fdc"); return IRQ_NONE; } @@ -1777,7 +1748,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) * activity. */ - do_print = !handler && print_unex && !initialising; + do_print = !handler && print_unex && initialized; inr = result(); if (do_print) @@ -1790,15 +1761,15 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) if (do_print) print_result("sensei", inr); max_sensei--; - } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2 - && max_sensei); + } while ((ST0 & 0x83) != UNIT(current_drive) && + inr == 2 && max_sensei); } if (!handler) { FDCS->reset = 1; return IRQ_NONE; } schedule_bh(handler); - is_alive("normal interrupt end"); + is_alive(__func__, "normal interrupt end"); /* FIXME! Was it really for us? */ return IRQ_HANDLED; @@ -1806,10 +1777,11 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) static void recalibrate_floppy(void) { - debugt("recalibrate floppy:"); + debugt(__func__, ""); do_floppy = recal_interrupt; output_byte(FD_RECALIBRATE); - LAST_OUT(UNIT(current_drive)); + if (output_byte(UNIT(current_drive)) < 0) + reset_fdc(); } /* @@ -1817,10 +1789,10 @@ static void recalibrate_floppy(void) */ static void reset_interrupt(void) { - debugt("reset interrupt:"); + debugt(__func__, ""); result(); /* get the status ready for set_fdc */ if (FDCS->reset) { - printk("reset set in interrupt, calling %p\n", cont->error); + pr_info("reset set in interrupt, calling %pf\n", cont->error); cont->error(); /* a reset just after a reset. BAD! */ } cont->redo(); @@ -1858,53 +1830,49 @@ static void show_floppy(void) { int i; - printk("\n"); - printk("floppy driver state\n"); - printk("-------------------\n"); - printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n", - jiffies, interruptjiffies, jiffies - interruptjiffies, - lasthandler); + pr_info("\n"); + pr_info("floppy driver state\n"); + pr_info("-------------------\n"); + pr_info("now=%lu last interrupt=%lu diff=%lu last called handler=%pf\n", + jiffies, interruptjiffies, jiffies - interruptjiffies, + lasthandler); -#ifdef FLOPPY_SANITY_CHECK - printk("timeout_message=%s\n", timeout_message); - printk("last output bytes:\n"); + pr_info("timeout_message=%s\n", timeout_message); + pr_info("last output bytes:\n"); for (i = 0; i < OLOGSIZE; i++) - printk("%2x %2x %lu\n", - output_log[(i + output_log_pos) % OLOGSIZE].data, - output_log[(i + output_log_pos) % OLOGSIZE].status, - output_log[(i + output_log_pos) % OLOGSIZE].jiffies); - printk("last result at %lu\n", resultjiffies); - printk("last redo_fd_request at %lu\n", lastredo); - for (i = 0; i < resultsize; i++) { - printk("%2x ", reply_buffer[i]); - } - printk("\n"); -#endif - - printk("status=%x\n", fd_inb(FD_STATUS)); - printk("fdc_busy=%lu\n", fdc_busy); + pr_info("%2x %2x %lu\n", + output_log[(i + output_log_pos) % OLOGSIZE].data, + output_log[(i + output_log_pos) % OLOGSIZE].status, + output_log[(i + output_log_pos) % OLOGSIZE].jiffies); + pr_info("last result at %lu\n", resultjiffies); + pr_info("last redo_fd_request at %lu\n", lastredo); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, + reply_buffer, resultsize, true); + + pr_info("status=%x\n", fd_inb(FD_STATUS)); + pr_info("fdc_busy=%lu\n", fdc_busy); if (do_floppy) - printk("do_floppy=%p\n", do_floppy); + pr_info("do_floppy=%pf\n", do_floppy); if (work_pending(&floppy_work)) - printk("floppy_work.func=%p\n", floppy_work.func); + pr_info("floppy_work.func=%pf\n", floppy_work.func); if (timer_pending(&fd_timer)) - printk("fd_timer.function=%p\n", fd_timer.function); + pr_info("fd_timer.function=%pf\n", fd_timer.function); if (timer_pending(&fd_timeout)) { - printk("timer_function=%p\n", fd_timeout.function); - printk("expires=%lu\n", fd_timeout.expires - jiffies); - printk("now=%lu\n", jiffies); - } - printk("cont=%p\n", cont); - printk("current_req=%p\n", current_req); - printk("command_status=%d\n", command_status); - printk("\n"); + 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(unsigned long data) { unsigned long flags; - if (!initialising) + if (initialized) show_floppy(); cancel_activity(); @@ -1916,17 +1884,17 @@ static void floppy_shutdown(unsigned long data) /* avoid dma going to a random drive after shutdown */ - if (!initialising) + if (initialized) DPRINT("floppy timeout called\n"); FDCS->reset = 1; if (cont) { cont->done(0); cont->redo(); /* this will recall reset when needed */ } else { - printk("no cont in shutdown!\n"); + pr_info("no cont in shutdown!\n"); process_fd_request(); } - is_alive("floppy shutdown"); + is_alive(__func__, ""); } /* start motor, check media-changed condition and write protection */ @@ -1954,27 +1922,26 @@ static int start_motor(void (*function)(void)) set_dor(fdc, mask, data); /* wait_for_completion also schedules reset if needed. */ - return (fd_wait_for_completion(DRS->select_date + DP->select_delay, - (timeout_fn) function)); + return fd_wait_for_completion(DRS->select_date + DP->select_delay, + (timeout_fn)function); } static void floppy_ready(void) { - CHECK_RESET; + if (FDCS->reset) { + reset_fdc(); + return; + } if (start_motor(floppy_ready)) return; if (fdc_dtr()) return; -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("calling disk change from floppy_ready\n"); - } -#endif + debug_dcl(DP->flags, "calling disk change from floppy_ready\n"); if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && disk_change(current_drive) && !DP->select_delay) - twaddle(); /* this clears the dcl on certain drive/controller - * combinations */ + twaddle(); /* this clears the dcl on certain + * drive/controller combinations */ #ifdef fd_chose_dma_mode if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) { @@ -1998,15 +1965,11 @@ static void floppy_ready(void) static void floppy_start(void) { - reschedule_timeout(current_reqD, "floppy start", 0); + reschedule_timeout(current_reqD, "floppy start"); scandrives(); -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("setting NEWCHANGE in floppy_start\n"); - } -#endif - SETF(FD_DISK_NEWCHANGE); + debug_dcl(DP->flags, "setting NEWCHANGE in floppy_start\n"); + set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); floppy_ready(); } @@ -2026,7 +1989,7 @@ static void floppy_start(void) static void do_wakeup(void) { - reschedule_timeout(MAXTIMEOUT, "do wakeup", 0); + reschedule_timeout(MAXTIMEOUT, "do wakeup"); cont = NULL; command_status += 2; wake_up(&command_done); @@ -2046,7 +2009,7 @@ static struct cont_t intr_cont = { .done = (done_f)empty }; -static int wait_til_done(void (*handler)(void), int interruptible) +static int wait_til_done(void (*handler)(void), bool interruptible) { int ret; @@ -2064,7 +2027,7 @@ static int wait_til_done(void (*handler)(void), int interruptible) if (command_status >= 2 || !NO_SIGNAL) break; - is_alive("wait_til_done"); + is_alive(__func__, ""); schedule(); } @@ -2180,9 +2143,9 @@ static void format_interrupt(void) cont->redo(); } -#define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2) -#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1)) +#define FM_MODE(x, y) ((y) & ~(((x)->rate & 0x80) >> 1)) #define CT(x) ((x) | 0xc0) + static void setup_format_params(int track) { int n; @@ -2197,8 +2160,8 @@ static void setup_format_params(int track) raw_cmd = &default_raw_cmd; raw_cmd->track = track; - raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | - FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; + raw_cmd->flags = (FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | + FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK); raw_cmd->rate = _floppy->rate & 0x43; raw_cmd->cmd_count = NR_F; COMMAND = FM_MODE(_floppy, FD_FORMAT); @@ -2257,7 +2220,7 @@ static void redo_format(void) buffer_track = -1; setup_format_params(format_req.track << STRETCH(_floppy)); floppy_start(); - debugt("queue format request"); + debugt(__func__, "queue format request"); } static struct cont_t format_cont = { @@ -2271,7 +2234,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req) { int ret; - LOCK_FDC(drive, 1); + if (lock_fdc(drive, true)) + return -EINTR; + set_floppy(drive); if (!_floppy || _floppy->track > DP->tracks || @@ -2286,7 +2251,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req) format_errors = 0; cont = &format_cont; errors = &format_errors; - IWAIT(redo_format); + ret = wait_til_done(redo_format, true); + if (ret == -EINTR) + return -EINTR; process_fd_request(); return ret; } @@ -2320,12 +2287,14 @@ static void request_done(int uptodate) struct request *req = current_req; unsigned long flags; int block; + char msg[sizeof("request done ") + sizeof(int) * 3]; probing = 0; - reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate); + snprintf(msg, sizeof(msg), "request done %d", uptodate); + reschedule_timeout(MAXTIMEOUT, msg); if (!req) { - printk("floppy.c: no request in request_done\n"); + pr_info("floppy.c: no request in request_done\n"); return; } @@ -2377,7 +2346,7 @@ static void rw_interrupt(void) DRS->first_read_date = jiffies; nr_sectors = 0; - CODE2SIZE; + ssize = DIV_ROUND_UP(1 << SIZECODE, 4); if (ST1 & ST1_EOC) eoc = 1; @@ -2393,20 +2362,18 @@ static void rw_interrupt(void) R_HEAD - HEAD) * SECT_PER_TRACK + R_SECTOR - SECTOR + eoc) << SIZECODE >> 2; -#ifdef FLOPPY_SANITY_CHECK if (nr_sectors / 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); - printk("rh=%d h=%d\n", R_HEAD, HEAD); - printk("rt=%d t=%d\n", R_TRACK, TRACK); - printk("heads=%d eoc=%d\n", heads, eoc); - printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK, - fsector_t, ssize); - printk("in_sector_offset=%d\n", in_sector_offset); + pr_info("rs=%d s=%d\n", R_SECTOR, SECTOR); + pr_info("rh=%d h=%d\n", R_HEAD, HEAD); + pr_info("rt=%d t=%d\n", R_TRACK, TRACK); + pr_info("heads=%d eoc=%d\n", heads, eoc); + pr_info("spt=%d st=%d ss=%d\n", + SECT_PER_TRACK, fsector_t, ssize); + pr_info("in_sector_offset=%d\n", in_sector_offset); } -#endif nr_sectors -= in_sector_offset; INFBOUND(nr_sectors, 0); @@ -2511,19 +2478,17 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) blk_rq_sectors(current_req)); remaining = current_count_sectors << 9; -#ifdef FLOPPY_SANITY_CHECK if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) { DPRINT("in copy buffer\n"); - printk("current_count_sectors=%ld\n", current_count_sectors); - printk("remaining=%d\n", remaining >> 9); - printk("current_req->nr_sectors=%u\n", - blk_rq_sectors(current_req)); - printk("current_req->current_nr_sectors=%u\n", - blk_rq_cur_sectors(current_req)); - printk("max_sector=%d\n", max_sector); - printk("ssize=%d\n", ssize); + pr_info("current_count_sectors=%ld\n", current_count_sectors); + pr_info("remaining=%d\n", remaining >> 9); + pr_info("current_req->nr_sectors=%u\n", + blk_rq_sectors(current_req)); + pr_info("current_req->current_nr_sectors=%u\n", + blk_rq_cur_sectors(current_req)); + pr_info("max_sector=%d\n", max_sector); + pr_info("ssize=%d\n", ssize); } -#endif buffer_max = max(max_sector, buffer_max); @@ -2539,26 +2504,24 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) SUPBOUND(size, remaining); buffer = page_address(bv->bv_page) + bv->bv_offset; -#ifdef FLOPPY_SANITY_CHECK if (dma_buffer + size > floppy_track_buffer + (max_buffer_sectors << 10) || dma_buffer < floppy_track_buffer) { DPRINT("buffer overrun in copy buffer %d\n", - (int)((floppy_track_buffer - - dma_buffer) >> 9)); - printk("fsector_t=%d buffer_min=%d\n", - fsector_t, buffer_min); - printk("current_count_sectors=%ld\n", - current_count_sectors); + (int)((floppy_track_buffer - dma_buffer) >> 9)); + pr_info("fsector_t=%d buffer_min=%d\n", + fsector_t, buffer_min); + pr_info("current_count_sectors=%ld\n", + current_count_sectors); if (CT(COMMAND) == FD_READ) - printk("read\n"); + pr_info("read\n"); if (CT(COMMAND) == FD_WRITE) - printk("write\n"); + pr_info("write\n"); break; } if (((unsigned long)buffer) % 512) DPRINT("%p buffer not aligned\n", buffer); -#endif + if (CT(COMMAND) == FD_READ) memcpy(buffer, dma_buffer, size); else @@ -2567,13 +2530,11 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) remaining -= size; dma_buffer += size; } -#ifdef FLOPPY_SANITY_CHECK if (remaining) { if (remaining > 0) max_sector -= remaining >> 9; DPRINT("weirdness: remaining %d\n", remaining >> 9); } -#endif } /* work around a bug in pseudo DMA @@ -2593,15 +2554,14 @@ static void virtualdmabug_workaround(void) hard_sectors = raw_cmd->length >> (7 + SIZECODE); end_sector = SECTOR + hard_sectors - 1; -#ifdef FLOPPY_SANITY_CHECK if (end_sector > SECT_PER_TRACK) { - printk("too many sectors %d > %d\n", - end_sector, SECT_PER_TRACK); + pr_info("too many sectors %d > %d\n", + end_sector, SECT_PER_TRACK); return; } -#endif - SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points - * to end of transfer */ + SECT_PER_TRACK = end_sector; + /* make sure SECT_PER_TRACK + * points to end of transfer */ } } @@ -2624,7 +2584,7 @@ static int make_raw_rw_request(void) int ssize; if (max_buffer_sectors == 0) { - printk("VFS: Block I/O scheduled on unopened device\n"); + pr_info("VFS: Block I/O scheduled on unopened device\n"); return 0; } @@ -2641,7 +2601,7 @@ static int make_raw_rw_request(void) raw_cmd->flags |= FD_RAW_WRITE; COMMAND = FM_MODE(_floppy, FD_WRITE); } else { - DPRINT("make_raw_rw_request: unknown command\n"); + DPRINT("%s: unknown command\n", __func__); return 0; } @@ -2659,7 +2619,8 @@ static int make_raw_rw_request(void) HEAD = fsector_t / _floppy->sect; if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || - TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect) + test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) && + fsector_t < _floppy->sect) max_sector = _floppy->sect; /* 2M disks have phantom sectors on the first track */ @@ -2685,7 +2646,7 @@ static int make_raw_rw_request(void) raw_cmd->track = TRACK << STRETCH(_floppy); DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD); GAP = _floppy->gap; - CODE2SIZE; + ssize = DIV_ROUND_UP(1 << SIZECODE, 4); SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + FD_SECTBASE(_floppy); @@ -2730,8 +2691,10 @@ static int make_raw_rw_request(void) } } else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) { if (CT(COMMAND) == FD_WRITE) { - if (fsector_t + blk_rq_sectors(current_req) > ssize && - fsector_t + blk_rq_sectors(current_req) < ssize + ssize) + unsigned int sectors; + + sectors = fsector_t + blk_rq_sectors(current_req); + if (sectors > ssize && sectors < ssize + ssize) max_size = ssize + ssize; else max_size = ssize; @@ -2752,12 +2715,10 @@ static int make_raw_rw_request(void) * on a 64 bit machine! */ max_size = buffer_chain_size(); - dma_limit = - (MAX_DMA_ADDRESS - - ((unsigned long)current_req->buffer)) >> 9; - if ((unsigned long)max_size > dma_limit) { + dma_limit = (MAX_DMA_ADDRESS - + ((unsigned long)current_req->buffer)) >> 9; + if ((unsigned long)max_size > dma_limit) max_size = dma_limit; - } /* 64 kb boundaries */ if (CROSS_64KB(current_req->buffer, max_size << 9)) max_size = (K_64 - @@ -2773,16 +2734,16 @@ static int make_raw_rw_request(void) */ if (!direct || (indirect * 2 > direct * 3 && - *errors < DP->max_errors.read_track && ((!probing - || (DP->read_track & (1 << DRS->probed_format)))))) { + *errors < DP->max_errors.read_track && + ((!probing || + (DP->read_track & (1 << DRS->probed_format)))))) { max_size = blk_rq_sectors(current_req); } else { raw_cmd->kernel_data = current_req->buffer; raw_cmd->length = current_count_sectors << 9; if (raw_cmd->length == 0) { - DPRINT - ("zero dma transfer attempted from make_raw_request\n"); - DPRINT("indirect=%d direct=%d fsector_t=%d", + DPRINT("%s: zero dma transfer attempted\n", __func__); + DPRINT("indirect=%d direct=%d fsector_t=%d\n", indirect, direct, fsector_t); return 0; } @@ -2802,25 +2763,22 @@ static int make_raw_rw_request(void) ((CT(COMMAND) == FD_READ || (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) && max_sector > 2 * max_buffer_sectors + buffer_min && - max_size + fsector_t > 2 * max_buffer_sectors + buffer_min) - /* not enough space */ - ) { + max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)) { + /* not enough space */ buffer_track = -1; buffer_drive = current_drive; buffer_max = buffer_min = aligned_sector_t; } raw_cmd->kernel_data = floppy_track_buffer + - ((aligned_sector_t - buffer_min) << 9); + ((aligned_sector_t - buffer_min) << 9); if (CT(COMMAND) == FD_WRITE) { /* copy write buffer to track buffer. * if we get here, we know that the write * is either aligned or the data already in the buffer * (buffer will be overwritten) */ -#ifdef FLOPPY_SANITY_CHECK if (in_sector_offset && buffer_track == -1) DPRINT("internal error offset !=0 on write\n"); -#endif buffer_track = raw_cmd->track; buffer_drive = current_drive; copy_buffer(ssize, max_sector, @@ -2834,7 +2792,6 @@ static int make_raw_rw_request(void) raw_cmd->length = in_sector_offset + current_count_sectors; raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; raw_cmd->length <<= 9; -#ifdef FLOPPY_SANITY_CHECK if ((raw_cmd->length < current_count_sectors << 9) || (raw_cmd->kernel_data != current_req->buffer && CT(COMMAND) == FD_WRITE && @@ -2845,19 +2802,19 @@ static int make_raw_rw_request(void) DPRINT("fractionary current count b=%lx s=%lx\n", raw_cmd->length, current_count_sectors); if (raw_cmd->kernel_data != current_req->buffer) - printk("addr=%d, length=%ld\n", - (int)((raw_cmd->kernel_data - - floppy_track_buffer) >> 9), - current_count_sectors); - printk("st=%d ast=%d mse=%d msi=%d\n", - fsector_t, aligned_sector_t, max_sector, max_size); - printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); - printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", - COMMAND, SECTOR, HEAD, TRACK); - printk("buffer drive=%d\n", buffer_drive); - printk("buffer track=%d\n", buffer_track); - printk("buffer_min=%d\n", buffer_min); - printk("buffer_max=%d\n", buffer_max); + pr_info("addr=%d, length=%ld\n", + (int)((raw_cmd->kernel_data - + floppy_track_buffer) >> 9), + current_count_sectors); + pr_info("st=%d ast=%d mse=%d msi=%d\n", + fsector_t, aligned_sector_t, max_sector, max_size); + pr_info("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); + pr_info("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", + COMMAND, SECTOR, HEAD, TRACK); + pr_info("buffer drive=%d\n", buffer_drive); + pr_info("buffer track=%d\n", buffer_track); + pr_info("buffer_min=%d\n", buffer_min); + pr_info("buffer_max=%d\n", buffer_max); return 0; } @@ -2868,14 +2825,14 @@ static int make_raw_rw_request(void) raw_cmd->kernel_data + raw_cmd->length > floppy_track_buffer + (max_buffer_sectors << 10)) { DPRINT("buffer overrun in schedule dma\n"); - printk("fsector_t=%d buffer_min=%d current_count=%ld\n", - fsector_t, buffer_min, raw_cmd->length >> 9); - printk("current_count_sectors=%ld\n", - current_count_sectors); + pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n", + fsector_t, buffer_min, raw_cmd->length >> 9); + pr_info("current_count_sectors=%ld\n", + current_count_sectors); if (CT(COMMAND) == FD_READ) - printk("read\n"); + pr_info("read\n"); if (CT(COMMAND) == FD_WRITE) - printk("write\n"); + pr_info("write\n"); return 0; } } else if (raw_cmd->length > blk_rq_bytes(current_req) || @@ -2884,14 +2841,13 @@ static int make_raw_rw_request(void) return 0; } else if (raw_cmd->length < current_count_sectors << 9) { DPRINT("more sectors than bytes\n"); - printk("bytes=%ld\n", raw_cmd->length >> 9); - printk("sectors=%ld\n", current_count_sectors); + pr_info("bytes=%ld\n", raw_cmd->length >> 9); + pr_info("sectors=%ld\n", current_count_sectors); } if (raw_cmd->length == 0) { DPRINT("zero dma transfer attempted from make_raw_request\n"); return 0; } -#endif virtualdmabug_workaround(); return 2; @@ -2899,7 +2855,6 @@ static int make_raw_rw_request(void) static void redo_fd_request(void) { -#define REPEAT {request_done(0); continue; } int drive; int tmp; @@ -2907,63 +2862,63 @@ static void redo_fd_request(void) if (current_drive < N_DRIVE) floppy_off(current_drive); - for (;;) { - if (!current_req) { - struct request *req; - - spin_lock_irq(floppy_queue->queue_lock); - req = blk_fetch_request(floppy_queue); - spin_unlock_irq(floppy_queue->queue_lock); - if (!req) { - do_floppy = NULL; - unlock_fdc(); - return; - } - current_req = req; - } - drive = (long)current_req->rq_disk->private_data; - set_fdc(drive); - reschedule_timeout(current_reqD, "redo fd request", 0); +do_request: + if (!current_req) { + struct request *req; - set_floppy(drive); - raw_cmd = &default_raw_cmd; - raw_cmd->flags = 0; - if (start_motor(redo_fd_request)) + spin_lock_irq(floppy_queue->queue_lock); + req = blk_fetch_request(floppy_queue); + spin_unlock_irq(floppy_queue->queue_lock); + if (!req) { + do_floppy = NULL; + unlock_fdc(); return; - disk_change(current_drive); - if (test_bit(current_drive, &fake_change) || - TESTF(FD_DISK_CHANGED)) { - DPRINT("disk absent or changed during operation\n"); - REPEAT; - } - if (!_floppy) { /* Autodetection */ - if (!probing) { - DRS->probed_format = 0; - if (next_valid_format()) { - DPRINT("no autodetectable formats\n"); - _floppy = NULL; - REPEAT; - } - } - probing = 1; - _floppy = - floppy_type + DP->autodetect[DRS->probed_format]; - } else - probing = 0; - errors = &(current_req->errors); - tmp = make_raw_rw_request(); - if (tmp < 2) { - request_done(tmp); - continue; } + current_req = req; + } + drive = (long)current_req->rq_disk->private_data; + set_fdc(drive); + reschedule_timeout(current_reqD, "redo fd request"); - if (TESTF(FD_NEED_TWADDLE)) - twaddle(); - schedule_bh(floppy_start); - debugt("queue fd request"); + set_floppy(drive); + raw_cmd = &default_raw_cmd; + raw_cmd->flags = 0; + if (start_motor(redo_fd_request)) return; + + disk_change(current_drive); + if (test_bit(current_drive, &fake_change) || + test_bit(FD_DISK_CHANGED_BIT, &DRS->flags)) { + DPRINT("disk absent or changed during operation\n"); + request_done(0); + goto do_request; + } + if (!_floppy) { /* Autodetection */ + if (!probing) { + DRS->probed_format = 0; + if (next_valid_format()) { + DPRINT("no autodetectable formats\n"); + _floppy = NULL; + request_done(0); + goto do_request; + } + } + probing = 1; + _floppy = floppy_type + DP->autodetect[DRS->probed_format]; + } else + probing = 0; + errors = &(current_req->errors); + tmp = make_raw_rw_request(); + if (tmp < 2) { + request_done(tmp); + goto do_request; } -#undef REPEAT + + if (test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) + twaddle(); + schedule_bh(floppy_start); + debugt(__func__, "queue fd request"); + return; } static struct cont_t rw_cont = { @@ -2979,30 +2934,30 @@ static void process_fd_request(void) schedule_bh(redo_fd_request); } -static void do_fd_request(struct request_queue * q) +static void do_fd_request(struct request_queue *q) { if (max_buffer_sectors == 0) { - printk("VFS: do_fd_request called on non-open device\n"); + pr_info("VFS: %s called on non-open device\n", __func__); return; } if (usage_count == 0) { - printk("warning: usage count=0, current_req=%p exiting\n", - current_req); - printk("sect=%ld type=%x flags=%x\n", - (long)blk_rq_pos(current_req), current_req->cmd_type, - current_req->cmd_flags); + pr_info("warning: usage count=0, current_req=%p exiting\n", + current_req); + pr_info("sect=%ld type=%x flags=%x\n", + (long)blk_rq_pos(current_req), current_req->cmd_type, + current_req->cmd_flags); return; } if (test_bit(0, &fdc_busy)) { /* fdc busy, this new request will be treated when the current one is done */ - is_alive("do fd request, old request running"); + is_alive(__func__, "old request running"); return; } - lock_fdc(MAXTIMEOUT, 0); + lock_fdc(MAXTIMEOUT, false); process_fd_request(); - is_alive("do fd request"); + is_alive(__func__, ""); } static struct cont_t poll_cont = { @@ -3012,24 +2967,18 @@ static struct cont_t poll_cont = { .done = generic_done }; -static int poll_drive(int interruptible, int flag) +static int poll_drive(bool interruptible, int flag) { - int ret; - /* no auto-sense, just clear dcl */ raw_cmd = &default_raw_cmd; raw_cmd->flags = flag; raw_cmd->track = 0; raw_cmd->cmd_count = 0; cont = &poll_cont; -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("setting NEWCHANGE in poll_drive\n"); - } -#endif - SETF(FD_DISK_NEWCHANGE); - WAIT(floppy_ready); - return ret; + debug_dcl(DP->flags, "setting NEWCHANGE in poll_drive\n"); + set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); + + return wait_til_done(floppy_ready, interruptible); } /* @@ -3039,7 +2988,7 @@ static int poll_drive(int interruptible, int flag) static void reset_intr(void) { - printk("weird, reset interrupt called\n"); + pr_info("weird, reset interrupt called\n"); } static struct cont_t reset_cont = { @@ -3049,20 +2998,23 @@ static struct cont_t reset_cont = { .done = generic_done }; -static int user_reset_fdc(int drive, int arg, int interruptible) +static int user_reset_fdc(int drive, int arg, bool interruptible) { int ret; - ret = 0; - LOCK_FDC(drive, interruptible); + if (lock_fdc(drive, interruptible)) + return -EINTR; + if (arg == FD_RESET_ALWAYS) FDCS->reset = 1; if (FDCS->reset) { cont = &reset_cont; - WAIT(reset_fdc); + ret = wait_til_done(reset_fdc, interruptible); + if (ret == -EINTR) + return -EINTR; } process_fd_request(); - return ret; + return 0; } /* @@ -3075,17 +3027,12 @@ static inline int fd_copyout(void __user *param, const void *address, return copy_to_user(param, address, size) ? -EFAULT : 0; } -static inline int fd_copyin(void __user *param, void *address, unsigned long size) +static inline int fd_copyin(void __user *param, void *address, + unsigned long size) { return copy_from_user(address, param, size) ? -EFAULT : 0; } -#define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) ? -EFAULT : 0) -#define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) ? -EFAULT : 0) - -#define COPYOUT(x) ECALL(_COPYOUT(x)) -#define COPYIN(x) ECALL(_COPYIN(x)) - static inline const char *drive_name(int type, int drive) { struct floppy_struct *floppy; @@ -3156,23 +3103,29 @@ static struct cont_t raw_cmd_cont = { .done = raw_cmd_done }; -static inline int raw_cmd_copyout(int cmd, char __user *param, +static inline int raw_cmd_copyout(int cmd, void __user *param, struct floppy_raw_cmd *ptr) { int ret; while (ptr) { - COPYOUT(*ptr); + ret = copy_to_user(param, ptr, sizeof(*ptr)); + if (ret) + return -EFAULT; param += sizeof(struct floppy_raw_cmd); if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) { - if (ptr->length >= 0 - && ptr->length <= ptr->buffer_length) - ECALL(fd_copyout - (ptr->data, ptr->kernel_data, - ptr->buffer_length - ptr->length)); + if (ptr->length >= 0 && + ptr->length <= ptr->buffer_length) { + long length = ptr->buffer_length - ptr->length; + ret = fd_copyout(ptr->data, ptr->kernel_data, + length); + if (ret) + return ret; + } } ptr = ptr->next; } + return 0; } @@ -3195,7 +3148,7 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr) } } -static inline int raw_cmd_copyin(int cmd, char __user *param, +static inline int raw_cmd_copyin(int cmd, void __user *param, struct floppy_raw_cmd **rcmd) { struct floppy_raw_cmd *ptr; @@ -3203,17 +3156,19 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, int i; *rcmd = NULL; - while (1) { - ptr = (struct floppy_raw_cmd *) - kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); - if (!ptr) - return -ENOMEM; - *rcmd = ptr; - COPYIN(*ptr); - ptr->next = NULL; - ptr->buffer_length = 0; - param += sizeof(struct floppy_raw_cmd); - if (ptr->cmd_count > 33) + +loop: + ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); + if (!ptr) + return -ENOMEM; + *rcmd = ptr; + ret = copy_from_user(ptr, param, sizeof(*ptr)); + if (ret) + return -EFAULT; + ptr->next = NULL; + ptr->buffer_length = 0; + param += sizeof(struct floppy_raw_cmd); + if (ptr->cmd_count > 33) /* the command may now also take up the space * initially intended for the reply & the * reply count. Needed for long 82078 commands @@ -3222,31 +3177,35 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, * 16 bytes for a structure, you'll one day * discover that you really need 17... */ + return -EINVAL; + + for (i = 0; i < 16; i++) + ptr->reply[i] = 0; + ptr->resultcode = 0; + ptr->kernel_data = NULL; + + if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { + if (ptr->length <= 0) return -EINVAL; + ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); + fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); + if (!ptr->kernel_data) + return -ENOMEM; + ptr->buffer_length = ptr->length; + } + if (ptr->flags & FD_RAW_WRITE) { + ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length); + if (ret) + return ret; + } - for (i = 0; i < 16; i++) - ptr->reply[i] = 0; - ptr->resultcode = 0; - ptr->kernel_data = NULL; - - if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { - if (ptr->length <= 0) - return -EINVAL; - ptr->kernel_data = - (char *)fd_dma_mem_alloc(ptr->length); - fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); - if (!ptr->kernel_data) - return -ENOMEM; - ptr->buffer_length = ptr->length; - } - if (ptr->flags & FD_RAW_WRITE) - ECALL(fd_copyin(ptr->data, ptr->kernel_data, - ptr->length)); + if (ptr->flags & FD_RAW_MORE) { rcmd = &(ptr->next); - if (!(ptr->flags & FD_RAW_MORE)) - return 0; ptr->rate &= 0x43; + goto loop; } + + return 0; } static int raw_cmd_ioctl(int cmd, void __user *param) @@ -3283,12 +3242,8 @@ static int raw_cmd_ioctl(int cmd, void __user *param) raw_cmd = my_raw_cmd; cont = &raw_cmd_cont; - ret = wait_til_done(floppy_start, 1); -#ifdef DCL_DEBUG - if (DP->flags & FD_DEBUG) { - DPRINT("calling disk change from raw_cmd ioctl\n"); - } -#endif + ret = wait_til_done(floppy_start, true); + debug_dcl(DP->flags, "calling disk change from raw_cmd ioctl\n"); if (ret != -EINTR && FDCS->reset) ret = -EIO; @@ -3327,7 +3282,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, if (!capable(CAP_SYS_ADMIN)) return -EPERM; mutex_lock(&open_lock); - if (lock_fdc(drive, 1)) { + if (lock_fdc(drive, true)) { mutex_unlock(&open_lock); return -EINTR; } @@ -3346,11 +3301,15 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, mutex_unlock(&open_lock); } else { int oldStretch; - LOCK_FDC(drive, 1); - if (cmd != FDDEFPRM) + + if (lock_fdc(drive, true)) + return -EINTR; + if (cmd != FDDEFPRM) { /* notice a disk change immediately, else * we lose our settings immediately*/ - CALL(poll_drive(1, FD_RAW_NEED_DISK)); + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) + return -EINTR; + } oldStretch = g->stretch; user_params[drive] = *g; if (buffer_drive == drive) @@ -3415,7 +3374,7 @@ static inline int normalize_ioctl(int *cmd, int *size) *size = _IOC_SIZE(*cmd); *cmd = ioctl_table[i]; if (*size > _IOC_SIZE(*cmd)) { - printk("ioctl not yet supported\n"); + pr_info("ioctl not yet supported\n"); return -EFAULT; } return 0; @@ -3429,8 +3388,10 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) if (type) *g = &floppy_type[type]; else { - LOCK_FDC(drive, 0); - CALL(poll_drive(0, 0)); + if (lock_fdc(drive, false)) + return -EINTR; + if (poll_drive(false, 0) == -EINTR) + return -EINTR; process_fd_request(); *g = current_type[drive]; } @@ -3459,10 +3420,6 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { -#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)bdev->bd_disk->private_data; int type = ITYPE(UDRS->fd_device); int i; @@ -3474,26 +3431,28 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, struct floppy_max_errors max_errors; struct floppy_drive_params dp; } inparam; /* parameters coming from user space */ - const char *outparam; /* parameters passed back to user space */ + const void *outparam; /* parameters passed back to user space */ /* convert compatibility eject ioctls into floppy eject ioctl. * We do this in order to provide a means to eject floppy disks before * installing the new fdutils package */ if (cmd == CDROMEJECT || /* CD-ROM eject */ - cmd == 0x6470 /* SunOS floppy eject */ ) { + cmd == 0x6470) { /* SunOS floppy eject */ DPRINT("obsolete eject ioctl\n"); DPRINT("please use floppycontrol --eject\n"); cmd = FDEJECT; } - /* convert the old style command into a new style command */ - if ((cmd & 0xff00) == 0x0200) { - ECALL(normalize_ioctl(&cmd, &size)); - } else + if (!((cmd & 0xff00) == 0x0200)) return -EINVAL; + /* convert the old style command into a new style command */ + ret = normalize_ioctl(&cmd, &size); + if (ret) + return ret; + /* permission checks */ - if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) || + if (((cmd & 0x40) && !(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL))) || ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -3501,129 +3460,142 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, return -EINVAL; /* copyin */ - CLEARSTRUCT(&inparam); - if (_IOC_DIR(cmd) & _IOC_WRITE) - ECALL(fd_copyin((void __user *)param, &inparam, size)) - - switch (cmd) { - case FDEJECT: - if (UDRS->fd_ref != 1) - /* somebody else has this drive open */ - return -EBUSY; - LOCK_FDC(drive, 1); - - /* do the actual eject. Fails on - * non-Sparc architectures */ - ret = fd_eject(UNIT(drive)); - - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); - process_fd_request(); + memset(&inparam, 0, sizeof(inparam)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + ret = fd_copyin((void __user *)param, &inparam, size); + if (ret) return ret; - case FDCLRPRM: - LOCK_FDC(drive, 1); - current_type[drive] = NULL; - floppy_sizes[drive] = MAX_DISK_SIZE << 1; - UDRS->keep_data = 0; - return invalidate_drive(bdev); - case FDSETPRM: - case FDDEFPRM: - return set_geometry(cmd, &inparam.g, - drive, type, bdev); - case FDGETPRM: - ECALL(get_floppy_geometry(drive, type, - (struct floppy_struct **) - &outparam)); - break; - - case FDMSGON: - UDP->flags |= FTD_MSG; - return 0; - case FDMSGOFF: - UDP->flags &= ~FTD_MSG; - return 0; - - case FDFMTBEG: - LOCK_FDC(drive, 1); - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - ret = UDRS->flags; - process_fd_request(); - if (ret & FD_VERIFY) - return -ENODEV; - if (!(ret & FD_DISK_WRITABLE)) - return -EROFS; - return 0; - case FDFMTTRK: - if (UDRS->fd_ref != 1) - return -EBUSY; - return do_format(drive, &inparam.f); - case FDFMTEND: - case FDFLUSH: - LOCK_FDC(drive, 1); - return invalidate_drive(bdev); - - case FDSETEMSGTRESH: - UDP->max_errors.reporting = - (unsigned short)(param & 0x0f); - return 0; - OUT(FDGETMAXERRS, &UDP->max_errors); - IN(FDSETMAXERRS, &UDP->max_errors, max_errors); - - case FDGETDRVTYP: - outparam = drive_name(type, drive); - SUPBOUND(size, strlen(outparam) + 1); - break; - - IN(FDSETDRVPRM, UDP, dp); - OUT(FDGETDRVPRM, UDP); - - case FDPOLLDRVSTAT: - LOCK_FDC(drive, 1); - CALL(poll_drive(1, FD_RAW_NEED_DISK)); - process_fd_request(); - /* fall through */ - OUT(FDGETDRVSTAT, UDRS); - - case FDRESET: - return user_reset_fdc(drive, (int)param, 1); - - OUT(FDGETFDCSTAT, UFDCS); + } - case FDWERRORCLR: - CLEARSTRUCT(UDRWE); - return 0; - OUT(FDWERRORGET, UDRWE); - - case FDRAWCMD: - if (type) - return -EINVAL; - LOCK_FDC(drive, 1); - set_floppy(drive); - CALL(i = raw_cmd_ioctl(cmd, (void __user *)param)); - process_fd_request(); - return i; + switch (cmd) { + case FDEJECT: + if (UDRS->fd_ref != 1) + /* somebody else has this drive open */ + return -EBUSY; + if (lock_fdc(drive, true)) + return -EINTR; - case FDTWADDLE: - LOCK_FDC(drive, 1); - twaddle(); - process_fd_request(); - return 0; + /* do the actual eject. Fails on + * non-Sparc architectures */ + ret = fd_eject(UNIT(drive)); - default: + set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); + set_bit(FD_VERIFY_BIT, &UDRS->flags); + process_fd_request(); + return ret; + case FDCLRPRM: + if (lock_fdc(drive, true)) + return -EINTR; + current_type[drive] = NULL; + floppy_sizes[drive] = MAX_DISK_SIZE << 1; + UDRS->keep_data = 0; + return invalidate_drive(bdev); + case FDSETPRM: + case FDDEFPRM: + return set_geometry(cmd, &inparam.g, drive, type, bdev); + case FDGETPRM: + ret = get_floppy_geometry(drive, type, + (struct floppy_struct **)&outparam); + if (ret) + return ret; + break; + case FDMSGON: + UDP->flags |= FTD_MSG; + return 0; + case FDMSGOFF: + UDP->flags &= ~FTD_MSG; + return 0; + case FDFMTBEG: + if (lock_fdc(drive, true)) + return -EINTR; + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) + return -EINTR; + ret = UDRS->flags; + process_fd_request(); + if (ret & FD_VERIFY) + return -ENODEV; + if (!(ret & FD_DISK_WRITABLE)) + return -EROFS; + return 0; + case FDFMTTRK: + if (UDRS->fd_ref != 1) + return -EBUSY; + return do_format(drive, &inparam.f); + case FDFMTEND: + case FDFLUSH: + if (lock_fdc(drive, true)) + return -EINTR; + return invalidate_drive(bdev); + case FDSETEMSGTRESH: + UDP->max_errors.reporting = (unsigned short)(param & 0x0f); + return 0; + case FDGETMAXERRS: + outparam = &UDP->max_errors; + break; + case FDSETMAXERRS: + UDP->max_errors = inparam.max_errors; + break; + case FDGETDRVTYP: + outparam = drive_name(type, drive); + SUPBOUND(size, strlen((const char *)outparam) + 1); + break; + case FDSETDRVPRM: + *UDP = inparam.dp; + break; + case FDGETDRVPRM: + outparam = UDP; + break; + case FDPOLLDRVSTAT: + if (lock_fdc(drive, true)) + return -EINTR; + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) + return -EINTR; + process_fd_request(); + /* fall through */ + case FDGETDRVSTAT: + outparam = UDRS; + break; + case FDRESET: + return user_reset_fdc(drive, (int)param, true); + case FDGETFDCSTAT: + outparam = UFDCS; + break; + case FDWERRORCLR: + memset(UDRWE, 0, sizeof(*UDRWE)); + return 0; + case FDWERRORGET: + outparam = UDRWE; + break; + case FDRAWCMD: + if (type) return -EINVAL; - } + if (lock_fdc(drive, true)) + return -EINTR; + set_floppy(drive); + i = raw_cmd_ioctl(cmd, (void __user *)param); + if (i == -EINTR) + return -EINTR; + process_fd_request(); + return i; + case FDTWADDLE: + if (lock_fdc(drive, true)) + return -EINTR; + twaddle(); + process_fd_request(); + return 0; + default: + return -EINVAL; + } if (_IOC_DIR(cmd) & _IOC_READ) return fd_copyout((void __user *)param, outparam, size); - else - return 0; -#undef OUT -#undef IN + + return 0; } static void __init config_types(void) { - int first = 1; + bool has_drive = false; int drive; /* read drive info out of physical CMOS */ @@ -3655,17 +3627,22 @@ static void __init config_types(void) name = temparea; } if (name) { - const char *prepend = ","; - if (first) { - prepend = KERN_INFO "Floppy drive(s):"; - first = 0; + const char *prepend; + if (!has_drive) { + prepend = ""; + has_drive = true; + pr_info("Floppy drive(s):"); + } else { + prepend = ","; } - printk("%s fd%d is %s", prepend, drive, name); + + pr_cont("%s fd%d is %s", prepend, drive, name); } *UDP = *params; } - if (!first) - printk("\n"); + + if (has_drive) + pr_cont("\n"); } static int floppy_release(struct gendisk *disk, fmode_t mode) @@ -3705,8 +3682,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) goto out2; if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); + set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); + set_bit(FD_VERIFY_BIT, &UDRS->flags); } if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) @@ -3735,9 +3712,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) INFBOUND(try, 16); tmp = (char *)fd_dma_mem_alloc(1024 * try); } - if (!tmp && !floppy_track_buffer) { + if (!tmp && !floppy_track_buffer) fallback_on_nodma_alloc(&tmp, 2048 * try); - } if (!tmp && !floppy_track_buffer) { DPRINT("Unable to allocate DMA memory\n"); goto out; @@ -3767,11 +3743,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) if (mode & (FMODE_READ|FMODE_WRITE)) { UDRS->last_checked = 0; check_disk_change(bdev); - if (UTESTF(FD_DISK_CHANGED)) + if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) goto out; } res = -EROFS; - if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE))) + if ((mode & FMODE_WRITE) && + !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) goto out; } mutex_unlock(&open_lock); @@ -3795,17 +3772,18 @@ static int check_floppy_change(struct gendisk *disk) { int drive = (long)disk->private_data; - if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY)) + if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || + test_bit(FD_VERIFY_BIT, &UDRS->flags)) return 1; if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { - lock_fdc(drive, 0); - poll_drive(0, 0); + lock_fdc(drive, false); + poll_drive(false, 0); process_fd_request(); } - if (UTESTF(FD_DISK_CHANGED) || - UTESTF(FD_VERIFY) || + if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || + test_bit(FD_VERIFY_BIT, &UDRS->flags) || test_bit(drive, &fake_change) || (!ITYPE(UDRS->fd_device) && !current_type[drive])) return 1; @@ -3818,8 +3796,7 @@ static int check_floppy_change(struct gendisk *disk) * a disk in the drive, and whether that disk is writable. */ -static void floppy_rb0_complete(struct bio *bio, - int err) +static void floppy_rb0_complete(struct bio *bio, int err) { complete((struct completion *)bio->bi_private); } @@ -3877,14 +3854,16 @@ static int floppy_revalidate(struct gendisk *disk) int cf; int res = 0; - if (UTESTF(FD_DISK_CHANGED) || - UTESTF(FD_VERIFY) || 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) { - printk("VFS: revalidate called on non-open device.\n"); + pr_info("VFS: revalidate called on non-open device.\n"); return -EFAULT; } - lock_fdc(drive, 0); - cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY); + lock_fdc(drive, false); + cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || + test_bit(FD_VERIFY_BIT, &UDRS->flags)); if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) { process_fd_request(); /*already done by another thread */ return 0; @@ -3894,7 +3873,7 @@ static int floppy_revalidate(struct gendisk *disk) if (buffer_drive == drive) buffer_track = -1; clear_bit(drive, &fake_change); - UCLEARF(FD_DISK_CHANGED); + clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); if (cf) UDRS->generation++; if (NO_GEOM) { @@ -3902,7 +3881,7 @@ static int floppy_revalidate(struct gendisk *disk) res = __floppy_read_block_0(opened_bdev[drive]); } else { if (cf) - poll_drive(0, FD_RAW_NEED_DISK); + poll_drive(false, FD_RAW_NEED_DISK); process_fd_request(); } } @@ -3934,21 +3913,21 @@ static char __init get_fdc_version(void) output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */ if (FDCS->reset) return FDC_NONE; - if ((r = result()) <= 0x00) + r = result(); + if (r <= 0x00) return FDC_NONE; /* No FDC present ??? */ if ((r == 1) && (reply_buffer[0] == 0x80)) { - printk(KERN_INFO "FDC %d is an 8272A\n", fdc); + pr_info("FDC %d is an 8272A\n", fdc); return FDC_8272A; /* 8272a/765 don't know DUMPREGS */ } if (r != 10) { - printk - ("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n", - fdc, r); + pr_info("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n", + fdc, r); return FDC_UNKNOWN; } if (!fdc_configure()) { - printk(KERN_INFO "FDC %d is an 82072\n", fdc); + pr_info("FDC %d is an 82072\n", fdc); return FDC_82072; /* 82072 doesn't know CONFIGURE */ } @@ -3956,52 +3935,50 @@ static char __init get_fdc_version(void) if (need_more_output() == MORE_OUTPUT) { output_byte(0); } else { - printk(KERN_INFO "FDC %d is an 82072A\n", fdc); + pr_info("FDC %d is an 82072A\n", fdc); return FDC_82072A; /* 82072A as found on Sparcs. */ } output_byte(FD_UNLOCK); r = result(); if ((r == 1) && (reply_buffer[0] == 0x80)) { - printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc); - return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know + pr_info("FDC %d is a pre-1991 82077\n", fdc); + return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know * LOCK/UNLOCK */ } if ((r != 1) || (reply_buffer[0] != 0x00)) { - printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n", - fdc, r); + pr_info("FDC %d init: UNLOCK: unexpected return of %d bytes.\n", + fdc, r); return FDC_UNKNOWN; } output_byte(FD_PARTID); r = result(); if (r != 1) { - printk("FDC %d init: PARTID: unexpected return of %d bytes.\n", - fdc, r); + pr_info("FDC %d init: PARTID: unexpected return of %d bytes.\n", + fdc, r); return FDC_UNKNOWN; } if (reply_buffer[0] == 0x80) { - printk(KERN_INFO "FDC %d is a post-1991 82077\n", fdc); + pr_info("FDC %d is a post-1991 82077\n", fdc); return FDC_82077; /* Revised 82077AA passes all the tests */ } switch (reply_buffer[0] >> 5) { case 0x0: /* Either a 82078-1 or a 82078SL running at 5Volt */ - printk(KERN_INFO "FDC %d is an 82078.\n", fdc); + pr_info("FDC %d is an 82078.\n", fdc); return FDC_82078; case 0x1: - printk(KERN_INFO "FDC %d is a 44pin 82078\n", fdc); + pr_info("FDC %d is a 44pin 82078\n", fdc); return FDC_82078; case 0x2: - printk(KERN_INFO "FDC %d is a S82078B\n", fdc); + pr_info("FDC %d is a S82078B\n", fdc); return FDC_S82078B; case 0x3: - printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n", - fdc); + pr_info("FDC %d is a National Semiconductor PC87306\n", fdc); return FDC_87306; default: - printk(KERN_INFO - "FDC %d init: 82078 variant with unknown PARTID=%d.\n", - fdc, reply_buffer[0] >> 5); + pr_info("FDC %d init: 82078 variant with unknown PARTID=%d.\n", + fdc, reply_buffer[0] >> 5); return FDC_82078_UNKN; } } /* get_fdc_version */ @@ -4113,9 +4090,9 @@ static int __init floppy_setup(char *str) else param = config_params[i].def_param; if (config_params[i].fn) - config_params[i]. - fn(ints, param, - config_params[i].param2); + config_params[i].fn(ints, param, + config_params[i]. + param2); if (config_params[i].var) { DPRINT("%s=%d\n", str, param); *config_params[i].var = param; @@ -4129,8 +4106,8 @@ static int __init floppy_setup(char *str) DPRINT("allowed options are:"); for (i = 0; i < ARRAY_SIZE(config_params); i++) - printk(" %s", config_params[i].name); - printk("\n"); + pr_cont(" %s", config_params[i].name); + pr_cont("\n"); } else DPRINT("botched floppy option\n"); DPRINT("Read Documentation/blockdev/floppy.txt\n"); @@ -4148,7 +4125,8 @@ static ssize_t floppy_cmos_show(struct device *dev, drive = p->id; return sprintf(buf, "%X\n", UDP->cmos); } -DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL); + +DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL); static void floppy_device_release(struct device *dev) { @@ -4160,7 +4138,7 @@ static int floppy_resume(struct device *dev) for (fdc = 0; fdc < N_FDC; fdc++) if (FDCS->address != -1) - user_reset_fdc(-1, FD_RESET_ALWAYS, 0); + user_reset_fdc(-1, FD_RESET_ALWAYS, false); return 0; } @@ -4172,8 +4150,8 @@ static const struct dev_pm_ops floppy_pm_ops = { static struct platform_driver floppy_driver = { .driver = { - .name = "floppy", - .pm = &floppy_pm_ops, + .name = "floppy", + .pm = &floppy_pm_ops, }, }; @@ -4245,16 +4223,16 @@ static int __init floppy_init(void) else floppy_sizes[i] = MAX_DISK_SIZE << 1; - reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); + reschedule_timeout(MAXTIMEOUT, "floppy init"); config_types(); for (i = 0; i < N_FDC; i++) { fdc = i; - CLEARSTRUCT(FDCS); + memset(FDCS, 0, sizeof(*FDCS)); FDCS->dtr = -1; FDCS->dor = 0x4; #if defined(__sparc__) || defined(__mc68000__) - /*sparcs/sun3x don't have a DOR reset which we can fall back on to */ + /*sparcs/sun3x don't have a DOR reset which we can fall back on to */ #ifdef __mc68000__ if (MACH_IS_SUN3X) #endif @@ -4283,11 +4261,11 @@ static int __init floppy_init(void) /* initialise drive state */ for (drive = 0; drive < N_DRIVE; drive++) { - CLEARSTRUCT(UDRS); - CLEARSTRUCT(UDRWE); - USETF(FD_DISK_NEWCHANGE); - USETF(FD_DISK_CHANGED); - USETF(FD_VERIFY); + memset(UDRS, 0, sizeof(*UDRS)); + memset(UDRWE, 0, sizeof(*UDRWE)); + set_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags); + set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); + set_bit(FD_VERIFY_BIT, &UDRS->flags); UDRS->fd_device = -1; floppy_track_buffer = NULL; max_buffer_sectors = 0; @@ -4307,7 +4285,7 @@ static int __init floppy_init(void) if (FDCS->address == -1) continue; FDCS->rawcmd = 2; - if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) { + if (user_reset_fdc(-1, FD_RESET_ALWAYS, false)) { /* free ioports reserved by floppy_grab_irq_and_dma() */ floppy_release_regions(fdc); FDCS->address = -1; @@ -4330,12 +4308,12 @@ static int __init floppy_init(void) * properly, so force a reset for the standard FDC clones, * to avoid interrupt garbage. */ - user_reset_fdc(-1, FD_RESET_ALWAYS, 0); + user_reset_fdc(-1, FD_RESET_ALWAYS, false); } fdc = 0; del_timer(&fd_timeout); current_drive = 0; - initialising = 0; + initialized = true; if (have_no_fdc) { DPRINT("no floppy controllers found\n"); err = have_no_fdc; @@ -4356,7 +4334,8 @@ static int __init floppy_init(void) if (err) goto out_flush_work; - err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); + err = device_create_file(&floppy_device[drive].dev, + &dev_attr_cmos); if (err) goto out_unreg_platform_dev; @@ -4420,8 +4399,10 @@ static int floppy_request_regions(int fdc) const struct io_region *p; for (p = io_regions; p < ARRAY_END(io_regions); p++) { - if (!request_region(FDCS->address + p->offset, p->size, "floppy")) { - DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset); + if (!request_region(FDCS->address + p->offset, + p->size, "floppy")) { + DPRINT("Floppy io-port 0x%04lx in use\n", + FDCS->address + p->offset); floppy_release_allocated_regions(fdc, p); return -EBUSY; } @@ -4512,11 +4493,9 @@ cleanup: static void floppy_release_irq_and_dma(void) { int old_fdc; -#ifdef FLOPPY_SANITY_CHECK #ifndef __sparc__ int drive; #endif -#endif long tmpsize; unsigned long tmpaddr; unsigned long flags; @@ -4547,20 +4526,18 @@ static void floppy_release_irq_and_dma(void) buffer_min = buffer_max = -1; fd_dma_mem_free(tmpaddr, tmpsize); } -#ifdef FLOPPY_SANITY_CHECK #ifndef __sparc__ for (drive = 0; drive < N_FDC * 4; drive++) if (timer_pending(motor_off_timer + drive)) - printk("motor off timer %d still active\n", drive); + pr_info("motor off timer %d still active\n", drive); #endif if (timer_pending(&fd_timeout)) - printk("floppy timer still active:%s\n", timeout_message); + pr_info("floppy timer still active:%s\n", timeout_message); if (timer_pending(&fd_timer)) - printk("auxiliary floppy timer still active\n"); + pr_info("auxiliary floppy timer still active\n"); if (work_pending(&floppy_work)) - printk("work still pending\n"); -#endif + pr_info("work still pending\n"); old_fdc = fdc; for (fdc = 0; fdc < N_FDC; fdc++) if (FDCS->address != -1) @@ -4577,7 +4554,9 @@ static void __init parse_floppy_cfg_string(char *cfg) char *ptr; while (*cfg) { - for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ; + ptr = cfg; + while (*cfg && *cfg != ' ' && *cfg != '\t') + cfg++; if (*cfg) { *cfg = '\0'; cfg++; @@ -4625,6 +4604,7 @@ static void __exit floppy_module_exit(void) /* eject disk, if any */ fd_eject(0); } + module_exit(floppy_module_exit); module_param(floppy, charp, 0); @@ -4636,9 +4616,10 @@ MODULE_LICENSE("GPL"); /* This doesn't actually get used other than for module information */ static const struct pnp_device_id floppy_pnpids[] = { - { "PNP0700", 0 }, - { } + {"PNP0700", 0}, + {} }; + MODULE_DEVICE_TABLE(pnp, floppy_pnpids); #else diff --git a/drivers/block/hd.c b/drivers/block/hd.c index b9868ad..81c78b3 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -34,7 +34,6 @@ #include <linux/fs.h> #include <linux/kernel.h> #include <linux/genhd.h> -#include <linux/slab.h> #include <linux/string.h> #include <linux/ioport.h> #include <linux/init.h> diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bd112c8..8546d12 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -71,7 +71,6 @@ #include <linux/buffer_head.h> /* for invalidate_bdev() */ #include <linux/completion.h> #include <linux/highmem.h> -#include <linux/gfp.h> #include <linux/kthread.h> #include <linux/splice.h> @@ -238,6 +237,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, if (ret) goto fail; + file_update_time(file); + transfer_result = lo_do_transfer(lo, WRITE, page, offset, bvec->bv_page, bv_offs, size, IV); copied = size; diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 5416c9a..28db925 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/mg_disk.h> +#include <linux/slab.h> #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index cc923a5..218d091 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -27,6 +27,7 @@ #include <linux/compiler.h> #include <linux/err.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <net/sock.h> #include <linux/net.h> #include <linux/kthread.h> diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index a808b15..6cd8b70 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c @@ -63,6 +63,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/fs.h> +#include <linux/slab.h> #include <scsi/osd_initiator.h> #include <scsi/osd_attributes.h> #include <scsi/osd_sec.h> @@ -476,7 +477,9 @@ static void class_osdblk_release(struct class *cls) kfree(cls); } -static ssize_t class_osdblk_list(struct class *c, char *data) +static ssize_t class_osdblk_list(struct class *c, + struct class_attribute *attr, + char *data) { int n = 0; struct list_head *tmp; @@ -500,7 +503,9 @@ static ssize_t class_osdblk_list(struct class *c, char *data) return n; } -static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count) +static ssize_t class_osdblk_add(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { struct osdblk_device *osdev; ssize_t rc; @@ -592,7 +597,9 @@ err_out_mod: return rc; } -static ssize_t class_osdblk_remove(struct class *c, const char *buf, +static ssize_t class_osdblk_remove(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { struct osdblk_device *osdev = NULL; diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 8866ca3..71acf4e 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg) && (j++ < PCD_SPIN)) udelay(PCD_DELAY); - if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) { + if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) { s = read_reg(cd, 7); e = read_reg(cd, 1); p = read_reg(cd, 2); - if (j >= PCD_SPIN) + if (j > PCD_SPIN) e |= 0x100; if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index e712cd5..c1e5cd0 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -145,6 +145,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; #include <linux/init.h> #include <linux/module.h> +#include <linux/gfp.h> #include <linux/fs.h> #include <linux/delay.h> #include <linux/hdreg.h> diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index ddb4f9a..c059aab 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg) && (j++ < PF_SPIN)) udelay(PF_SPIN_DEL); - if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) { + if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) { s = read_reg(pf, 7); e = read_reg(pf, 1); p = read_reg(pf, 2); - if (j >= PF_SPIN) + if (j > PF_SPIN) e |= 0x100; if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 1e4006e..bc5825f 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg) && (j++ < PT_SPIN)) udelay(PT_SPIN_DEL); - if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) { + if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) { s = read_reg(pi, 7); e = read_reg(pi, 1); p = read_reg(pi, 2); - if (j >= PT_SPIN) + if (j > PT_SPIN) e |= 0x100; if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index b72935b..8a549db 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -48,6 +48,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> +#include <linux/compat.h> #include <linux/kthread.h> #include <linux/errno.h> #include <linux/spinlock.h> @@ -57,6 +58,7 @@ #include <linux/miscdevice.h> #include <linux/freezer.h> #include <linux/mutex.h> +#include <linux/slab.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_ioctl.h> #include <scsi/scsi.h> @@ -284,7 +286,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj, return len; } -static struct sysfs_ops kobj_pkt_ops = { +static const struct sysfs_ops kobj_pkt_ops = { .show = kobj_pkt_show, .store = kobj_pkt_store }; @@ -337,7 +339,9 @@ static void class_pktcdvd_release(struct class *cls) { kfree(cls); } -static ssize_t class_pktcdvd_show_map(struct class *c, char *data) +static ssize_t class_pktcdvd_show_map(struct class *c, + struct class_attribute *attr, + char *data) { int n = 0; int idx; @@ -356,7 +360,9 @@ static ssize_t class_pktcdvd_show_map(struct class *c, char *data) return n; } -static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, +static ssize_t class_pktcdvd_store_add(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { unsigned int major, minor; @@ -376,7 +382,9 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, return -EINVAL; } -static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf, +static ssize_t class_pktcdvd_store_remove(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { unsigned int major, minor; @@ -2977,7 +2985,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) mutex_unlock(&ctl_mutex); } -static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; struct pkt_ctrl_command ctrl_cmd; @@ -3014,10 +3022,20 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm return ret; } +#ifdef CONFIG_COMPAT +static long pkt_ctl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return pkt_ctl_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif static const struct file_operations pkt_ctl_fops = { - .ioctl = pkt_ctl_ioctl, - .owner = THIS_MODULE, + .open = nonseekable_open, + .unlocked_ioctl = pkt_ctl_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = pkt_ctl_compat_ioctl, +#endif + .owner = THIS_MODULE, }; static struct miscdevice pkt_misc = { diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index bc95469..3b419e3 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -20,6 +20,7 @@ #include <linux/ata.h> #include <linux/blkdev.h> +#include <linux/slab.h> #include <asm/lv1call.h> #include <asm/ps3stor.h> diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index e446082..b3bdb8a 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -12,6 +12,7 @@ #include <linux/delay.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/slab.h> #include <asm/cell-regs.h> #include <asm/firmware.h> diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 821c283..e463657 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/fd.h> +#include <linux/slab.h> #include <linux/blkdev.h> #include <linux/hdreg.h> #include <linux/kernel.h> diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 2e88983..0536b5b 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -27,6 +27,7 @@ #include <linux/blkdev.h> #include <linux/timer.h> #include <linux/scatterlist.h> +#include <linux/slab.h> #include <scsi/scsi.h> #define DRV_NAME "ub" diff --git a/drivers/block/umem.c b/drivers/block/umem.c index ad1ba39..2f9470f 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -40,13 +40,13 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/mman.h> +#include <linux/gfp.h> #include <linux/ioctl.h> #include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/timer.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/dma-mapping.h> #include <linux/fcntl.h> /* O_ACCMODE */ diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3c64af0..2138a7a 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -1,5 +1,6 @@ //#define DEBUG #include <linux/spinlock.h> +#include <linux/slab.h> #include <linux/blkdev.h> #include <linux/hdreg.h> #include <linux/virtio.h> @@ -347,14 +348,13 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) set_capacity(vblk->disk, cap); /* We can handle whatever the host told us to handle. */ - blk_queue_max_phys_segments(q, vblk->sg_elems-2); - blk_queue_max_hw_segments(q, vblk->sg_elems-2); + blk_queue_max_segments(q, vblk->sg_elems-2); /* No need to bounce any requests */ blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); /* No real sector limit. */ - blk_queue_max_sectors(q, -1U); + blk_queue_max_hw_sectors(q, -1U); /* Host can optionally specify maximum segment size and number of * segments. */ diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 1a325fb..18a80ff 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -49,6 +49,7 @@ #include <linux/blkpg.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/gfp.h> #include <asm/system.h> #include <asm/uaccess.h> diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9c09694..82ed403 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -40,6 +40,7 @@ #include <linux/hdreg.h> #include <linux/cdrom.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/scatterlist.h> #include <xen/xen.h> diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 64f941e..9114654 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -33,6 +33,7 @@ #include <linux/module.h> #include <linux/blkdev.h> #include <linux/bitops.h> +#include <linux/slab.h> #include <asm/setup.h> #include <asm/amigahw.h> |