diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2009-09-12 12:02:26 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-12 12:02:26 +0100 |
commit | ddd559b13f6d2fe3ad68c4b3f5235fd3c2eae4e3 (patch) | |
tree | d827bca3fc825a0ac33efbcd493713be40fcc812 /drivers/block | |
parent | cf7a2b4fb6a9b86779930a0a123b0df41aa9208f (diff) | |
parent | f17a1f06d2fa93f4825be572622eb02c4894db4e (diff) |
Merge branch 'devel-stable' into devel
Conflicts:
MAINTAINERS
arch/arm/mm/fault.c
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/DAC960.c | 1 | ||||
-rw-r--r-- | drivers/block/ataflop.c | 2 | ||||
-rw-r--r-- | drivers/block/cciss.c | 1 | ||||
-rw-r--r-- | drivers/block/loop.c | 1 | ||||
-rw-r--r-- | drivers/block/mg_disk.c | 101 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 12 | ||||
-rw-r--r-- | drivers/block/z2ram.c | 2 |
7 files changed, 70 insertions, 50 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 668dc234b8e..1e6b7c14f69 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -36,6 +36,7 @@ #include <linux/ioport.h> #include <linux/mm.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <linux/proc_fs.h> #include <linux/reboot.h> #include <linux/spinlock.h> diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index f5e7180d7f4..3ff02941b3d 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1627,7 +1627,7 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, drive, dtp->blocks, dtp->spt, dtp->stretch); /* sanity check */ - if (!dtp || setprm.track != dtp->blocks/dtp->spt/2 || + if (setprm.track != dtp->blocks/dtp->spt/2 || setprm.head != 2) { redo_fd_request(); return -EINVAL; diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 65a0655e7fc..a52cc7fe45e 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -26,6 +26,7 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <linux/delay.h> #include <linux/major.h> #include <linux/fs.h> diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 801f4ab8330..5757188cd1f 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -61,7 +61,6 @@ #include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/init.h> -#include <linux/smp_lock.h> #include <linux/swap.h> #include <linux/slab.h> #include <linux/loop.h> diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index f703f547824..6d7fbaa9224 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -36,7 +36,6 @@ /* Register offsets */ #define MG_BUFF_OFFSET 0x8000 -#define MG_STORAGE_BUFFER_SIZE 0x200 #define MG_REG_OFFSET 0xC000 #define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */ #define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */ @@ -219,6 +218,16 @@ static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec) host->error = MG_ERR_NONE; expire = jiffies + msecs_to_jiffies(msec); + /* These 2 times dummy status read prevents reading invalid + * status. A very little time (3 times of mflash operating clk) + * is required for busy bit is set. Use dummy read instead of + * busy wait, because mflash's PLL is machine dependent. + */ + if (prv_data->use_polling) { + status = inb((unsigned long)host->dev_base + MG_REG_STATUS); + status = inb((unsigned long)host->dev_base + MG_REG_STATUS); + } + status = inb((unsigned long)host->dev_base + MG_REG_STATUS); do { @@ -245,8 +254,6 @@ static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec) mg_dump_status("not ready", status, host); return MG_ERR_INV_STAT; } - if (prv_data->use_polling) - msleep(1); status = inb((unsigned long)host->dev_base + MG_REG_STATUS); } while (time_before(cur_jiffies, expire)); @@ -469,9 +476,18 @@ static unsigned int mg_out(struct mg_host *host, return MG_ERR_NONE; } +static void mg_read_one(struct mg_host *host, struct request *req) +{ + u16 *buff = (u16 *)req->buffer; + u32 i; + + for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) + *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + + (i << 1)); +} + static void mg_read(struct request *req) { - u32 j; struct mg_host *host = req->rq_disk->private_data; if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req), @@ -482,49 +498,65 @@ static void mg_read(struct request *req) blk_rq_sectors(req), blk_rq_pos(req), req->buffer); do { - u16 *buff = (u16 *)req->buffer; - if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } - for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) - *buff++ = inw((unsigned long)host->dev_base + - MG_BUFF_OFFSET + (j << 1)); + + mg_read_one(host, req); outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); } while (mg_end_request(host, 0, MG_SECTOR_SIZE)); } +static void mg_write_one(struct mg_host *host, struct request *req) +{ + u16 *buff = (u16 *)req->buffer; + u32 i; + + for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) + outw(*buff++, (unsigned long)host->dev_base + MG_BUFF_OFFSET + + (i << 1)); +} + static void mg_write(struct request *req) { - u32 j; struct mg_host *host = req->rq_disk->private_data; + unsigned int rem = blk_rq_sectors(req); - if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req), + if (mg_out(host, blk_rq_pos(req), rem, MG_CMD_WR, NULL) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", - blk_rq_sectors(req), blk_rq_pos(req), req->buffer); + rem, blk_rq_pos(req), req->buffer); + + if (mg_wait(host, ATA_DRQ, + MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { + mg_bad_rw_intr(host); + return; + } do { - u16 *buff = (u16 *)req->buffer; + mg_write_one(host, req); - if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { + outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + + MG_REG_COMMAND); + + rem--; + if (rem > 1 && mg_wait(host, ATA_DRQ, + MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { + mg_bad_rw_intr(host); + return; + } else if (mg_wait(host, MG_STAT_READY, + MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } - for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) - outw(*buff++, (unsigned long)host->dev_base + - MG_BUFF_OFFSET + (j << 1)); - - outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + - MG_REG_COMMAND); } while (mg_end_request(host, 0, MG_SECTOR_SIZE)); } @@ -532,7 +564,6 @@ static void mg_read_intr(struct mg_host *host) { struct request *req = host->req; u32 i; - u16 *buff; /* check status */ do { @@ -550,13 +581,7 @@ static void mg_read_intr(struct mg_host *host) return; ok_to_read: - /* get current segment of request */ - buff = (u16 *)req->buffer; - - /* read 1 sector */ - for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) - *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + - (i << 1)); + mg_read_one(host, req); MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n", blk_rq_pos(req), blk_rq_sectors(req) - 1, req->buffer); @@ -575,8 +600,7 @@ ok_to_read: static void mg_write_intr(struct mg_host *host) { struct request *req = host->req; - u32 i, j; - u16 *buff; + u32 i; bool rem; /* check status */ @@ -597,12 +621,7 @@ static void mg_write_intr(struct mg_host *host) ok_to_write: if ((rem = mg_end_request(host, 0, MG_SECTOR_SIZE))) { /* write 1 sector and set handler if remains */ - buff = (u16 *)req->buffer; - for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) { - outw(*buff, (unsigned long)host->dev_base + - MG_BUFF_OFFSET + (j << 1)); - buff++; - } + mg_write_one(host, req); MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n", blk_rq_pos(req), blk_rq_sectors(req), req->buffer); host->mg_do_intr = mg_write_intr; @@ -667,9 +686,6 @@ static unsigned int mg_issue_req(struct request *req, unsigned int sect_num, unsigned int sect_cnt) { - u16 *buff; - u32 i; - switch (rq_data_dir(req)) { case READ: if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr) @@ -693,12 +709,7 @@ static unsigned int mg_issue_req(struct request *req, mg_bad_rw_intr(host); return host->error; } - buff = (u16 *)req->buffer; - for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) { - outw(*buff, (unsigned long)host->dev_base + - MG_BUFF_OFFSET + (i << 1)); - buff++; - } + mg_write_one(host, req); mod_timer(&host->timer, jiffies + 3 * HZ); outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 43db3ea15b5..aa1a3d5a3e2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -213,7 +213,7 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, * Only allow the generic SCSI ioctls if the host can support it. */ if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) - return -ENOIOCTLCMD; + return -ENOTTY; return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); } @@ -360,6 +360,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2); blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); + /* No need to bounce any requests */ + blk_queue_bounce_limit(vblk->disk->queue, BLK_BOUNCE_ANY); + /* No real sector limit. */ blk_queue_max_sectors(vblk->disk->queue, -1U); @@ -424,7 +427,12 @@ static unsigned int features[] = { VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY }; -static struct virtio_driver virtio_blk = { +/* + * virtio_blk causes spurious section mismatch warning by + * simultaneously referring to a __devinit and a __devexit function. + * Use __refdata to avoid this warning. + */ +static struct virtio_driver __refdata virtio_blk = { .feature_table = features, .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 4575171e5be..b2590409f25 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -374,7 +374,7 @@ err: static void __exit z2_exit(void) { int i, j; - blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); + blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT); unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); del_gendisk(z2ram_gendisk); put_disk(z2ram_gendisk); |