diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/Kconfig | 3 | ||||
-rw-r--r-- | drivers/block/ataflop.c | 16 | ||||
-rw-r--r-- | drivers/block/cciss.c | 10 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 4 | ||||
-rw-r--r-- | drivers/block/loop.c | 8 | ||||
-rw-r--r-- | drivers/block/paride/pt.c | 2 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 4 | ||||
-rw-r--r-- | drivers/block/rd.c | 3 | ||||
-rw-r--r-- | drivers/block/ub.c | 23 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 106 |
10 files changed, 96 insertions, 83 deletions
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index f2122855d4e..64e5148d82b 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -440,6 +440,7 @@ config VIRTIO_BLK tristate "Virtio block driver (EXPERIMENTAL)" depends on EXPERIMENTAL && VIRTIO ---help--- - This is the virtual block driver for lguest. Say Y or M. + This is the virtual block driver for virtio. It can be used with + lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. endif # BLK_DEV diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 94268c75d04..424995073c6 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -90,7 +90,7 @@ static struct atari_disk_type { unsigned blocks; /* total number of blocks */ unsigned fdc_speed; /* fdc_speed setting */ unsigned stretch; /* track doubling ? */ -} disk_type[] = { +} atari_disk_type[] = { { "d360", 9, 720, 0, 0}, /* 0: 360kB diskette */ { "D360", 9, 720, 0, 1}, /* 1: 360kb in 720k or 1.2MB drive */ { "D720", 9,1440, 0, 0}, /* 2: 720kb in 720k or 1.2MB drive */ @@ -658,7 +658,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) return -EINVAL; } type = minor2disktype[type].index; - UDT = &disk_type[type]; + UDT = &atari_disk_type[type]; } if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { @@ -1064,7 +1064,7 @@ static void fd_rwsec_done1(int status) searched for a non-existent sector! */ !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) { if (Probing) { - if (SUDT > disk_type) { + if (SUDT > atari_disk_type) { if (SUDT[-1].blocks > ReqBlock) { /* try another disk type */ SUDT--; @@ -1082,7 +1082,7 @@ static void fd_rwsec_done1(int status) } else { /* record not found, but not probing. Maybe stretch wrong ? Restart probing */ if (SUD.autoprobe) { - SUDT = disk_type + StartDiskType[DriveType]; + SUDT = atari_disk_type + StartDiskType[DriveType]; set_capacity(unit[SelectedDrive].disk, SUDT->blocks); Probing = 1; @@ -1421,7 +1421,7 @@ repeat: if (type == 0) { if (!UDT) { Probing = 1; - UDT = disk_type + StartDiskType[DriveType]; + UDT = atari_disk_type + StartDiskType[DriveType]; set_capacity(floppy->disk, UDT->blocks); UD.autoprobe = 1; } @@ -1439,7 +1439,7 @@ repeat: goto repeat; } type = minor2disktype[type].index; - UDT = &disk_type[type]; + UDT = &atari_disk_type[type]; set_capacity(floppy->disk, UDT->blocks); UD.autoprobe = 0; } @@ -1505,7 +1505,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, if (minor2disktype[type].drive_types > DriveType) return -ENODEV; type = minor2disktype[type].index; - dtp = &disk_type[type]; + dtp = &atari_disk_type[type]; if (UD.flags & FTD_MSG) printk (KERN_ERR "floppy%d: found dtp %p name %s!\n", drive, dtp, dtp->name); @@ -1576,7 +1576,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, continue; } setidx = minor2disktype[settype].index; - dtp = &disk_type[setidx]; + dtp = &atari_disk_type[setidx]; /* found matching entry ?? */ if ( dtp->blocks == setprm.size diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 855ce8e5efb..9715be3f248 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -2630,12 +2630,14 @@ static void do_cciss_request(struct request_queue *q) c->Request.CDB[8] = creq->nr_sectors & 0xff; c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; } else { + u32 upper32 = upper_32_bits(start_blk); + c->Request.CDBLen = 16; c->Request.CDB[1]= 0; - c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB - c->Request.CDB[3]= (start_blk >> 48) & 0xff; - c->Request.CDB[4]= (start_blk >> 40) & 0xff; - c->Request.CDB[5]= (start_blk >> 32) & 0xff; + c->Request.CDB[2]= (upper32 >> 24) & 0xff; //MSB + c->Request.CDB[3]= (upper32 >> 16) & 0xff; + c->Request.CDB[4]= (upper32 >> 8) & 0xff; + c->Request.CDB[5]= upper32 & 0xff; c->Request.CDB[6]= (start_blk >> 24) & 0xff; c->Request.CDB[7]= (start_blk >> 16) & 0xff; c->Request.CDB[8]= (start_blk >> 8) & 0xff; diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 63ee6c076cb..55178e9973a 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1453,7 +1453,7 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) rc = sendcmd(CCISS_RESET_MSG, ctlr, NULL, 0, 2, 0, 0, (unsigned char *) &cmd_in_trouble->Header.LUN.LunAddrBytes[0], TYPE_MSG); - /* sendcmd turned off interrputs on the board, turn 'em back on. */ + /* sendcmd turned off interrupts on the board, turn 'em back on. */ (*c)->access.set_intr_mask(*c, CCISS_INTR_ON); if (rc == 0) return SUCCESS; @@ -1483,7 +1483,7 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) 0, 2, 0, 0, (unsigned char *) &cmd_to_abort->Header.LUN.LunAddrBytes[0], TYPE_MSG); - /* sendcmd turned off interrputs on the board, turn 'em back on. */ + /* sendcmd turned off interrupts on the board, turn 'em back on. */ (*c)->access.set_intr_mask(*c, CCISS_INTR_ON); if (rc == 0) return SUCCESS; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b8af22e610d..91ebb007416 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -973,6 +973,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) lo->transfer = xfer->transfer; lo->ioctl = xfer->ioctl; + if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) != + (info->lo_flags & LO_FLAGS_AUTOCLEAR)) + lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; + lo->lo_encrypt_key_size = info->lo_encrypt_key_size; lo->lo_init[0] = info->lo_init[0]; lo->lo_init[1] = info->lo_init[1]; @@ -1331,6 +1335,10 @@ static int lo_release(struct inode *inode, struct file *file) mutex_lock(&lo->lo_ctl_mutex); --lo->lo_refcnt; + + if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt) + loop_clr_fd(lo, inode->i_bdev); + mutex_unlock(&lo->lo_ctl_mutex); return 0; diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 76096cad798..8b9549ab4a4 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -660,7 +660,7 @@ static int pt_open(struct inode *inode, struct file *file) pt_identify(tape); err = -ENODEV; - if (!tape->flags & PT_MEDIA) + if (!(tape->flags & PT_MEDIA)) goto out; err = -EROFS; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index e9de1712e5a..674cd66dcab 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2212,11 +2212,11 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) return ret; } - if (!buf[6] & 0x40) { + if (!(buf[6] & 0x40)) { printk(DRIVER_NAME": Disc type is not CD-RW\n"); return 1; } - if (!buf[6] & 0x4) { + if (!(buf[6] & 0x4)) { printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n"); return 1; } diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 82f4eecc869..06e23be7090 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -56,6 +56,7 @@ #include <linux/backing-dev.h> #include <linux/blkpg.h> #include <linux/writeback.h> +#include <linux/log2.h> #include <asm/uaccess.h> @@ -450,7 +451,7 @@ static int __init rd_init(void) err = -ENOMEM; if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 || - (rd_blocksize & (rd_blocksize-1))) { + !is_power_of_2(rd_blocksize)) { printk("RAMDISK: wrong blocksize %d, reverting to defaults\n", rd_blocksize); rd_blocksize = BLOCK_SIZE; diff --git a/drivers/block/ub.c b/drivers/block/ub.c index c6179d6ac6e..a70c1c29a7a 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -922,11 +922,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); - /* Fill what we shouldn't be filling, because usb-storage did so. */ - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; - if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ ub_complete(&sc->work_done); @@ -1313,9 +1308,6 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) sc->last_pipe = pipe; usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg), sg->length, ub_urb_complete, sc); - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ @@ -1356,9 +1348,6 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) sc->last_pipe = sc->recv_bulk_pipe; usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ @@ -1473,9 +1462,6 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { ub_complete(&sc->work_done); @@ -1953,9 +1939,6 @@ static int ub_sync_reset(struct ub_dev *sc) usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { printk(KERN_WARNING @@ -2007,9 +1990,6 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) goto err_submit; @@ -2077,9 +2057,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { printk(KERN_WARNING diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 924ddd8bccd..3b1a68d6edd 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -7,8 +7,10 @@ #include <linux/scatterlist.h> #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) +#define PART_BITS 4 + +static int major, index; -static unsigned char virtblk_index = 'a'; struct virtio_blk { spinlock_t lock; @@ -36,7 +38,7 @@ struct virtblk_req struct virtio_blk_inhdr in_hdr; }; -static bool blk_done(struct virtqueue *vq) +static void blk_done(struct virtqueue *vq) { struct virtio_blk *vblk = vq->vdev->priv; struct virtblk_req *vbr; @@ -65,7 +67,6 @@ static bool blk_done(struct virtqueue *vq) /* In case queue is stopped waiting for more buffers. */ blk_start_queue(vblk->disk->queue); spin_unlock_irqrestore(&vblk->lock, flags); - return true; } static bool do_req(struct request_queue *q, struct virtio_blk *vblk, @@ -153,20 +154,37 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp, (void __user *)data); } +/* We provide getgeo only to please some old bootloader/partitioning tools */ +static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) +{ + /* some standard values, similar to sd */ + geo->heads = 1 << 6; + geo->sectors = 1 << 5; + geo->cylinders = get_capacity(bd->bd_disk) >> 11; + return 0; +} + static struct block_device_operations virtblk_fops = { - .ioctl = virtblk_ioctl, - .owner = THIS_MODULE, + .ioctl = virtblk_ioctl, + .owner = THIS_MODULE, + .getgeo = virtblk_getgeo, }; +static int index_to_minor(int index) +{ + return index << PART_BITS; +} + static int virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; - int err, major; - void *token; - unsigned int len; + int err; u64 cap; u32 v; + if (index_to_minor(index) >= 1 << MINORBITS) + return -ENOSPC; + vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); if (!vblk) { err = -ENOMEM; @@ -178,7 +196,7 @@ static int virtblk_probe(struct virtio_device *vdev) vblk->vdev = vdev; /* We expect one virtqueue, for output. */ - vblk->vq = vdev->config->find_vq(vdev, blk_done); + vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); if (IS_ERR(vblk->vq)) { err = PTR_ERR(vblk->vq); goto out_free_vblk; @@ -190,17 +208,11 @@ static int virtblk_probe(struct virtio_device *vdev) goto out_free_vq; } - major = register_blkdev(0, "virtblk"); - if (major < 0) { - err = major; - goto out_mempool; - } - /* FIXME: How many partitions? How long is a piece of string? */ - vblk->disk = alloc_disk(1 << 4); + vblk->disk = alloc_disk(1 << PART_BITS); if (!vblk->disk) { err = -ENOMEM; - goto out_unregister_blkdev; + goto out_mempool; } vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); @@ -209,22 +221,32 @@ static int virtblk_probe(struct virtio_device *vdev) goto out_put_disk; } - sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++); + if (index < 26) { + sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); + } else if (index < (26 + 1) * 26) { + sprintf(vblk->disk->disk_name, "vd%c%c", + 'a' + index / 26 - 1, 'a' + index % 26); + } else { + const unsigned int m1 = (index / 26 - 1) / 26 - 1; + const unsigned int m2 = (index / 26 - 1) % 26; + const unsigned int m3 = index % 26; + sprintf(vblk->disk->disk_name, "vd%c%c%c", + 'a' + m1, 'a' + m2, 'a' + m3); + } + vblk->disk->major = major; - vblk->disk->first_minor = 0; + vblk->disk->first_minor = index_to_minor(index); vblk->disk->private_data = vblk; vblk->disk->fops = &virtblk_fops; + index++; /* If barriers are supported, tell block layer that queue is ordered */ - token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len); - if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER)) + if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); - err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); - if (err) { - dev_err(&vdev->dev, "Bad/missing capacity in config\n"); - goto out_cleanup_queue; - } + /* Host must always specify the capacity. */ + __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), + &cap); /* If capacity is too big, truncate with warning. */ if ((sector_t)cap != cap) { @@ -234,31 +256,25 @@ static int virtblk_probe(struct virtio_device *vdev) } set_capacity(vblk->disk, cap); - err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v); + /* Host can optionally specify maximum segment size and number of + * segments. */ + err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, + offsetof(struct virtio_blk_config, size_max), + &v); if (!err) blk_queue_max_segment_size(vblk->disk->queue, v); - else if (err != -ENOENT) { - dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); - goto out_cleanup_queue; - } - err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); + err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, + offsetof(struct virtio_blk_config, seg_max), + &v); if (!err) blk_queue_max_hw_segments(vblk->disk->queue, v); - else if (err != -ENOENT) { - dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); - goto out_cleanup_queue; - } add_disk(vblk->disk); return 0; -out_cleanup_queue: - blk_cleanup_queue(vblk->disk->queue); out_put_disk: put_disk(vblk->disk); -out_unregister_blkdev: - unregister_blkdev(major, "virtblk"); out_mempool: mempool_destroy(vblk->pool); out_free_vq: @@ -274,12 +290,16 @@ static void virtblk_remove(struct virtio_device *vdev) struct virtio_blk *vblk = vdev->priv; int major = vblk->disk->major; + /* Nothing should be pending. */ BUG_ON(!list_empty(&vblk->reqs)); + + /* Stop all the virtqueues. */ + vdev->config->reset(vdev); + blk_cleanup_queue(vblk->disk->queue); put_disk(vblk->disk); unregister_blkdev(major, "virtblk"); mempool_destroy(vblk->pool); - /* There should be nothing in the queue now, so no need to shutdown */ vdev->config->del_vq(vblk->vq); kfree(vblk); } @@ -299,11 +319,15 @@ static struct virtio_driver virtio_blk = { static int __init init(void) { + major = register_blkdev(0, "virtblk"); + if (major < 0) + return major; return register_virtio_driver(&virtio_blk); } static void __exit fini(void) { + unregister_blkdev(major, "virtblk"); unregister_virtio_driver(&virtio_blk); } module_init(init); |