diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/DAC960.c | 11 | ||||
-rw-r--r-- | drivers/block/Kconfig | 14 | ||||
-rw-r--r-- | drivers/block/aoe/aoeblk.c | 51 | ||||
-rw-r--r-- | drivers/block/aoe/aoechr.c | 7 | ||||
-rw-r--r-- | drivers/block/ataflop.c | 16 | ||||
-rw-r--r-- | drivers/block/cciss.c | 38 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 4 | ||||
-rw-r--r-- | drivers/block/cpqarray.c | 36 | ||||
-rw-r--r-- | drivers/block/floppy.c | 16 | ||||
-rw-r--r-- | drivers/block/loop.c | 8 | ||||
-rw-r--r-- | drivers/block/nbd.c | 23 | ||||
-rw-r--r-- | drivers/block/paride/pg.c | 6 | ||||
-rw-r--r-- | drivers/block/paride/pt.c | 14 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 31 | ||||
-rw-r--r-- | drivers/block/ps3disk.c | 12 | ||||
-rw-r--r-- | drivers/block/rd.c | 3 | ||||
-rw-r--r-- | drivers/block/sunvdc.c | 13 | ||||
-rw-r--r-- | drivers/block/sx8.c | 58 | ||||
-rw-r--r-- | drivers/block/ub.c | 33 | ||||
-rw-r--r-- | drivers/block/viodasd.c | 15 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 106 | ||||
-rw-r--r-- | drivers/block/xen-blkfront.c | 10 | ||||
-rw-r--r-- | drivers/block/xsysace.c | 9 |
23 files changed, 243 insertions, 291 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 9030c373ce67..cd03473f3547 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -3455,19 +3455,12 @@ static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, bool SuccessfulIO) { struct request *Request = Command->Request; - int UpToDate; - - UpToDate = 0; - if (SuccessfulIO) - UpToDate = 1; + int Error = SuccessfulIO ? 0 : -EIO; pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist, Command->SegmentCount, Command->DmaDirection); - if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { - add_disk_randomness(Request->rq_disk); - end_that_request_last(Request, UpToDate); - + if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) { if (Command->Completion) { complete(Command->Completion); Command->Completion = NULL; diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 4d0119ea9e35..64e5148d82bc 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -105,6 +105,17 @@ config PARIDE "MicroSolutions backpack protocol", "DataStor Commuter protocol" etc.). +config GDROM + tristate "SEGA Dreamcast GD-ROM drive" + depends on SH_DREAMCAST + help + A standard SEGA Dreamcast comes with a modified CD ROM drive called a + "GD-ROM" by SEGA to signify it is capable of reading special disks + with up to 1 GB of data. This drive will also read standard CD ROM + disks. Select this option to access any disks in your GD ROM drive. + Most users will want to say "Y" here. + You can also build this as a module which will be called gdrom.ko + source "drivers/block/paride/Kconfig" config BLK_CPQ_DA @@ -429,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/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index ad00b3d94711..826d12381e21 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -15,8 +15,10 @@ static struct kmem_cache *buf_pool_cache; -static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) +static ssize_t aoedisk_show_state(struct device *dev, + struct device_attribute *attr, char *page) { + struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; return snprintf(page, PAGE_SIZE, @@ -26,50 +28,47 @@ static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : ""); /* I'd rather see nopen exported so we can ditch closewait */ } -static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page) +static ssize_t aoedisk_show_mac(struct device *dev, + struct device_attribute *attr, char *page) { + struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; return snprintf(page, PAGE_SIZE, "%012llx\n", (unsigned long long)mac_addr(d->addr)); } -static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page) +static ssize_t aoedisk_show_netif(struct device *dev, + struct device_attribute *attr, char *page) { + struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name); } /* firmware version */ -static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page) +static ssize_t aoedisk_show_fwver(struct device *dev, + struct device_attribute *attr, char *page) { + struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver); } -static struct disk_attribute disk_attr_state = { - .attr = {.name = "state", .mode = S_IRUGO }, - .show = aoedisk_show_state -}; -static struct disk_attribute disk_attr_mac = { - .attr = {.name = "mac", .mode = S_IRUGO }, - .show = aoedisk_show_mac -}; -static struct disk_attribute disk_attr_netif = { - .attr = {.name = "netif", .mode = S_IRUGO }, - .show = aoedisk_show_netif -}; -static struct disk_attribute disk_attr_fwver = { - .attr = {.name = "firmware-version", .mode = S_IRUGO }, - .show = aoedisk_show_fwver +static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL); +static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL); +static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL); +static struct device_attribute dev_attr_firmware_version = { + .attr = { .name = "firmware-version", .mode = S_IRUGO, .owner = THIS_MODULE }, + .show = aoedisk_show_fwver, }; static struct attribute *aoe_attrs[] = { - &disk_attr_state.attr, - &disk_attr_mac.attr, - &disk_attr_netif.attr, - &disk_attr_fwver.attr, - NULL + &dev_attr_state.attr, + &dev_attr_mac.attr, + &dev_attr_netif.attr, + &dev_attr_firmware_version.attr, + NULL, }; static const struct attribute_group attr_group = { @@ -79,12 +78,12 @@ static const struct attribute_group attr_group = { static int aoedisk_add_sysfs(struct aoedev *d) { - return sysfs_create_group(&d->gd->kobj, &attr_group); + return sysfs_create_group(&d->gd->dev.kobj, &attr_group); } void aoedisk_rm_sysfs(struct aoedev *d) { - sysfs_remove_group(&d->gd->kobj, &attr_group); + sysfs_remove_group(&d->gd->dev.kobj, &attr_group); } static int diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 39e563ea0878..d5480e34cb22 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -259,9 +259,8 @@ aoechr_init(void) return PTR_ERR(aoe_class); } for (i = 0; i < ARRAY_SIZE(chardevs); ++i) - class_device_create(aoe_class, NULL, - MKDEV(AOE_MAJOR, chardevs[i].minor), - NULL, chardevs[i].name); + device_create(aoe_class, NULL, + MKDEV(AOE_MAJOR, chardevs[i].minor), chardevs[i].name); return 0; } @@ -272,7 +271,7 @@ aoechr_exit(void) int i; for (i = 0; i < ARRAY_SIZE(chardevs); ++i) - class_device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor)); + device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor)); class_destroy(aoe_class); unregister_chrdev(AOE_MAJOR, "aoechr"); } diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 94268c75d04f..424995073c6b 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 7d704968765f..9715be3f2487 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1187,17 +1187,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, } } -static inline void complete_buffers(struct bio *bio, int status) -{ - while (bio) { - struct bio *xbh = bio->bi_next; - - bio->bi_next = NULL; - bio_endio(bio, status ? 0 : -EIO); - bio = xbh; - } -} - static void cciss_check_queues(ctlr_info_t *h) { int start_queue = h->next_to_run; @@ -1263,21 +1252,14 @@ static void cciss_softirq_done(struct request *rq) pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); } - complete_buffers(rq->bio, (rq->errors == 0)); - - if (blk_fs_request(rq)) { - const int rw = rq_data_dir(rq); - - disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); - } - #ifdef CCISS_DEBUG printk("Done with %p\n", rq); #endif /* CCISS_DEBUG */ - add_disk_randomness(rq->rq_disk); + if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq))) + BUG(); + spin_lock_irqsave(&h->lock, flags); - end_that_request_last(rq, (rq->errors == 0)); cmd_free(h, cmd, 1); cciss_check_queues(h); spin_unlock_irqrestore(&h->lock, flags); @@ -2542,9 +2524,7 @@ after_error_processing: resend_cciss_cmd(h, cmd); return; } - cmd->rq->data_len = 0; cmd->rq->completion_data = cmd; - blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); blk_complete_request(cmd->rq); } @@ -2650,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; @@ -2927,7 +2909,7 @@ default_int_mode: return; } -static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) +static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) { ushort subsystem_vendor_id, subsystem_device_id, command; __u32 board_id, scratchpad = 0; diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 63ee6c076cb3..55178e9973a0 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/cpqarray.c b/drivers/block/cpqarray.c index c8132d958795..69199185ff4b 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -167,7 +167,6 @@ static void start_io(ctlr_info_t *h); static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); -static inline void complete_buffers(struct bio *bio, int ok); static inline void complete_command(cmdlist_t *cmd, int timeout); static irqreturn_t do_ida_intr(int irq, void *dev_id); @@ -980,26 +979,13 @@ static void start_io(ctlr_info_t *h) } } -static inline void complete_buffers(struct bio *bio, int ok) -{ - struct bio *xbh; - - while (bio) { - xbh = bio->bi_next; - bio->bi_next = NULL; - - bio_endio(bio, ok ? 0 : -EIO); - - bio = xbh; - } -} /* * Mark all buffers that cmd was responsible for */ static inline void complete_command(cmdlist_t *cmd, int timeout) { struct request *rq = cmd->rq; - int ok=1; + int error = 0; int i, ddir; if (cmd->req.hdr.rcode & RCODE_NONFATAL && @@ -1011,16 +997,17 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) if (cmd->req.hdr.rcode & RCODE_FATAL) { printk(KERN_WARNING "Fatal error on ida/c%dd%d\n", cmd->ctlr, cmd->hdr.unit); - ok = 0; + error = -EIO; } if (cmd->req.hdr.rcode & RCODE_INVREQ) { printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n", cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd, cmd->req.hdr.blk, cmd->req.hdr.blk_cnt, cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode); - ok = 0; + error = -EIO; } - if (timeout) ok = 0; + if (timeout) + error = -EIO; /* unmap the DMA mapping for all the scatter gather elements */ if (cmd->req.hdr.cmd == IDA_READ) ddir = PCI_DMA_FROMDEVICE; @@ -1030,18 +1017,9 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, cmd->req.sg[i].size, ddir); - complete_buffers(rq->bio, ok); - - if (blk_fs_request(rq)) { - const int rw = rq_data_dir(rq); - - disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); - } - - add_disk_randomness(rq->rq_disk); - DBGPX(printk("Done with %p\n", rq);); - end_that_request_last(rq, ok ? 1 : -EIO); + if (__blk_end_request(rq, error, blk_rq_bytes(rq))) + BUG(); } /* diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 639ed14bb08d..32c79a55511b 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -2287,21 +2287,19 @@ static int do_format(int drive, struct format_descr *tmp_format_req) * ============================= */ -static void floppy_end_request(struct request *req, int uptodate) +static void floppy_end_request(struct request *req, int error) { unsigned int nr_sectors = current_count_sectors; + unsigned int drive = (unsigned long)req->rq_disk->private_data; /* current_count_sectors can be zero if transfer failed */ - if (!uptodate) + if (error) nr_sectors = req->current_nr_sectors; - if (end_that_request_first(req, uptodate, nr_sectors)) + if (__blk_end_request(req, error, nr_sectors << 9)) return; - add_disk_randomness(req->rq_disk); - floppy_off((long)req->rq_disk->private_data); - blkdev_dequeue_request(req); - end_that_request_last(req, uptodate); /* We're done with the request */ + floppy_off(drive); current_req = NULL; } @@ -2332,7 +2330,7 @@ static void request_done(int uptodate) /* unlock chained buffers */ spin_lock_irqsave(q->queue_lock, flags); - floppy_end_request(req, 1); + floppy_end_request(req, 0); spin_unlock_irqrestore(q->queue_lock, flags); } else { if (rq_data_dir(req) == WRITE) { @@ -2346,7 +2344,7 @@ static void request_done(int uptodate) DRWE->last_error_generation = DRS->generation; } spin_lock_irqsave(q->queue_lock, flags); - floppy_end_request(req, 0); + floppy_end_request(req, -EIO); spin_unlock_irqrestore(q->queue_lock, flags); } } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b8af22e610df..91ebb007416c 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/nbd.c b/drivers/block/nbd.c index b4c0888aedc3..ae3106045ee5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -100,17 +100,15 @@ static const char *nbdcmd_to_ascii(int cmd) static void nbd_end_request(struct request *req) { - int uptodate = (req->errors == 0) ? 1 : 0; + int error = req->errors ? -EIO : 0; struct request_queue *q = req->q; unsigned long flags; dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, - req, uptodate? "done": "failed"); + req, error ? "failed" : "done"); spin_lock_irqsave(q->queue_lock, flags); - if (!end_that_request_first(req, uptodate, req->nr_sectors)) { - end_that_request_last(req, uptodate); - } + __blk_end_request(req, error, req->nr_sectors << 9); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -375,14 +373,17 @@ harderror: return NULL; } -static ssize_t pid_show(struct gendisk *disk, char *page) +static ssize_t pid_show(struct device *dev, + struct device_attribute *attr, char *buf) { - return sprintf(page, "%ld\n", + struct gendisk *disk = dev_to_disk(dev); + + return sprintf(buf, "%ld\n", (long) ((struct nbd_device *)disk->private_data)->pid); } -static struct disk_attribute pid_attr = { - .attr = { .name = "pid", .mode = S_IRUGO }, +static struct device_attribute pid_attr = { + .attr = { .name = "pid", .mode = S_IRUGO, .owner = THIS_MODULE }, .show = pid_show, }; @@ -394,7 +395,7 @@ static int nbd_do_it(struct nbd_device *lo) BUG_ON(lo->magic != LO_MAGIC); lo->pid = current->pid; - ret = sysfs_create_file(&lo->disk->kobj, &pid_attr.attr); + ret = sysfs_create_file(&lo->disk->dev.kobj, &pid_attr.attr); if (ret) { printk(KERN_ERR "nbd: sysfs_create_file failed!"); return ret; @@ -403,7 +404,7 @@ static int nbd_do_it(struct nbd_device *lo) while ((req = nbd_read_stat(lo)) != NULL) nbd_end_request(req); - sysfs_remove_file(&lo->disk->kobj, &pid_attr.attr); + sysfs_remove_file(&lo->disk->dev.kobj, &pid_attr.attr); return 0; } diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index d89e7d32a3b6..ab86e23ddc69 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -676,8 +676,8 @@ static int __init pg_init(void) for (unit = 0; unit < PG_UNITS; unit++) { struct pg *dev = &devices[unit]; if (dev->present) - class_device_create(pg_class, NULL, MKDEV(major, unit), - NULL, "pg%u", unit); + device_create(pg_class, NULL, MKDEV(major, unit), + "pg%u", unit); } err = 0; goto out; @@ -695,7 +695,7 @@ static void __exit pg_exit(void) for (unit = 0; unit < PG_UNITS; unit++) { struct pg *dev = &devices[unit]; if (dev->present) - class_device_destroy(pg_class, MKDEV(major, unit)); + device_destroy(pg_class, MKDEV(major, unit)); } class_destroy(pg_class); unregister_chrdev(major, name); diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index b91accf12656..8b9549ab4a4e 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; @@ -972,10 +972,10 @@ static int __init pt_init(void) for (unit = 0; unit < PT_UNITS; unit++) if (pt[unit].present) { - class_device_create(pt_class, NULL, MKDEV(major, unit), - NULL, "pt%d", unit); - class_device_create(pt_class, NULL, MKDEV(major, unit + 128), - NULL, "pt%dn", unit); + device_create(pt_class, NULL, MKDEV(major, unit), + "pt%d", unit); + device_create(pt_class, NULL, MKDEV(major, unit + 128), + "pt%dn", unit); } goto out; @@ -990,8 +990,8 @@ static void __exit pt_exit(void) int unit; for (unit = 0; unit < PT_UNITS; unit++) if (pt[unit].present) { - class_device_destroy(pt_class, MKDEV(major, unit)); - class_device_destroy(pt_class, MKDEV(major, unit + 128)); + device_destroy(pt_class, MKDEV(major, unit)); + device_destroy(pt_class, MKDEV(major, unit + 128)); } class_destroy(pt_class); unregister_chrdev(major, name); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3535ef896677..674cd66dcaba 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -110,17 +110,18 @@ static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd, struct kobj_type* ktype) { struct pktcdvd_kobj *p; + int error; + p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return NULL; - kobject_set_name(&p->kobj, "%s", name); - p->kobj.parent = parent; - p->kobj.ktype = ktype; p->pd = pd; - if (kobject_register(&p->kobj) != 0) { + error = kobject_init_and_add(&p->kobj, ktype, parent, "%s", name); + if (error) { kobject_put(&p->kobj); return NULL; } + kobject_uevent(&p->kobj, KOBJ_ADD); return p; } /* @@ -129,7 +130,7 @@ static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd, static void pkt_kobj_remove(struct pktcdvd_kobj *p) { if (p) - kobject_unregister(&p->kobj); + kobject_put(&p->kobj); } /* * default release function for pktcdvd kernel objects. @@ -301,18 +302,16 @@ static struct kobj_type kobj_pkt_type_wqueue = { static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) { if (class_pktcdvd) { - pd->clsdev = class_device_create(class_pktcdvd, - NULL, pd->pkt_dev, - NULL, "%s", pd->name); - if (IS_ERR(pd->clsdev)) - pd->clsdev = NULL; + pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, "%s", pd->name); + if (IS_ERR(pd->dev)) + pd->dev = NULL; } - if (pd->clsdev) { + if (pd->dev) { pd->kobj_stat = pkt_kobj_create(pd, "stat", - &pd->clsdev->kobj, + &pd->dev->kobj, &kobj_pkt_type_stat); pd->kobj_wqueue = pkt_kobj_create(pd, "write_queue", - &pd->clsdev->kobj, + &pd->dev->kobj, &kobj_pkt_type_wqueue); } } @@ -322,7 +321,7 @@ static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd) pkt_kobj_remove(pd->kobj_stat); pkt_kobj_remove(pd->kobj_wqueue); if (class_pktcdvd) - class_device_destroy(class_pktcdvd, pd->pkt_dev); + device_destroy(class_pktcdvd, pd->pkt_dev); } @@ -2213,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/ps3disk.c b/drivers/block/ps3disk.c index e354bfc070e1..7483f947f0e9 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -229,7 +229,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) struct ps3_storage_device *dev = data; struct ps3disk_private *priv; struct request *req; - int res, read, uptodate; + int res, read, error; u64 tag, status; unsigned long num_sectors; const char *op; @@ -270,21 +270,17 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) if (status) { dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, __LINE__, op, status); - uptodate = 0; + error = -EIO; } else { dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__, __LINE__, op); - uptodate = 1; + error = 0; if (read) ps3disk_scatter_gather(dev, req, 0); } spin_lock(&priv->lock); - if (!end_that_request_first(req, uptodate, num_sectors)) { - add_disk_randomness(req->rq_disk); - blkdev_dequeue_request(req); - end_that_request_last(req, uptodate); - } + __blk_end_request(req, error, num_sectors << 9); priv->req = NULL; ps3disk_do_request(dev, priv->queue); spin_unlock(&priv->lock); diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 82f4eecc8699..06e23be70904 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/sunvdc.c b/drivers/block/sunvdc.c index fac4c6cd04f7..a8de037ecd4a 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -212,12 +212,9 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc) vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); } -static void vdc_end_request(struct request *req, int uptodate, int num_sectors) +static void vdc_end_request(struct request *req, int error, int num_sectors) { - if (end_that_request_first(req, uptodate, num_sectors)) - return; - add_disk_randomness(req->rq_disk); - end_that_request_last(req, uptodate); + __blk_end_request(req, error, num_sectors << 9); } static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, @@ -242,7 +239,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, rqe->req = NULL; - vdc_end_request(req, !desc->status, desc->size >> 9); + vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9); if (blk_queue_stopped(port->disk->queue)) blk_start_queue(port->disk->queue); @@ -456,7 +453,7 @@ static void do_vdc_request(struct request_queue *q) blkdev_dequeue_request(req); if (__send_request(req) < 0) - vdc_end_request(req, 0, req->hard_nr_sectors); + vdc_end_request(req, -EIO, req->hard_nr_sectors); } } @@ -735,7 +732,7 @@ static struct vio_driver_ops vdc_vio_ops = { .handshake_complete = vdc_handshake_complete, }; -static void print_version(void) +static void __devinit print_version(void) { static int version_printed; diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 52dc5e131718..cd5674b63faf 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -744,16 +744,14 @@ static unsigned int carm_fill_get_fw_ver(struct carm_host *host, static inline void carm_end_request_queued(struct carm_host *host, struct carm_request *crq, - int uptodate) + int error) { struct request *req = crq->rq; int rc; - rc = end_that_request_first(req, uptodate, req->hard_nr_sectors); + rc = __blk_end_request(req, error, blk_rq_bytes(req)); assert(rc == 0); - end_that_request_last(req, uptodate); - rc = carm_put_request(host, crq); assert(rc == 0); } @@ -793,9 +791,9 @@ static inline void carm_round_robin(struct carm_host *host) } static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, - int is_ok) + int error) { - carm_end_request_queued(host, crq, is_ok); + carm_end_request_queued(host, crq, error); if (max_queue == 1) carm_round_robin(host); else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && @@ -873,14 +871,14 @@ queue_one_request: sg = &crq->sg[0]; n_elem = blk_rq_map_sg(q, rq, sg); if (n_elem <= 0) { - carm_end_rq(host, crq, 0); + carm_end_rq(host, crq, -EIO); return; /* request with no s/g entries? */ } /* map scatterlist to PCI bus addresses */ n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); if (n_elem <= 0) { - carm_end_rq(host, crq, 0); + carm_end_rq(host, crq, -EIO); return; /* request with no s/g entries? */ } crq->n_elem = n_elem; @@ -941,7 +939,7 @@ queue_one_request: static void carm_handle_array_info(struct carm_host *host, struct carm_request *crq, u8 *mem, - int is_ok) + int error) { struct carm_port *port; u8 *msg_data = mem + sizeof(struct carm_array_info); @@ -952,9 +950,9 @@ static void carm_handle_array_info(struct carm_host *host, DPRINTK("ENTER\n"); - carm_end_rq(host, crq, is_ok); + carm_end_rq(host, crq, error); - if (!is_ok) + if (error) goto out; if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) goto out; @@ -1001,7 +999,7 @@ out: static void carm_handle_scan_chan(struct carm_host *host, struct carm_request *crq, u8 *mem, - int is_ok) + int error) { u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; unsigned int i, dev_count = 0; @@ -1009,9 +1007,9 @@ static void carm_handle_scan_chan(struct carm_host *host, DPRINTK("ENTER\n"); - carm_end_rq(host, crq, is_ok); + carm_end_rq(host, crq, error); - if (!is_ok) { + if (error) { new_state = HST_ERROR; goto out; } @@ -1033,23 +1031,23 @@ out: } static void carm_handle_generic(struct carm_host *host, - struct carm_request *crq, int is_ok, + struct carm_request *crq, int error, int cur_state, int next_state) { DPRINTK("ENTER\n"); - carm_end_rq(host, crq, is_ok); + carm_end_rq(host, crq, error); assert(host->state == cur_state); - if (is_ok) - host->state = next_state; - else + if (error) host->state = HST_ERROR; + else + host->state = next_state; schedule_work(&host->fsm_task); } static inline void carm_handle_rw(struct carm_host *host, - struct carm_request *crq, int is_ok) + struct carm_request *crq, int error) { int pci_dir; @@ -1062,7 +1060,7 @@ static inline void carm_handle_rw(struct carm_host *host, pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); - carm_end_rq(host, crq, is_ok); + carm_end_rq(host, crq, error); } static inline void carm_handle_resp(struct carm_host *host, @@ -1071,7 +1069,7 @@ static inline void carm_handle_resp(struct carm_host *host, u32 handle = le32_to_cpu(ret_handle_le); unsigned int msg_idx; struct carm_request *crq; - int is_ok = (status == RMSG_OK); + int error = (status == RMSG_OK) ? 0 : -EIO; u8 *mem; VPRINTK("ENTER, handle == 0x%x\n", handle); @@ -1090,7 +1088,7 @@ static inline void carm_handle_resp(struct carm_host *host, /* fast path */ if (likely(crq->msg_type == CARM_MSG_READ || crq->msg_type == CARM_MSG_WRITE)) { - carm_handle_rw(host, crq, is_ok); + carm_handle_rw(host, crq, error); return; } @@ -1100,7 +1098,7 @@ static inline void carm_handle_resp(struct carm_host *host, case CARM_MSG_IOCTL: { switch (crq->msg_subtype) { case CARM_IOC_SCAN_CHAN: - carm_handle_scan_chan(host, crq, mem, is_ok); + carm_handle_scan_chan(host, crq, mem, error); break; default: /* unknown / invalid response */ @@ -1112,21 +1110,21 @@ static inline void carm_handle_resp(struct carm_host *host, case CARM_MSG_MISC: { switch (crq->msg_subtype) { case MISC_ALLOC_MEM: - carm_handle_generic(host, crq, is_ok, + carm_handle_generic(host, crq, error, HST_ALLOC_BUF, HST_SYNC_TIME); break; case MISC_SET_TIME: - carm_handle_generic(host, crq, is_ok, + carm_handle_generic(host, crq, error, HST_SYNC_TIME, HST_GET_FW_VER); break; case MISC_GET_FW_VER: { struct carm_fw_ver *ver = (struct carm_fw_ver *) mem + sizeof(struct carm_msg_get_fw_ver); - if (is_ok) { + if (!error) { host->fw_ver = le32_to_cpu(ver->version); host->flags |= (ver->features & FL_FW_VER_MASK); } - carm_handle_generic(host, crq, is_ok, + carm_handle_generic(host, crq, error, HST_GET_FW_VER, HST_PORT_SCAN); break; } @@ -1140,7 +1138,7 @@ static inline void carm_handle_resp(struct carm_host *host, case CARM_MSG_ARRAY: { switch (crq->msg_subtype) { case CARM_ARRAY_INFO: - carm_handle_array_info(host, crq, mem, is_ok); + carm_handle_array_info(host, crq, mem, error); break; default: /* unknown / invalid response */ @@ -1159,7 +1157,7 @@ static inline void carm_handle_resp(struct carm_host *host, err_out: printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", pci_name(host->pdev), crq->msg_type, crq->msg_subtype); - carm_end_rq(host, crq, 0); + carm_end_rq(host, crq, -EIO); } static inline void carm_handle_responses(struct carm_host *host) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 08e909dc7944..a70c1c29a7aa 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -808,16 +808,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) static void ub_end_rq(struct request *rq, unsigned int scsi_status) { - int uptodate; + int error; if (scsi_status == 0) { - uptodate = 1; + error = 0; } else { - uptodate = 0; + error = -EIO; rq->errors = scsi_status; } - end_that_request_first(rq, uptodate, rq->hard_nr_sectors); - end_that_request_last(rq, uptodate); + if (__blk_end_request(rq, error, blk_rq_bytes(rq))) + BUG(); } static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, @@ -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/viodasd.c b/drivers/block/viodasd.c index ab5d404faa11..9e61fca46117 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -229,13 +229,10 @@ static struct block_device_operations viodasd_fops = { /* * End a request */ -static void viodasd_end_request(struct request *req, int uptodate, +static void viodasd_end_request(struct request *req, int error, int num_sectors) { - if (end_that_request_first(req, uptodate, num_sectors)) - return; - add_disk_randomness(req->rq_disk); - end_that_request_last(req, uptodate); + __blk_end_request(req, error, num_sectors << 9); } /* @@ -374,12 +371,12 @@ static void do_viodasd_request(struct request_queue *q) blkdev_dequeue_request(req); /* check that request contains a valid command */ if (!blk_fs_request(req)) { - viodasd_end_request(req, 0, req->hard_nr_sectors); + viodasd_end_request(req, -EIO, req->hard_nr_sectors); continue; } /* Try sending the request */ if (send_request(req) != 0) - viodasd_end_request(req, 0, req->hard_nr_sectors); + viodasd_end_request(req, -EIO, req->hard_nr_sectors); } } @@ -591,7 +588,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent) num_req_outstanding--; spin_unlock_irqrestore(&viodasd_spinlock, irq_flags); - error = event->xRc != HvLpEvent_Rc_Good; + error = (event->xRc == HvLpEvent_Rc_Good) ? 0 : -EIO; if (error) { const struct vio_error_entry *err; err = vio_lookup_rc(viodasd_err_table, bevent->sub_result); @@ -601,7 +598,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent) } qlock = req->q->queue_lock; spin_lock_irqsave(qlock, irq_flags); - viodasd_end_request(req, !error, num_sect); + viodasd_end_request(req, error, num_sect); spin_unlock_irqrestore(qlock, irq_flags); /* Finally, try to get more requests off of this device's queue */ diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 924ddd8bccd2..3b1a68d6eddb 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); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2bdebcb3ff16..8afce67c0aa5 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -452,7 +452,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) RING_IDX i, rp; unsigned long flags; struct blkfront_info *info = (struct blkfront_info *)dev_id; - int uptodate; + int error; spin_lock_irqsave(&blkif_io_lock, flags); @@ -477,13 +477,13 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) add_id_to_freelist(info, id); - uptodate = (bret->status == BLKIF_RSP_OKAY); + error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; switch (bret->operation) { case BLKIF_OP_WRITE_BARRIER: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", info->gd->disk_name); - uptodate = -EOPNOTSUPP; + error = -EOPNOTSUPP; info->feature_barrier = 0; xlvbd_barrier(info); } @@ -494,10 +494,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " "request: %x\n", bret->status); - ret = end_that_request_first(req, uptodate, - req->hard_nr_sectors); + ret = __blk_end_request(req, error, blk_rq_bytes(req)); BUG_ON(ret); - end_that_request_last(req, uptodate); break; default: BUG(); diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 82effce97c51..78ebfffc77e3 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -483,7 +483,6 @@ static void ace_fsm_dostate(struct ace_device *ace) u32 status; u16 val; int count; - int i; #if defined(DEBUG) dev_dbg(ace->dev, "fsm_state=%i, id_req_count=%i\n", @@ -688,7 +687,6 @@ static void ace_fsm_dostate(struct ace_device *ace) } /* Transfer the next buffer */ - i = 16; if (ace->fsm_task == ACE_TASK_WRITE) ace->reg_ops->dataout(ace); else @@ -702,8 +700,8 @@ static void ace_fsm_dostate(struct ace_device *ace) } /* bio finished; is there another one? */ - i = ace->req->current_nr_sectors; - if (end_that_request_first(ace->req, 1, i)) { + if (__blk_end_request(ace->req, 0, + blk_rq_cur_bytes(ace->req))) { /* dev_dbg(ace->dev, "next block; h=%li c=%i\n", * ace->req->hard_nr_sectors, * ace->req->current_nr_sectors); @@ -718,9 +716,6 @@ static void ace_fsm_dostate(struct ace_device *ace) break; case ACE_FSM_STATE_REQ_COMPLETE: - /* Complete the block request */ - blkdev_dequeue_request(ace->req); - end_that_request_last(ace->req, 1); ace->req = NULL; /* Finished request; go to idle state */ |