diff options
Diffstat (limited to 'drivers/block')
32 files changed, 513 insertions, 456 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index a002a381df92..f6a337c34ac4 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -72,9 +72,9 @@ static long disk_size(DAC960_Controller_T *p, int drive_nr) } } -static int DAC960_open(struct inode *inode, struct file *file) +static int DAC960_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; DAC960_Controller_T *p = disk->queue->queuedata; int drive_nr = (long)disk->private_data; @@ -89,7 +89,7 @@ static int DAC960_open(struct inode *inode, struct file *file) return -ENXIO; } - check_disk_change(inode->i_bdev); + check_disk_change(bdev); if (!get_capacity(p->disks[drive_nr])) return -ENXIO; diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 61ad8d639ba3..0344a8a8321d 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -21,7 +21,8 @@ config BLK_DEV_FD ---help--- If you want to use the floppy disk drive(s) of your PC under Linux, say Y. Information about this driver, especially important for IBM - Thinkpad users, is contained in <file:Documentation/floppy.txt>. + Thinkpad users, is contained in + <file:Documentation/blockdev/floppy.txt>. That file also contains the location of the Floppy driver FAQ as well as location of the fdutils package used to configure additional parameters of the driver at run time. @@ -76,7 +77,7 @@ config PARIDE your computer's parallel port. Most of them are actually IDE devices using a parallel port IDE adapter. This option enables the PARIDE subsystem which contains drivers for many of these external drives. - Read <file:Documentation/paride.txt> for more information. + Read <file:Documentation/blockdev/paride.txt> for more information. If you have said Y to the "Parallel-port support" configuration option, you may share a single port between your printer and other @@ -114,9 +115,9 @@ config BLK_CPQ_DA help This is the driver for Compaq Smart Array controllers. Everyone using these boards should say Y here. See the file - <file:Documentation/cpqarray.txt> for the current list of boards - supported by this driver, and for further information on the use of - this driver. + <file:Documentation/blockdev/cpqarray.txt> for the current list of + boards supported by this driver, and for further information on the + use of this driver. config BLK_CPQ_CISS_DA tristate "Compaq Smart Array 5xxx support" @@ -124,7 +125,7 @@ config BLK_CPQ_CISS_DA help This is the driver for Compaq Smart Array 5xxx controllers. Everyone using these boards should say Y here. - See <file:Documentation/cciss.txt> for the current list of + See <file:Documentation/blockdev/cciss.txt> for the current list of boards supported by this driver, and for further information on the use of this driver. @@ -135,7 +136,7 @@ config CISS_SCSI_TAPE help When enabled (Y), this option allows SCSI tape drives and SCSI medium changers (tape robots) to be accessed via a Compaq 5xxx array - controller. (See <file:Documentation/cciss.txt> for more details.) + controller. (See <file:Documentation/blockdev/cciss.txt> for more details.) "SCSI support" and "SCSI tape support" must also be enabled for this option to work. @@ -149,8 +150,8 @@ config BLK_DEV_DAC960 help This driver adds support for the Mylex DAC960, AcceleRAID, and eXtremeRAID PCI RAID controllers. See the file - <file:Documentation/README.DAC960> for further information about - this driver. + <file:Documentation/blockdev/README.DAC960> for further information + about this driver. To compile this driver as a module, choose M here: the module will be called DAC960. @@ -278,9 +279,9 @@ config BLK_DEV_NBD userland (making server and client physically the same computer, communicating using the loopback network device). - Read <file:Documentation/nbd.txt> for more information, especially - about where to find the server code, which runs in user space and - does not need special kernel support. + Read <file:Documentation/blockdev/nbd.txt> for more information, + especially about where to find the server code, which runs in user + space and does not need special kernel support. Note that this has nothing to do with the network file systems NFS or Coda; you can say N here even if you intend to use NFS or Coda. @@ -321,8 +322,8 @@ config BLK_DEV_RAM store a copy of a minimal root file system off of a floppy into RAM during the initial install of Linux. - Note that the kernel command line option "ramdisk=XX" is now - obsolete. For details, read <file:Documentation/ramdisk.txt>. + Note that the kernel command line option "ramdisk=XX" is now obsolete. + For details, read <file:Documentation/blockdev/ramdisk.txt>. To compile this driver as a module, choose M here: the module will be called rd. diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 7516baff3bb9..4b1d4ac960f1 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1437,10 +1437,11 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int fd_ioctl(struct inode *inode, struct file *filp, +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { - int drive = iminor(inode) & 3; + struct amiga_floppy_struct *p = bdev->bd_disk->private_data; + int drive = p - unit; static struct floppy_struct getprm; void __user *argp = (void __user *)param; @@ -1451,7 +1452,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, rel_fdc(); return -EBUSY; } - fsync_bdev(inode->i_bdev); + fsync_bdev(bdev); if (fd_motor_on(drive) == 0) { rel_fdc(); return -ENODEV; @@ -1464,12 +1465,12 @@ static int fd_ioctl(struct inode *inode, struct file *filp, rel_fdc(); break; case FDFMTTRK: - if (param < unit[drive].type->tracks * unit[drive].type->heads) + if (param < p->type->tracks * p->type->heads) { get_fdc(drive); if (fd_seek(drive,param) != 0){ - memset(unit[drive].trackbuf, FD_FILL_BYTE, - unit[drive].dtype->sects * unit[drive].type->sect_mult * 512); + memset(p->trackbuf, FD_FILL_BYTE, + p->dtype->sects * p->type->sect_mult * 512); non_int_flush_track(drive); } floppy_off(drive); @@ -1480,14 +1481,14 @@ static int fd_ioctl(struct inode *inode, struct file *filp, break; case FDFMTEND: floppy_off(drive); - invalidate_bdev(inode->i_bdev); + invalidate_bdev(bdev); break; case FDGETPRM: memset((void *)&getprm, 0, sizeof (getprm)); - getprm.track=unit[drive].type->tracks; - getprm.head=unit[drive].type->heads; - getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult; - getprm.size=unit[drive].blocks; + getprm.track=p->type->tracks; + getprm.head=p->type->heads; + getprm.sect=p->dtype->sects * p->type->sect_mult; + getprm.size=p->blocks; if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct))) return -EFAULT; break; @@ -1500,10 +1501,10 @@ static int fd_ioctl(struct inode *inode, struct file *filp, break; #ifdef RAW_IOCTL case IOCTL_RAW_TRACK: - if (copy_to_user(argp, raw_buf, unit[drive].type->read_size)) + if (copy_to_user(argp, raw_buf, p->type->read_size)) return -EFAULT; else - return unit[drive].type->read_size; + return p->type->read_size; #endif default: printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.", @@ -1548,10 +1549,10 @@ static void fd_probe(int dev) * /dev/PS0 etc), and disallows simultaneous access to the same * drive with different device numbers. */ -static int floppy_open(struct inode *inode, struct file *filp) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - int drive = iminor(inode) & 3; - int system = (iminor(inode) & 4) >> 2; + int drive = MINOR(bdev->bd_dev) & 3; + int system = (MINOR(bdev->bd_dev) & 4) >> 2; int old_dev; unsigned long flags; @@ -1560,9 +1561,9 @@ static int floppy_open(struct inode *inode, struct file *filp) if (fd_ref[drive] && old_dev != system) return -EBUSY; - if (filp && filp->f_mode & 3) { - check_disk_change(inode->i_bdev); - if (filp->f_mode & 2 ) { + if (mode & (FMODE_READ|FMODE_WRITE)) { + check_disk_change(bdev); + if (mode & FMODE_WRITE) { int wrprot; get_fdc(drive); @@ -1592,9 +1593,10 @@ static int floppy_open(struct inode *inode, struct file *filp) return 0; } -static int floppy_release(struct inode * inode, struct file * filp) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - int drive = iminor(inode) & 3; + struct amiga_floppy_struct *p = disk->private_data; + int drive = p - unit; if (unit[drive].dirty == 1) { del_timer (flush_track_timer + drive); @@ -1650,7 +1652,7 @@ static struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .ioctl = fd_ioctl, + .locked_ioctl = fd_ioctl, .getgeo = fd_getgeo, .media_changed = amiga_floppy_change, }; diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 93f3690396a5..c237527b1aa5 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -200,4 +200,3 @@ void aoenet_xmit(struct sk_buff_head *); int is_aoe_netif(struct net_device *ifp); int set_aoe_iflist(const char __user *str, size_t size); -unsigned long long mac_addr(char addr[6]); diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index b82654e883a7..2307a271bdc9 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -37,7 +37,7 @@ static ssize_t aoedisk_show_mac(struct device *dev, if (t == NULL) return snprintf(page, PAGE_SIZE, "none\n"); - return snprintf(page, PAGE_SIZE, "%012llx\n", mac_addr(t->addr)); + return snprintf(page, PAGE_SIZE, "%pm\n", t->addr); } static ssize_t aoedisk_show_netif(struct device *dev, struct device_attribute *attr, char *page) @@ -90,7 +90,7 @@ 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 }, + .attr = { .name = "firmware-version", .mode = S_IRUGO }, .show = aoedisk_show_fwver, }; @@ -118,13 +118,11 @@ aoedisk_rm_sysfs(struct aoedev *d) } static int -aoeblk_open(struct inode *inode, struct file *filp) +aoeblk_open(struct block_device *bdev, fmode_t mode) { - struct aoedev *d; + struct aoedev *d = bdev->bd_disk->private_data; ulong flags; - d = inode->i_bdev->bd_disk->private_data; - spin_lock_irqsave(&d->lock, flags); if (d->flags & DEVFL_UP) { d->nopen++; @@ -136,13 +134,11 @@ aoeblk_open(struct inode *inode, struct file *filp) } static int -aoeblk_release(struct inode *inode, struct file *filp) +aoeblk_release(struct gendisk *disk, fmode_t mode) { - struct aoedev *d; + struct aoedev *d = disk->private_data; ulong flags; - d = inode->i_bdev->bd_disk->private_data; - spin_lock_irqsave(&d->lock, flags); if (--d->nopen == 0) { diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 1f56d2c5b7fc..200efc4d2c1e 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -284,9 +284,9 @@ aoechr_init(void) return PTR_ERR(aoe_class); } for (i = 0; i < ARRAY_SIZE(chardevs); ++i) - device_create_drvdata(aoe_class, NULL, - MKDEV(AOE_MAJOR, chardevs[i].minor), - NULL, chardevs[i].name); + device_create(aoe_class, NULL, + MKDEV(AOE_MAJOR, chardevs[i].minor), NULL, + chardevs[i].name); return 0; } diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 71ff78c9e4d6..45c5a33daf49 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -349,11 +349,9 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f) ah = (struct aoe_atahdr *) (h+1); snprintf(buf, sizeof buf, - "%15s e%ld.%d oldtag=%08x@%08lx newtag=%08x " - "s=%012llx d=%012llx nout=%d\n", + "%15s e%ld.%d oldtag=%08x@%08lx newtag=%08x s=%pm d=%pm nout=%d\n", "retransmit", d->aoemajor, d->aoeminor, f->tag, jiffies, n, - mac_addr(h->src), - mac_addr(h->dst), t->nout); + h->src, h->dst, t->nout); aoechr_error(buf); f->tag = n; @@ -544,10 +542,10 @@ rexmit_timer(ulong vp) printk(KERN_INFO "aoe: e%ld.%d: " "too many lost jumbo on " - "%s:%012llx - " + "%s:%pm - " "falling back to %d frames.\n", d->aoemajor, d->aoeminor, - ifp->nd->name, mac_addr(t->addr), + ifp->nd->name, t->addr, DEFAULTBCNT); ifp->maxbcnt = 0; } @@ -672,8 +670,8 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id) if (d->ssize != ssize) printk(KERN_INFO - "aoe: %012llx e%ld.%d v%04x has %llu sectors\n", - mac_addr(t->addr), + "aoe: %pm e%ld.%d v%04x has %llu sectors\n", + t->addr, d->aoemajor, d->aoeminor, d->fw_ver, (long long)ssize); d->ssize = ssize; @@ -775,8 +773,8 @@ aoecmd_ata_rsp(struct sk_buff *skb) n = get_unaligned_be32(&hin->tag); t = gettgt(d, hin->src); if (t == NULL) { - printk(KERN_INFO "aoe: can't find target e%ld.%d:%012llx\n", - d->aoemajor, d->aoeminor, mac_addr(hin->src)); + printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n", + d->aoemajor, d->aoeminor, hin->src); spin_unlock_irqrestore(&d->lock, flags); return; } @@ -1036,10 +1034,10 @@ aoecmd_cfg_rsp(struct sk_buff *skb) n = n ? n * 512 : DEFAULTBCNT; if (n != ifp->maxbcnt) { printk(KERN_INFO - "aoe: e%ld.%d: setting %d%s%s:%012llx\n", + "aoe: e%ld.%d: setting %d%s%s:%pm\n", d->aoemajor, d->aoeminor, n, " byte data frames on ", ifp->nd->name, - mac_addr(t->addr)); + t->addr); ifp->maxbcnt = n; } } diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 9157d64270cb..30de5b1c647e 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -83,17 +83,6 @@ set_aoe_iflist(const char __user *user_str, size_t size) return 0; } -unsigned long long -mac_addr(char addr[6]) -{ - __be64 n = 0; - char *p = (char *) &n; - - memcpy(p + 2, addr, 6); /* (sizeof addr != 6) */ - - return (unsigned long long) __be64_to_cpu(n); -} - void aoenet_xmit(struct sk_buff_head *queue) { diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 432cf4018291..69e1df7dfa14 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -361,13 +361,13 @@ static void finish_fdc( void ); static void finish_fdc_done( int dummy ); static void setup_req_params( int drive ); static void redo_fd_request( void); -static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param); static void fd_probe( int drive ); static int fd_test_drive_present( int drive ); static void config_types( void ); -static int floppy_open( struct inode *inode, struct file *filp ); -static int floppy_release( struct inode * inode, struct file * filp ); +static int floppy_open(struct block_device *bdev, fmode_t mode); +static int floppy_release(struct gendisk *disk, fmode_t mode); /************************* End of Prototypes **************************/ @@ -1483,10 +1483,10 @@ void do_fd_request(struct request_queue * q) atari_enable_irq( IRQ_MFP_FDC ); } -static int fd_ioctl(struct inode *inode, struct file *filp, +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; struct atari_floppy_struct *floppy = disk->private_data; int drive = floppy - unit; int type = floppy->type; @@ -1661,7 +1661,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, /* invalidate the buffer track to force a reread */ BufferDrive = -1; set_bit(drive, &fake_change); - check_disk_change(inode->i_bdev); + check_disk_change(bdev); return 0; default: return -EINVAL; @@ -1804,37 +1804,36 @@ static void __init config_types( void ) * drive with different device numbers. */ -static int floppy_open( struct inode *inode, struct file *filp ) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data; - int type = iminor(inode) >> 2; + struct atari_floppy_struct *p = bdev->bd_disk->private_data; + int type = MINOR(bdev->bd_dev) >> 2; DPRINT(("fd_open: type=%d\n",type)); if (p->ref && p->type != type) return -EBUSY; - if (p->ref == -1 || (p->ref && filp->f_flags & O_EXCL)) + if (p->ref == -1 || (p->ref && mode & FMODE_EXCL)) return -EBUSY; - if (filp->f_flags & O_EXCL) + if (mode & FMODE_EXCL) p->ref = -1; else p->ref++; p->type = type; - if (filp->f_flags & O_NDELAY) + if (mode & FMODE_NDELAY) return 0; - if (filp->f_mode & 3) { - check_disk_change(inode->i_bdev); - if (filp->f_mode & 2) { + if (mode & (FMODE_READ|FMODE_WRITE)) { + check_disk_change(bdev); + if (mode & FMODE_WRITE) { if (p->wpstat) { if (p->ref < 0) p->ref = 0; else p->ref--; - floppy_release(inode, filp); return -EROFS; } } @@ -1843,9 +1842,9 @@ static int floppy_open( struct inode *inode, struct file *filp ) } -static int floppy_release( struct inode * inode, struct file * filp ) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data; + struct atari_floppy_struct *p = disk->private_data; if (p->ref < 0) p->ref = 0; else if (!p->ref--) { @@ -1859,7 +1858,7 @@ static struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .ioctl = fd_ioctl, + .locked_ioctl = fd_ioctl, .media_changed = check_floppy_change, .revalidate_disk= floppy_revalidate, }; diff --git a/drivers/block/brd.c b/drivers/block/brd.c index d070d492e385..bdd4f5f45575 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -340,11 +340,10 @@ static int brd_direct_access (struct block_device *bdev, sector_t sector, } #endif -static int brd_ioctl(struct inode *inode, struct file *file, +static int brd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { int error; - struct block_device *bdev = inode->i_bdev; struct brd_device *brd = bdev->bd_disk->private_data; if (cmd != BLKFLSBUF) @@ -376,7 +375,7 @@ static int brd_ioctl(struct inode *inode, struct file *file, static struct block_device_operations brd_fops = { .owner = THIS_MODULE, - .ioctl = brd_ioctl, + .locked_ioctl = brd_ioctl, #ifdef CONFIG_BLK_DEV_XIP .direct_access = brd_direct_access, #endif diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1e1f9153000c..01e69383d9c0 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -96,6 +96,8 @@ static const struct pci_device_id cciss_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, {0,} @@ -133,6 +135,8 @@ static struct board_type products[] = { {0x3245103C, "Smart Array P410i", &SA5_access}, {0x3247103C, "Smart Array P411", &SA5_access}, {0x3249103C, "Smart Array P812", &SA5_access}, + {0x324A103C, "Smart Array P712m", &SA5_access}, + {0x324B103C, "Smart Array P711m", &SA5_access}, {0xFFFF103C, "Unknown Smart Array", &SA5_access}, }; @@ -152,15 +156,15 @@ static ctlr_info_t *hba[MAX_CTLR]; static void do_cciss_request(struct request_queue *q); static irqreturn_t do_cciss_intr(int irq, void *dev_id); -static int cciss_open(struct inode *inode, struct file *filep); -static int cciss_release(struct inode *inode, struct file *filep); -static int cciss_ioctl(struct inode *inode, struct file *filep, +static int cciss_open(struct block_device *bdev, fmode_t mode); +static int cciss_release(struct gendisk *disk, fmode_t mode); +static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int cciss_revalidate(struct gendisk *disk); static int rebuild_lun_table(ctlr_info_t *h, int first_time); -static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, +static int deregister_disk(ctlr_info_t *h, int drv_index, int clear_all); static void cciss_read_capacity(int ctlr, int logvol, int withirq, @@ -192,14 +196,15 @@ static void cciss_procinit(int i) #endif /* CONFIG_PROC_FS */ #ifdef CONFIG_COMPAT -static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +static int cciss_compat_ioctl(struct block_device *, fmode_t, + unsigned, unsigned long); #endif static struct block_device_operations cciss_fops = { .owner = THIS_MODULE, .open = cciss_open, .release = cciss_release, - .ioctl = cciss_ioctl, + .locked_ioctl = cciss_ioctl, .getgeo = cciss_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = cciss_compat_ioctl, @@ -210,31 +215,17 @@ static struct block_device_operations cciss_fops = { /* * Enqueuing and dequeuing functions for cmdlists. */ -static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c) +static inline void addQ(struct hlist_head *list, CommandList_struct *c) { - if (*Qptr == NULL) { - *Qptr = c; - c->next = c->prev = c; - } else { - c->prev = (*Qptr)->prev; - c->next = (*Qptr); - (*Qptr)->prev->next = c; - (*Qptr)->prev = c; - } + hlist_add_head(&c->list, list); } -static inline CommandList_struct *removeQ(CommandList_struct **Qptr, - CommandList_struct *c) +static inline void removeQ(CommandList_struct *c) { - if (c && c->next != c) { - if (*Qptr == c) - *Qptr = c->next; - c->prev->next = c->next; - c->next->prev = c->prev; - } else { - *Qptr = NULL; - } - return c; + if (WARN_ON(hlist_unhashed(&c->list))) + return; + + hlist_del_init(&c->list); } #include "cciss_scsi.c" /* For SCSI tape support */ @@ -501,6 +492,7 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) c->cmdindex = i; } + INIT_HLIST_NODE(&c->list); c->busaddr = (__u32) cmd_dma_handle; temp64.val = (__u64) err_dma_handle; c->ErrDesc.Addr.lower = temp64.val32.lower; @@ -547,13 +539,13 @@ static inline drive_info_struct *get_drv(struct gendisk *disk) /* * Open. Make sure the device is really there. */ -static int cciss_open(struct inode *inode, struct file *filep) +static int cciss_open(struct block_device *bdev, fmode_t mode) { - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); - drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(bdev->bd_disk); + drive_info_struct *drv = get_drv(bdev->bd_disk); #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name); + printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); #endif /* CCISS_DEBUG */ if (host->busy_initializing || drv->busy_configuring) @@ -567,9 +559,9 @@ static int cciss_open(struct inode *inode, struct file *filep) * for "raw controller". */ if (drv->heads == 0) { - if (iminor(inode) != 0) { /* not node 0? */ + if (MINOR(bdev->bd_dev) != 0) { /* not node 0? */ /* if not node 0 make sure it is a partition = 0 */ - if (iminor(inode) & 0x0f) { + if (MINOR(bdev->bd_dev) & 0x0f) { return -ENXIO; /* if it is, make sure we have a LUN ID */ } else if (drv->LunID == 0) { @@ -587,14 +579,13 @@ static int cciss_open(struct inode *inode, struct file *filep) /* * Close. Sync first. */ -static int cciss_release(struct inode *inode, struct file *filep) +static int cciss_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); - drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(disk); + drive_info_struct *drv = get_drv(disk); #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_release %s\n", - inode->i_bdev->bd_disk->disk_name); + printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name); #endif /* CCISS_DEBUG */ drv->usage_count--; @@ -604,21 +595,23 @@ static int cciss_release(struct inode *inode, struct file *filep) #ifdef CONFIG_COMPAT -static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg) +static int do_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { int ret; lock_kernel(); - ret = cciss_ioctl(f->f_path.dentry->d_inode, f, cmd, arg); + ret = cciss_ioctl(bdev, mode, cmd, arg); unlock_kernel(); return ret; } -static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, - unsigned long arg); -static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd, - unsigned long arg); +static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg); +static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg); -static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) +static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { switch (cmd) { case CCISS_GETPCIINFO: @@ -636,20 +629,20 @@ static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) case CCISS_REGNEWD: case CCISS_RESCANDISK: case CCISS_GETLUNINFO: - return do_ioctl(f, cmd, arg); + return do_ioctl(bdev, mode, cmd, arg); case CCISS_PASSTHRU32: - return cciss_ioctl32_passthru(f, cmd, arg); + return cciss_ioctl32_passthru(bdev, mode, cmd, arg); case CCISS_BIG_PASSTHRU32: - return cciss_ioctl32_big_passthru(f, cmd, arg); + return cciss_ioctl32_big_passthru(bdev, mode, cmd, arg); default: return -ENOIOCTLCMD; } } -static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, - unsigned long arg) +static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { IOCTL32_Command_struct __user *arg32 = (IOCTL32_Command_struct __user *) arg; @@ -676,7 +669,7 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, if (err) return -EFAULT; - err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long)p); + err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); if (err) return err; err |= @@ -687,8 +680,8 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, return err; } -static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, - unsigned long arg) +static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { BIG_IOCTL32_Command_struct __user *arg32 = (BIG_IOCTL32_Command_struct __user *) arg; @@ -717,7 +710,7 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, if (err) return -EFAULT; - err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long)p); + err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); if (err) return err; err |= @@ -745,10 +738,9 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) /* * ioctl */ -static int cciss_ioctl(struct inode *inode, struct file *filep, +static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct gendisk *disk = bdev->bd_disk; ctlr_info_t *host = get_host(disk); drive_info_struct *drv = get_drv(disk); @@ -1232,7 +1224,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case SG_EMULATED_HOST: case SG_IO: case SCSI_IOCTL_SEND_COMMAND: - return scsi_cmd_ioctl(filep, disk->queue, disk, cmd, argp); + return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); /* scsi_cmd_ioctl would normally handle these, below, but */ /* they aren't a good fit for cciss, as CD-ROMs are */ @@ -1365,6 +1357,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, disk->first_minor = drv_index << NWD_SHIFT; disk->fops = &cciss_fops; disk->private_data = &h->drv[drv_index]; + disk->driverfs_dev = &h->pdev->dev; /* Set up queue information */ blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); @@ -1486,8 +1479,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) * which keeps the interrupt handler from starting * the queue. */ - ret = deregister_disk(h->gendisk[drv_index], - &h->drv[drv_index], 0); + ret = deregister_disk(h, drv_index, 0); h->drv[drv_index].busy_configuring = 0; } @@ -1687,6 +1679,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) for (i = 0; i <= h->highest_lun; i++) { int j; drv_found = 0; + + /* skip holes in the array from already deleted drives */ + if (h->drv[i].raid_level == -1) + continue; + for (j = 0; j < num_luns; j++) { memcpy(&lunid, &ld_buff->LUN[j][0], 4); lunid = le32_to_cpu(lunid); @@ -1700,8 +1697,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); h->drv[i].busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return_code = deregister_disk(h->gendisk[i], - &h->drv[i], 1); + return_code = deregister_disk(h, i, 1); h->drv[i].busy_configuring = 0; } } @@ -1771,15 +1767,19 @@ mem_msg: * the highest_lun should be left unchanged and the LunID * should not be cleared. */ -static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, +static int deregister_disk(ctlr_info_t *h, int drv_index, int clear_all) { int i; - ctlr_info_t *h = get_host(disk); + struct gendisk *disk; + drive_info_struct *drv; if (!capable(CAP_SYS_RAWIO)) return -EPERM; + drv = &h->drv[drv_index]; + disk = h->gendisk[drv_index]; + /* make sure logical volume is NOT is use */ if (clear_all || (h->gendisk[0] == disk)) { if (drv->usage_count > 1) @@ -2537,7 +2537,8 @@ static void start_io(ctlr_info_t *h) { CommandList_struct *c; - while ((c = h->reqQ) != NULL) { + while (!hlist_empty(&h->reqQ)) { + c = hlist_entry(h->reqQ.first, CommandList_struct, list); /* can't do anything if fifo is full */ if ((h->access.fifo_full(h))) { printk(KERN_WARNING "cciss: fifo full\n"); @@ -2545,14 +2546,14 @@ static void start_io(ctlr_info_t *h) } /* Get the first entry from the Request Q */ - removeQ(&(h->reqQ), c); + removeQ(c); h->Qdepth--; /* Tell the controller execute command */ h->access.submit_command(h, c); /* Put job onto the completed Q */ - addQ(&(h->cmpQ), c); + addQ(&h->cmpQ, c); } } @@ -2565,7 +2566,7 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) memset(c->err_info, 0, sizeof(ErrorInfo_struct)); /* add it to software queue and then send it to the controller */ - addQ(&(h->reqQ), c); + addQ(&h->reqQ, c); h->Qdepth++; if (h->Qdepth > h->maxQsinceinit) h->maxQsinceinit = h->Qdepth; @@ -2841,7 +2842,7 @@ static void do_cciss_request(struct request_queue *q) h->maxSG = seg; #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n", + printk(KERN_DEBUG "cciss: Submitting %lu sectors in %d segments\n", creq->nr_sectors, seg); #endif /* CCISS_DEBUG */ @@ -2886,7 +2887,7 @@ static void do_cciss_request(struct request_queue *q) spin_lock_irq(q->queue_lock); - addQ(&(h->reqQ), c); + addQ(&h->reqQ, c); h->Qdepth++; if (h->Qdepth > h->maxQsinceinit) h->maxQsinceinit = h->Qdepth; @@ -2974,16 +2975,12 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) a = c->busaddr; } else { + struct hlist_node *tmp; + a &= ~3; - if ((c = h->cmpQ) == NULL) { - printk(KERN_WARNING - "cciss: Completion of %08x ignored\n", - a1); - continue; - } - while (c->busaddr != a) { - c = c->next; - if (c == h->cmpQ) + c = NULL; + hlist_for_each_entry(c, tmp, &h->cmpQ, list) { + if (c->busaddr == a) break; } } @@ -2991,8 +2988,8 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) * If we've found the command, take it off the * completion Q and free it */ - if (c->busaddr == a) { - removeQ(&h->cmpQ, c); + if (c && c->busaddr == a) { + removeQ(c); if (c->cmd_type == CMD_RWREQ) { complete_command(h, c, 0); } else if (c->cmd_type == CMD_IOCTL_PEND) { @@ -3191,7 +3188,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */ #ifdef CCISS_DEBUG - printk("address 0 = %x\n", c->paddr); + printk("address 0 = %lx\n", c->paddr); #endif /* CCISS_DEBUG */ c->vaddr = remap_pci_mem(c->paddr, 0x250); @@ -3218,7 +3215,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) #endif /* CCISS_DEBUG */ cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); #ifdef CCISS_DEBUG - printk("cfg base address index = %x\n", cfg_base_addr_index); + printk("cfg base address index = %llx\n", + (unsigned long long)cfg_base_addr_index); #endif /* CCISS_DEBUG */ if (cfg_base_addr_index == -1) { printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); @@ -3228,7 +3226,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); #ifdef CCISS_DEBUG - printk("cfg offset = %x\n", cfg_offset); + printk("cfg offset = %llx\n", (unsigned long long)cfg_offset); #endif /* CCISS_DEBUG */ c->cfgtable = remap_pci_mem(pci_resource_start(pdev, cfg_base_addr_index) + @@ -3403,13 +3401,16 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int i; int j = 0; int rc; - int dac; + int dac, return_code; + InquiryData_struct *inq_buff = NULL; i = alloc_cciss_hba(); if (i < 0) return -1; hba[i]->busy_initializing = 1; + INIT_HLIST_HEAD(&hba[i]->cmpQ); + INIT_HLIST_HEAD(&hba[i]->reqQ); if (cciss_pci_init(hba[i], pdev) != 0) goto clean1; @@ -3509,6 +3510,25 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, /* Turn the interrupts on so we can service requests */ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); + /* Get the firmware version */ + inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); + if (inq_buff == NULL) { + printk(KERN_ERR "cciss: out of memory\n"); + goto clean4; + } + + return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff, + sizeof(InquiryData_struct), 0, 0 , 0, TYPE_CMD); + if (return_code == IO_OK) { + hba[i]->firm_ver[0] = inq_buff->data_byte[32]; + hba[i]->firm_ver[1] = inq_buff->data_byte[33]; + hba[i]->firm_ver[2] = inq_buff->data_byte[34]; + hba[i]->firm_ver[3] = inq_buff->data_byte[35]; + } else { /* send command failed */ + printk(KERN_WARNING "cciss: unable to determine firmware" + " version of controller\n"); + } + cciss_procinit(i); hba[i]->cciss_max_sectors = 2048; @@ -3519,6 +3539,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, return 1; clean4: + kfree(inq_buff); #ifdef CONFIG_CISS_SCSI_TAPE kfree(hba[i]->scsi_rejects.complete); #endif @@ -3697,15 +3718,17 @@ static void fail_all_cmds(unsigned long ctlr) pci_disable_device(h->pdev); /* Make sure it is really dead. */ /* move everything off the request queue onto the completed queue */ - while ((c = h->reqQ) != NULL) { - removeQ(&(h->reqQ), c); + while (!hlist_empty(&h->reqQ)) { + c = hlist_entry(h->reqQ.first, CommandList_struct, list); + removeQ(c); h->Qdepth--; - addQ(&(h->cmpQ), c); + addQ(&h->cmpQ, c); } /* Now, fail everything on the completed queue with a HW error */ - while ((c = h->cmpQ) != NULL) { - removeQ(&h->cmpQ, c); + while (!hlist_empty(&h->cmpQ)) { + c = hlist_entry(h->cmpQ.first, CommandList_struct, list); + removeQ(c); c->err_info->CommandStatus = CMD_HARDWARE_ERR; if (c->cmd_type == CMD_RWREQ) { complete_command(h, c, 0); diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 24a7efa993ab..15e2b84734e3 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -89,8 +89,8 @@ struct ctlr_info struct access_method access; /* queue and queue Info */ - CommandList_struct *reqQ; - CommandList_struct *cmpQ; + struct hlist_head reqQ; + struct hlist_head cmpQ; unsigned int Qdepth; unsigned int maxQsinceinit; unsigned int maxSG; diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index 43bf5593b59b..24e22dea1a99 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -265,8 +265,7 @@ typedef struct _CommandList_struct { int ctlr; int cmd_type; long cmdindex; - struct _CommandList_struct *prev; - struct _CommandList_struct *next; + struct hlist_node list; struct request * rq; struct completion *waiting; int retry_count; diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 3d967525e9a9..5d39df14ed90 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -156,9 +156,9 @@ static int sendcmd( unsigned int blkcnt, unsigned int log_unit ); -static int ida_open(struct inode *inode, struct file *filep); -static int ida_release(struct inode *inode, struct file *filep); -static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); +static int ida_open(struct block_device *bdev, fmode_t mode); +static int ida_release(struct gendisk *disk, fmode_t mode); +static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); @@ -197,7 +197,7 @@ static struct block_device_operations ida_fops = { .owner = THIS_MODULE, .open = ida_open, .release = ida_release, - .ioctl = ida_ioctl, + .locked_ioctl = ida_ioctl, .getgeo = ida_getgeo, .revalidate_disk= ida_revalidate, }; @@ -567,7 +567,12 @@ static int __init cpqarray_init(void) num_cntlrs_reg++; } - return(num_cntlrs_reg); + if (num_cntlrs_reg) + return 0; + else { + pci_unregister_driver(&cpqarray_pci_driver); + return -ENODEV; + } } /* Function to find the first free pointer into our hba[] array */ @@ -818,12 +823,12 @@ DBGINFO( /* * Open. Make sure the device is really there. */ -static int ida_open(struct inode *inode, struct file *filep) +static int ida_open(struct block_device *bdev, fmode_t mode) { - drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + drv_info_t *drv = get_drv(bdev->bd_disk); + ctlr_info_t *host = get_host(bdev->bd_disk); - DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name)); + DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name)); /* * Root is allowed to open raw volume zero even if it's not configured * so array config can still work. I don't think I really like this, @@ -843,9 +848,9 @@ static int ida_open(struct inode *inode, struct file *filep) /* * Close. Sync first. */ -static int ida_release(struct inode *inode, struct file *filep) +static int ida_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(disk); host->usage_count--; return 0; } @@ -1128,10 +1133,10 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) * ida_ioctl does some miscellaneous stuff like reporting drive geometry, * setting readahead and submitting commands from userspace to the controller. */ -static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) +static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + drv_info_t *drv = get_drv(bdev->bd_disk); + ctlr_info_t *host = get_host(bdev->bd_disk); int error; ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; ida_ioctl_t *my_io; @@ -1165,7 +1170,7 @@ out_passthru: put_user(host->ctlr_sig, (int __user *)arg); return 0; case IDAREVALIDATEVOLS: - if (iminor(inode) != 0) + if (MINOR(bdev->bd_dev) != 0) return -ENXIO; return revalidate_allvol(host); case IDADRIVERVERSION: diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index cf64ddf5d839..cf29cc4e6ab7 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3450,14 +3450,14 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { -#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data) +#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)inode->i_bdev->bd_disk->private_data; + int drive = (long)bdev->bd_disk->private_data; int type = ITYPE(UDRS->fd_device); int i; int ret; @@ -3516,11 +3516,11 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, current_type[drive] = NULL; floppy_sizes[drive] = MAX_DISK_SIZE << 1; UDRS->keep_data = 0; - return invalidate_drive(inode->i_bdev); + return invalidate_drive(bdev); case FDSETPRM: case FDDEFPRM: return set_geometry(cmd, &inparam.g, - drive, type, inode->i_bdev); + drive, type, bdev); case FDGETPRM: ECALL(get_floppy_geometry(drive, type, (struct floppy_struct **) @@ -3551,7 +3551,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case FDFMTEND: case FDFLUSH: LOCK_FDC(drive, 1); - return invalidate_drive(inode->i_bdev); + return invalidate_drive(bdev); case FDSETEMSGTRESH: UDP->max_errors.reporting = @@ -3659,9 +3659,9 @@ static void __init config_types(void) printk("\n"); } -static int floppy_release(struct inode *inode, struct file *filp) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - int drive = (long)inode->i_bdev->bd_disk->private_data; + int drive = (long)disk->private_data; mutex_lock(&open_lock); if (UDRS->fd_ref < 0) @@ -3682,18 +3682,17 @@ static int floppy_release(struct inode *inode, struct file *filp) * /dev/PS0 etc), and disallows simultaneous access to the same * drive with different device numbers. */ -static int floppy_open(struct inode *inode, struct file *filp) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - int drive = (long)inode->i_bdev->bd_disk->private_data; - int old_dev; + int drive = (long)bdev->bd_disk->private_data; + int old_dev, new_dev; int try; int res = -EBUSY; char *tmp; - filp->private_data = (void *)0; mutex_lock(&open_lock); old_dev = UDRS->fd_device; - if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev) + if (opened_bdev[drive] && opened_bdev[drive] != bdev) goto out2; if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { @@ -3701,15 +3700,15 @@ static int floppy_open(struct inode *inode, struct file *filp) USETF(FD_VERIFY); } - if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) + if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) goto out2; - if (filp->f_flags & O_EXCL) + if (mode & FMODE_EXCL) UDRS->fd_ref = -1; else UDRS->fd_ref++; - opened_bdev[drive] = inode->i_bdev; + opened_bdev[drive] = bdev; res = -ENXIO; @@ -3744,31 +3743,26 @@ static int floppy_open(struct inode *inode, struct file *filp) } } - UDRS->fd_device = iminor(inode); - set_capacity(disks[drive], floppy_sizes[iminor(inode)]); - if (old_dev != -1 && old_dev != iminor(inode)) { + new_dev = MINOR(bdev->bd_dev); + UDRS->fd_device = new_dev; + set_capacity(disks[drive], floppy_sizes[new_dev]); + if (old_dev != -1 && old_dev != new_dev) { if (buffer_drive == drive) buffer_track = -1; } - /* Allow ioctls if we have write-permissions even if read-only open. - * Needed so that programs such as fdrawcmd still can work on write - * protected disks */ - if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE)) - filp->private_data = (void *)8; - if (UFDCS->rawcmd == 1) UFDCS->rawcmd = 2; - if (!(filp->f_flags & O_NDELAY)) { - if (filp->f_mode & 3) { + if (!(mode & FMODE_NDELAY)) { + if (mode & (FMODE_READ|FMODE_WRITE)) { UDRS->last_checked = 0; - check_disk_change(inode->i_bdev); + check_disk_change(bdev); if (UTESTF(FD_DISK_CHANGED)) goto out; } res = -EROFS; - if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE))) + if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE))) goto out; } mutex_unlock(&open_lock); @@ -3911,7 +3905,7 @@ static struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .ioctl = fd_ioctl, + .locked_ioctl = fd_ioctl, .getgeo = fd_getgeo, .media_changed = check_floppy_change, .revalidate_disk = floppy_revalidate, @@ -4130,7 +4124,7 @@ static int __init floppy_setup(char *str) printk("\n"); } else DPRINT("botched floppy option\n"); - DPRINT("Read Documentation/floppy.txt\n"); + DPRINT("Read Documentation/blockdev/floppy.txt\n"); return 0; } @@ -4172,7 +4166,7 @@ static int __init floppy_init(void) int i, unit, drive; int err, dr; -#if defined(CONFIG_PPC_MERGE) +#if defined(CONFIG_PPC) if (check_legacy_ioport(FDC1)) return -ENODEV; #endif diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d3a25b027ff9..edbaac6c0573 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -40,8 +40,7 @@ * Heinz Mauelshagen <mge@sistina.com>, Feb 2002 * * Support for falling back on the write file operation when the address space - * operations prepare_write and/or commit_write are not available on the - * backing filesystem. + * operations write_begin is not available on the backing filesystem. * Anton Altaparmakov, 16 Feb 2005 * * Still To Fix: @@ -210,7 +209,7 @@ lo_do_transfer(struct loop_device *lo, int cmd, * space operations write_begin and write_end. */ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, - int bsize, loff_t pos, struct page *unused) + loff_t pos, struct page *unused) { struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ struct address_space *mapping = file->f_mapping; @@ -302,7 +301,7 @@ static int __do_lo_send_write(struct file *file, * filesystems. */ static int do_lo_send_direct_write(struct loop_device *lo, - struct bio_vec *bvec, int bsize, loff_t pos, struct page *page) + struct bio_vec *bvec, loff_t pos, struct page *page) { ssize_t bw = __do_lo_send_write(lo->lo_backing_file, kmap(bvec->bv_page) + bvec->bv_offset, @@ -326,7 +325,7 @@ static int do_lo_send_direct_write(struct loop_device *lo, * destination pages of the backing file. */ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, - int bsize, loff_t pos, struct page *page) + loff_t pos, struct page *page) { int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, bvec->bv_offset, bvec->bv_len, pos >> 9); @@ -341,10 +340,9 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, return ret; } -static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, - loff_t pos) +static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos) { - int (*do_lo_send)(struct loop_device *, struct bio_vec *, int, loff_t, + int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t, struct page *page); struct bio_vec *bvec; struct page *page = NULL; @@ -362,7 +360,7 @@ static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, } } bio_for_each_segment(bvec, bio, i) { - ret = do_lo_send(lo, bvec, bsize, pos, page); + ret = do_lo_send(lo, bvec, pos, page); if (ret < 0) break; pos += bvec->bv_len; @@ -478,7 +476,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; if (bio_rw(bio) == WRITE) - ret = lo_send(lo, bio, lo->lo_blocksize, pos); + ret = lo_send(lo, bio, pos); else ret = lo_receive(lo, bio, lo->lo_blocksize, pos); return ret; @@ -626,20 +624,38 @@ static int loop_switch(struct loop_device *lo, struct file *file) } /* + * Helper to flush the IOs in loop, but keeping loop thread running + */ +static int loop_flush(struct loop_device *lo) +{ + /* loop not yet configured, no running thread, nothing to flush */ + if (!lo->lo_thread) + return 0; + + return loop_switch(lo, NULL); +} + +/* * Do the actual switch; called from the BIO completion routine */ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) { struct file *file = p->file; struct file *old_file = lo->lo_backing_file; - struct address_space *mapping = file->f_mapping; + struct address_space *mapping; + + /* if no new file, only flush of queued bios requested */ + if (!file) + goto out; + mapping = file->f_mapping; mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); lo->lo_backing_file = file; lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ? mapping->host->i_bdev->bd_block_size : PAGE_SIZE; lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); +out: complete(&p->wait); } @@ -652,8 +668,8 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) * This can only work if the loop device is used read-only, and if the * new backing store is the same size and type as the old backing store. */ -static int loop_change_fd(struct loop_device *lo, struct file *lo_file, - struct block_device *bdev, unsigned int arg) +static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + unsigned int arg) { struct file *file, *old_file; struct inode *inode; @@ -712,7 +728,7 @@ static inline int is_loop_device(struct file *file) return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } -static int loop_set_fd(struct loop_device *lo, struct file *lo_file, +static int loop_set_fd(struct loop_device *lo, fmode_t mode, struct block_device *bdev, unsigned int arg) { struct file *file, *f; @@ -740,7 +756,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, while (is_loop_device(f)) { struct loop_device *l; - if (f->f_mapping->host->i_rdev == lo_file->f_mapping->host->i_rdev) + if (f->f_mapping->host->i_bdev == bdev) goto out_putf; l = f->f_mapping->host->i_bdev->bd_disk->private_data; @@ -766,7 +782,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, */ if (!file->f_op->splice_read) goto out_putf; - if (aops->prepare_write || aops->write_begin) + if (aops->write_begin) lo_flags |= LO_FLAGS_USE_AOPS; if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) lo_flags |= LO_FLAGS_READ_ONLY; @@ -786,7 +802,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, goto out_putf; } - if (!(lo_file->f_mode & FMODE_WRITE)) + if (!(mode & FMODE_WRITE)) lo_flags |= LO_FLAGS_READ_ONLY; set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); @@ -903,6 +919,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) kthread_stop(lo->lo_thread); + lo->lo_queue->unplug_fn = NULL; lo->lo_backing_file = NULL; loop_release_xfer(lo); @@ -918,9 +935,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - invalidate_bdev(bdev); + if (bdev) + invalidate_bdev(bdev); set_capacity(lo->lo_disk, 0); - bd_set_size(bdev, 0); + if (bdev) + bd_set_size(bdev, 0); mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = Lo_unbound; fput(filp); @@ -936,8 +955,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) { int err; struct loop_func_table *xfer; + uid_t uid = current_uid(); - if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid && + if (lo->lo_encrypt_key_size && + lo->lo_key_owner != uid && !capable(CAP_SYS_ADMIN)) return -EPERM; if (lo->lo_state != Lo_bound) @@ -992,7 +1013,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) if (info->lo_encrypt_key_size) { memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, info->lo_encrypt_key_size); - lo->lo_key_owner = current->uid; + lo->lo_key_owner = uid; } return 0; @@ -1137,22 +1158,22 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { return err; } -static int lo_ioctl(struct inode * inode, struct file * file, +static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = bdev->bd_disk->private_data; int err; mutex_lock(&lo->lo_ctl_mutex); switch (cmd) { case LOOP_SET_FD: - err = loop_set_fd(lo, file, inode->i_bdev, arg); + err = loop_set_fd(lo, mode, bdev, arg); break; case LOOP_CHANGE_FD: - err = loop_change_fd(lo, file, inode->i_bdev, arg); + err = loop_change_fd(lo, bdev, arg); break; case LOOP_CLR_FD: - err = loop_clr_fd(lo, inode->i_bdev); + err = loop_clr_fd(lo, bdev); break; case LOOP_SET_STATUS: err = loop_set_status_old(lo, (struct loop_info __user *) arg); @@ -1292,10 +1313,10 @@ loop_get_status_compat(struct loop_device *lo, return err; } -static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = bdev->bd_disk->private_data; int err; switch(cmd) { @@ -1317,7 +1338,7 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a arg = (unsigned long) compat_ptr(arg); case LOOP_SET_FD: case LOOP_CHANGE_FD: - err = lo_ioctl(inode, file, cmd, arg); + err = lo_ioctl(bdev, mode, cmd, arg); break; default: err = -ENOIOCTLCMD; @@ -1327,9 +1348,9 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a } #endif -static int lo_open(struct inode *inode, struct file *file) +static int lo_open(struct block_device *bdev, fmode_t mode) { - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = bdev->bd_disk->private_data; mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; @@ -1338,16 +1359,30 @@ static int lo_open(struct inode *inode, struct file *file) return 0; } -static int lo_release(struct inode *inode, struct file *file) +static int lo_release(struct gendisk *disk, fmode_t mode) { - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = disk->private_data; 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); + if (--lo->lo_refcnt) + goto out; + if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { + /* + * In autoclear mode, stop the loop thread + * and remove configuration after last close. + */ + loop_clr_fd(lo, NULL); + } else { + /* + * Otherwise keep thread (if running) and config, + * but flush possible ongoing bios in thread. + */ + loop_flush(lo); + } + +out: mutex_unlock(&lo->lo_ctl_mutex); return 0; diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7b3351260d56..7bcc1d8bc967 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -391,7 +391,7 @@ static ssize_t pid_show(struct device *dev, } static struct device_attribute pid_attr = { - .attr = { .name = "pid", .mode = S_IRUGO, .owner = THIS_MODULE }, + .attr = { .name = "pid", .mode = S_IRUGO}, .show = pid_show, }; @@ -557,10 +557,11 @@ static void do_nbd_request(struct request_queue * q) } } -static int nbd_ioctl(struct inode *inode, struct file *file, +static int nbd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct nbd_device *lo = inode->i_bdev->bd_disk->private_data; + struct nbd_device *lo = bdev->bd_disk->private_data; + struct file *file; int error; struct request sreq ; struct task_struct *thread; @@ -612,8 +613,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, error = -EINVAL; file = fget(arg); if (file) { - struct block_device *bdev = inode->i_bdev; - inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; if (S_ISSOCK(inode->i_mode)) { lo->file = file; lo->sock = SOCKET_I(inode); @@ -628,14 +628,14 @@ static int nbd_ioctl(struct inode *inode, struct file *file, case NBD_SET_BLKSIZE: lo->blksize = arg; lo->bytesize &= ~(lo->blksize-1); - inode->i_bdev->bd_inode->i_size = lo->bytesize; - set_blocksize(inode->i_bdev, lo->blksize); + bdev->bd_inode->i_size = lo->bytesize; + set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_SET_SIZE: lo->bytesize = arg & ~(lo->blksize-1); - inode->i_bdev->bd_inode->i_size = lo->bytesize; - set_blocksize(inode->i_bdev, lo->blksize); + bdev->bd_inode->i_size = lo->bytesize; + set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_SET_TIMEOUT: @@ -643,8 +643,8 @@ static int nbd_ioctl(struct inode *inode, struct file *file, return 0; case NBD_SET_SIZE_BLOCKS: lo->bytesize = ((u64) arg) * lo->blksize; - inode->i_bdev->bd_inode->i_size = lo->bytesize; - set_blocksize(inode->i_bdev, lo->blksize); + bdev->bd_inode->i_size = lo->bytesize; + set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_DO_IT: @@ -666,10 +666,10 @@ static int nbd_ioctl(struct inode *inode, struct file *file, if (file) fput(file); lo->bytesize = 0; - inode->i_bdev->bd_inode->i_size = 0; + bdev->bd_inode->i_size = 0; set_capacity(lo->disk, 0); if (max_part > 0) - ioctl_by_bdev(inode->i_bdev, BLKRRPART, 0); + ioctl_by_bdev(bdev, BLKRRPART, 0); return lo->harderror; case NBD_CLEAR_QUE: /* @@ -680,7 +680,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, return 0; case NBD_PRINT_DEBUG: printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n", - inode->i_bdev->bd_disk->disk_name, + bdev->bd_disk->disk_name, lo->queue_head.next, lo->queue_head.prev, &lo->queue_head); return 0; @@ -691,7 +691,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, static struct block_device_operations nbd_fops = { .owner = THIS_MODULE, - .ioctl = nbd_ioctl, + .locked_ioctl = nbd_ioctl, }; /* @@ -722,7 +722,6 @@ static int __init nbd_init(void) for (i = 0; i < nbds_max; i++) { struct gendisk *disk = alloc_disk(1 << part_shift); - elevator_t *old_e; if (!disk) goto out; nbd_dev[i].disk = disk; @@ -736,11 +735,10 @@ static int __init nbd_init(void) put_disk(disk); goto out; } - old_e = disk->queue->elevator; - if (elevator_init(disk->queue, "deadline") == 0 || - elevator_init(disk->queue, "noop") == 0) { - elevator_exit(old_e); - } + /* + * Tell the block layer that we are not a rotational device + */ + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue); } if (register_blkdev(NBD_MAJOR, "nbd")) { diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index b8a994a2b013..e91d4b4b014f 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -223,23 +223,24 @@ static int pcd_warned; /* Have we logged a phase warning ? */ /* kernel glue structures */ -static int pcd_block_open(struct inode *inode, struct file *file) +static int pcd_block_open(struct block_device *bdev, fmode_t mode) { - struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_open(&cd->info, inode, file); + struct pcd_unit *cd = bdev->bd_disk->private_data; + return cdrom_open(&cd->info, bdev, mode); } -static int pcd_block_release(struct inode *inode, struct file *file) +static int pcd_block_release(struct gendisk *disk, fmode_t mode) { - struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_release(&cd->info, file); + struct pcd_unit *cd = disk->private_data; + cdrom_release(&cd->info, mode); + return 0; } -static int pcd_block_ioctl(struct inode *inode, struct file *file, +static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(file, &cd->info, inode, cmd, arg); + struct pcd_unit *cd = bdev->bd_disk->private_data; + return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); } static int pcd_block_media_changed(struct gendisk *disk) @@ -252,7 +253,7 @@ static struct block_device_operations pcd_bdops = { .owner = THIS_MODULE, .open = pcd_block_open, .release = pcd_block_release, - .ioctl = pcd_block_ioctl, + .locked_ioctl = pcd_block_ioctl, .media_changed = pcd_block_media_changed, }; diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 5fdfa7c888ce..9299455b0af6 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -728,9 +728,9 @@ static int pd_special_command(struct pd_unit *disk, /* kernel glue structures */ -static int pd_open(struct inode *inode, struct file *file) +static int pd_open(struct block_device *bdev, fmode_t mode) { - struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct pd_unit *disk = bdev->bd_disk->private_data; disk->access++; @@ -758,10 +758,10 @@ static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int pd_ioctl(struct inode *inode, struct file *file, +static int pd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct pd_unit *disk = bdev->bd_disk->private_data; switch (cmd) { case CDROMEJECT: @@ -773,9 +773,9 @@ static int pd_ioctl(struct inode *inode, struct file *file, } } -static int pd_release(struct inode *inode, struct file *file) +static int pd_release(struct gendisk *p, fmode_t mode) { - struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct pd_unit *disk = p->private_data; if (!--disk->access && disk->removable) pd_special_command(disk, pd_door_unlock); @@ -809,7 +809,7 @@ static struct block_device_operations pd_fops = { .owner = THIS_MODULE, .open = pd_open, .release = pd_release, - .ioctl = pd_ioctl, + .locked_ioctl = pd_ioctl, .getgeo = pd_getgeo, .media_changed = pd_check_media, .revalidate_disk= pd_revalidate diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index e7fe6ca97dd8..bef3b997ba3e 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -201,13 +201,13 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_READ_10 0x28 #define ATAPI_WRITE_10 0x2a -static int pf_open(struct inode *inode, struct file *file); +static int pf_open(struct block_device *bdev, fmode_t mode); static void do_pf_request(struct request_queue * q); -static int pf_ioctl(struct inode *inode, struct file *file, +static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); -static int pf_release(struct inode *inode, struct file *file); +static int pf_release(struct gendisk *disk, fmode_t mode); static int pf_detect(void); static void do_pf_read(void); @@ -266,7 +266,7 @@ static struct block_device_operations pf_fops = { .owner = THIS_MODULE, .open = pf_open, .release = pf_release, - .ioctl = pf_ioctl, + .locked_ioctl = pf_ioctl, .getgeo = pf_getgeo, .media_changed = pf_check_media, }; @@ -296,16 +296,16 @@ static void __init pf_init_units(void) } } -static int pf_open(struct inode *inode, struct file *file) +static int pf_open(struct block_device *bdev, fmode_t mode) { - struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; + struct pf_unit *pf = bdev->bd_disk->private_data; pf_identify(pf); if (pf->media_status == PF_NM) return -ENODEV; - if ((pf->media_status == PF_RO) && (file->f_mode & 2)) + if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) return -EROFS; pf->access++; @@ -333,9 +333,9 @@ static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; + struct pf_unit *pf = bdev->bd_disk->private_data; if (cmd != CDROMEJECT) return -EINVAL; @@ -346,9 +346,9 @@ static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un return 0; } -static int pf_release(struct inode *inode, struct file *file) +static int pf_release(struct gendisk *disk, fmode_t mode) { - struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; + struct pf_unit *pf = disk->private_data; if (pf->access <= 0) return -EINVAL; diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index d731ca42f802..9dfa27163001 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -686,9 +686,8 @@ static int __init pg_init(void) for (unit = 0; unit < PG_UNITS; unit++) { struct pg *dev = &devices[unit]; if (dev->present) - device_create_drvdata(pg_class, NULL, - MKDEV(major, unit), NULL, - "pg%u", unit); + device_create(pg_class, NULL, MKDEV(major, unit), NULL, + "pg%u", unit); } err = 0; goto out; diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 673b8b2fd337..1e4006e18f03 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -667,7 +667,7 @@ static int pt_open(struct inode *inode, struct file *file) goto out; err = -EROFS; - if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & 2)) + if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & FMODE_WRITE)) goto out; if (!(iminor(inode) & 128)) @@ -979,12 +979,10 @@ static int __init pt_init(void) for (unit = 0; unit < PT_UNITS; unit++) if (pt[unit].present) { - device_create_drvdata(pt_class, NULL, - MKDEV(major, unit), NULL, - "pt%d", unit); - device_create_drvdata(pt_class, NULL, - MKDEV(major, unit + 128), NULL, - "pt%dn", unit); + device_create(pt_class, NULL, MKDEV(major, unit), NULL, + "pt%d", unit); + device_create(pt_class, NULL, MKDEV(major, unit + 128), + NULL, "pt%dn", unit); } goto out; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 0e077150568b..dc7a8c352da2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -302,9 +302,8 @@ static struct kobj_type kobj_pkt_type_wqueue = { static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) { if (class_pktcdvd) { - pd->dev = device_create_drvdata(class_pktcdvd, NULL, - pd->pkt_dev, NULL, - "%s", pd->name); + pd->dev = device_create(class_pktcdvd, NULL, MKDEV(0, 0), NULL, + "%s", pd->name); if (IS_ERR(pd->dev)) pd->dev = NULL; } @@ -2321,7 +2320,7 @@ static int pkt_open_write(struct pktcdvd_device *pd) /* * called at open time. */ -static int pkt_open_dev(struct pktcdvd_device *pd, int write) +static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) { int ret; long lba; @@ -2333,7 +2332,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) * so bdget() can't fail. */ bdget(pd->bdev->bd_dev); - if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY))) + if ((ret = blkdev_get(pd->bdev, FMODE_READ))) goto out; if ((ret = bd_claim(pd->bdev, pd))) @@ -2382,7 +2381,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) out_unclaim: bd_release(pd->bdev); out_putdev: - blkdev_put(pd->bdev); + blkdev_put(pd->bdev, FMODE_READ); out: return ret; } @@ -2400,7 +2399,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); bd_release(pd->bdev); - blkdev_put(pd->bdev); + blkdev_put(pd->bdev, FMODE_READ); pkt_shrink_pktlist(pd); } @@ -2412,7 +2411,7 @@ static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) return pkt_devs[dev_minor]; } -static int pkt_open(struct inode *inode, struct file *file) +static int pkt_open(struct block_device *bdev, fmode_t mode) { struct pktcdvd_device *pd = NULL; int ret; @@ -2420,7 +2419,7 @@ static int pkt_open(struct inode *inode, struct file *file) VPRINTK(DRIVER_NAME": entering open\n"); mutex_lock(&ctl_mutex); - pd = pkt_find_dev_from_minor(iminor(inode)); + pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev)); if (!pd) { ret = -ENODEV; goto out; @@ -2429,20 +2428,20 @@ static int pkt_open(struct inode *inode, struct file *file) pd->refcnt++; if (pd->refcnt > 1) { - if ((file->f_mode & FMODE_WRITE) && + if ((mode & FMODE_WRITE) && !test_bit(PACKET_WRITABLE, &pd->flags)) { ret = -EBUSY; goto out_dec; } } else { - ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE); + ret = pkt_open_dev(pd, mode & FMODE_WRITE); if (ret) goto out_dec; /* * needed here as well, since ext2 (among others) may change * the blocksize at mount time */ - set_blocksize(inode->i_bdev, CD_FRAMESIZE); + set_blocksize(bdev, CD_FRAMESIZE); } mutex_unlock(&ctl_mutex); @@ -2456,9 +2455,9 @@ out: return ret; } -static int pkt_close(struct inode *inode, struct file *file) +static int pkt_close(struct gendisk *disk, fmode_t mode) { - struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; + struct pktcdvd_device *pd = disk->private_data; int ret = 0; mutex_lock(&ctl_mutex); @@ -2766,7 +2765,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) bdev = bdget(dev); if (!bdev) return -ENOMEM; - ret = blkdev_get(bdev, FMODE_READ, O_RDONLY | O_NONBLOCK); + ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY); if (ret) return ret; @@ -2791,19 +2790,28 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) return 0; out_mem: - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ | FMODE_NDELAY); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); return ret; } -static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; + struct pktcdvd_device *pd = bdev->bd_disk->private_data; - VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); + VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, + MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); switch (cmd) { + case CDROMEJECT: + /* + * The door gets locked when the device is opened, so we + * have to unlock it or else the eject command fails. + */ + if (pd->refcnt == 1) + pkt_lock_door(pd, 0); + /* fallthru */ /* * forward selected CDROM ioctls to CD-ROM, for UDF */ @@ -2812,16 +2820,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u case CDROM_LAST_WRITTEN: case CDROM_SEND_PACKET: case SCSI_IOCTL_SEND_COMMAND: - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); - - case CDROMEJECT: - /* - * The door gets locked when the device is opened, so we - * have to unlock it or else the eject command fails. - */ - if (pd->refcnt == 1) - pkt_lock_door(pd, 0); - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + return __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); default: VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); @@ -2850,7 +2849,7 @@ static struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .ioctl = pkt_ioctl, + .locked_ioctl = pkt_ioctl, .media_changed = pkt_media_changed, }; @@ -2976,7 +2975,7 @@ static int pkt_remove_dev(dev_t pkt_dev) pkt_debugfs_dev_remove(pd); pkt_sysfs_dev_remove(pd); - blkdev_put(pd->bdev); + blkdev_put(pd->bdev, FMODE_READ | FMODE_NDELAY); remove_proc_entry(pd->name, pkt_proc); DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name); diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 730ccea78e45..612965307ba0 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -244,10 +244,10 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state, int interruptible); static void release_drive(struct floppy_state *fs); static int fd_eject(struct floppy_state *fs); -static int floppy_ioctl(struct inode *inode, struct file *filp, +static int floppy_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param); -static int floppy_open(struct inode *inode, struct file *filp); -static int floppy_release(struct inode *inode, struct file *filp); +static int floppy_open(struct block_device *bdev, fmode_t mode); +static int floppy_release(struct gendisk *disk, fmode_t mode); static int floppy_check_change(struct gendisk *disk); static int floppy_revalidate(struct gendisk *disk); @@ -839,10 +839,10 @@ static int fd_eject(struct floppy_state *fs) static struct floppy_struct floppy_type = { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ -static int floppy_ioctl(struct inode *inode, struct file *filp, +static int floppy_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { - struct floppy_state *fs = inode->i_bdev->bd_disk->private_data; + struct floppy_state *fs = bdev->bd_disk->private_data; int err; if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)) @@ -868,9 +868,9 @@ static int floppy_ioctl(struct inode *inode, struct file *filp, return -ENOTTY; } -static int floppy_open(struct inode *inode, struct file *filp) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - struct floppy_state *fs = inode->i_bdev->bd_disk->private_data; + struct floppy_state *fs = bdev->bd_disk->private_data; struct swim3 __iomem *sw = fs->swim3; int n, err = 0; @@ -904,17 +904,17 @@ static int floppy_open(struct inode *inode, struct file *filp) swim3_action(fs, SETMFM); swim3_select(fs, RELAX); - } else if (fs->ref_count == -1 || filp->f_flags & O_EXCL) + } else if (fs->ref_count == -1 || mode & FMODE_EXCL) return -EBUSY; - if (err == 0 && (filp->f_flags & O_NDELAY) == 0 - && (filp->f_mode & 3)) { - check_disk_change(inode->i_bdev); + if (err == 0 && (mode & FMODE_NDELAY) == 0 + && (mode & (FMODE_READ|FMODE_WRITE))) { + check_disk_change(bdev); if (fs->ejected) err = -ENXIO; } - if (err == 0 && (filp->f_mode & 2)) { + if (err == 0 && (mode & FMODE_WRITE)) { if (fs->write_prot < 0) fs->write_prot = swim3_readbit(fs, WRITE_PROT); if (fs->write_prot) @@ -930,7 +930,7 @@ static int floppy_open(struct inode *inode, struct file *filp) return err; } - if (filp->f_flags & O_EXCL) + if (mode & FMODE_EXCL) fs->ref_count = -1; else ++fs->ref_count; @@ -938,9 +938,9 @@ static int floppy_open(struct inode *inode, struct file *filp) return 0; } -static int floppy_release(struct inode *inode, struct file *filp) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - struct floppy_state *fs = inode->i_bdev->bd_disk->private_data; + struct floppy_state *fs = disk->private_data; struct swim3 __iomem *sw = fs->swim3; if (fs->ref_count > 0 && --fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); @@ -1000,7 +1000,7 @@ static int floppy_revalidate(struct gendisk *disk) static struct block_device_operations floppy_fops = { .open = floppy_open, .release = floppy_release, - .ioctl = floppy_ioctl, + .locked_ioctl = floppy_ioctl, .media_changed = floppy_check_change, .revalidate_disk= floppy_revalidate, }; diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 3a281ef11ffa..048d71d244d7 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -349,8 +349,6 @@ struct ub_dev { struct work_struct reset_work; wait_queue_head_t reset_wait; - - int sg_stat[6]; }; /* @@ -685,7 +683,6 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) goto drop; } urq->nsg = n_elem; - sc->sg_stat[n_elem < 5 ? n_elem : 5]++; if (blk_pc_request(rq)) { ub_cmd_build_packet(sc, lun, cmd, urq); @@ -1549,8 +1546,6 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) /* * Reset management - * XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing. - * XXX Make usb_sync_reset asynchronous. */ static void ub_reset_enter(struct ub_dev *sc, int try) @@ -1636,6 +1631,22 @@ static void ub_reset_task(struct work_struct *work) } /* + * XXX Reset brackets are too much hassle to implement, so just stub them + * in order to prevent forced unbinding (which deadlocks solid when our + * ->disconnect method waits for the reset to complete and this kills keventd). + * + * XXX Tell Alan to move usb_unlock_device inside of usb_reset_device, + * or else the post_reset is invoked, and restats I/O on a locked device. + */ +static int ub_pre_reset(struct usb_interface *iface) { + return 0; +} + +static int ub_post_reset(struct usb_interface *iface) { + return 0; +} + +/* * This is called from a process context. */ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) @@ -1670,10 +1681,9 @@ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) * This is mostly needed to keep refcounting, but also to support * media checks on removable media drives. */ -static int ub_bd_open(struct inode *inode, struct file *filp) +static int ub_bd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_lun *lun = disk->private_data; + struct ub_lun *lun = bdev->bd_disk->private_data; struct ub_dev *sc = lun->udev; unsigned long flags; int rc; @@ -1687,19 +1697,19 @@ static int ub_bd_open(struct inode *inode, struct file *filp) spin_unlock_irqrestore(&ub_lock, flags); if (lun->removable || lun->readonly) - check_disk_change(inode->i_bdev); + check_disk_change(bdev); /* * The sd.c considers ->media_present and ->changed not equivalent, * under some pretty murky conditions (a failure of READ CAPACITY). * We may need it one day. */ - if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) { + if (lun->removable && lun->changed && !(mode & FMODE_NDELAY)) { rc = -ENOMEDIUM; goto err_open; } - if (lun->readonly && (filp->f_mode & FMODE_WRITE)) { + if (lun->readonly && (mode & FMODE_WRITE)) { rc = -EROFS; goto err_open; } @@ -1713,9 +1723,8 @@ err_open: /* */ -static int ub_bd_release(struct inode *inode, struct file *filp) +static int ub_bd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct ub_lun *lun = disk->private_data; struct ub_dev *sc = lun->udev; @@ -1726,13 +1735,13 @@ static int ub_bd_release(struct inode *inode, struct file *filp) /* * The ioctl interface. */ -static int ub_bd_ioctl(struct inode *inode, struct file *filp, +static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; void __user *usermem = (void __user *) arg; - return scsi_cmd_ioctl(filp, disk->queue, disk, cmd, usermem); + return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); } /* @@ -1796,7 +1805,7 @@ static struct block_device_operations ub_bd_fops = { .owner = THIS_MODULE, .open = ub_bd_open, .release = ub_bd_release, - .ioctl = ub_bd_ioctl, + .locked_ioctl = ub_bd_ioctl, .media_changed = ub_bd_media_changed, .revalidate_disk = ub_bd_revalidate, }; @@ -2451,6 +2460,8 @@ static struct usb_driver ub_driver = { .probe = ub_probe, .disconnect = ub_disconnect, .id_table = ub_usb_ids, + .pre_reset = ub_pre_reset, + .post_reset = ub_post_reset, }; static int __init ub_init(void) diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index f1c8feb5510b..ecccf65dce2f 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -130,15 +130,15 @@ struct viodasd_device { /* * External open entry point. */ -static int viodasd_open(struct inode *ino, struct file *fil) +static int viodasd_open(struct block_device *bdev, fmode_t mode) { - struct viodasd_device *d = ino->i_bdev->bd_disk->private_data; + struct viodasd_device *d = bdev->bd_disk->private_data; HvLpEvent_Rc hvrc; struct viodasd_waitevent we; u16 flags = 0; if (d->read_only) { - if ((fil != NULL) && (fil->f_mode & FMODE_WRITE)) + if (mode & FMODE_WRITE) return -EROFS; flags = vioblockflags_ro; } @@ -179,9 +179,9 @@ static int viodasd_open(struct inode *ino, struct file *fil) /* * External release entry point. */ -static int viodasd_release(struct inode *ino, struct file *fil) +static int viodasd_release(struct gendisk *disk, fmode_t mode) { - struct viodasd_device *d = ino->i_bdev->bd_disk->private_data; + struct viodasd_device *d = disk->private_data; HvLpEvent_Rc hvrc; /* Send the event to OS/400. We DON'T expect a response */ @@ -249,7 +249,6 @@ static int send_request(struct request *req) struct HvLpEvent *hev; struct scatterlist sg[VIOMAXBLOCKDMA]; int sgindex; - int statindex; struct viodasd_device *d; unsigned long flags; @@ -258,11 +257,9 @@ static int send_request(struct request *req) if (rq_data_dir(req) == READ) { direction = DMA_FROM_DEVICE; viocmd = viomajorsubtype_blockio | vioblockread; - statindex = 0; } else { direction = DMA_TO_DEVICE; viocmd = viomajorsubtype_blockio | vioblockwrite; - statindex = 1; } d = req->rq_disk->private_data; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 6ec5fc052786..5d34764c8a87 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -6,7 +6,6 @@ #include <linux/virtio_blk.h> #include <linux/scatterlist.h> -#define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) #define PART_BITS 4 static int major, index; @@ -26,8 +25,11 @@ struct virtio_blk mempool_t *pool; + /* What host tells us, plus 2 for header & tailer. */ + unsigned int sg_elems; + /* Scatterlist: can be too big for stack. */ - struct scatterlist sg[VIRTIO_MAX_SG]; + struct scatterlist sg[/*sg_elems*/]; }; struct virtblk_req @@ -97,8 +99,6 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, if (blk_barrier_rq(vbr->req)) vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; - /* This init could be done at vblk creation time */ - sg_init_table(vblk->sg, VIRTIO_MAX_SG); sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr)); num = blk_rq_map_sg(q, vbr->req, vblk->sg+1); sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status)); @@ -130,7 +130,7 @@ static void do_virtblk_request(struct request_queue *q) while ((req = elv_next_request(q)) != NULL) { vblk = req->rq_disk->private_data; - BUG_ON(req->nr_phys_segments > ARRAY_SIZE(vblk->sg)); + BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); /* If this request fails, stop queue and wait for something to finish to restart it. */ @@ -146,11 +146,11 @@ static void do_virtblk_request(struct request_queue *q) vblk->vq->vq_ops->kick(vblk->vq); } -static int virtblk_ioctl(struct inode *inode, struct file *filp, +static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { - return scsi_cmd_ioctl(filp, inode->i_bdev->bd_disk->queue, - inode->i_bdev->bd_disk, cmd, + return scsi_cmd_ioctl(bdev->bd_disk->queue, + bdev->bd_disk, mode, cmd, (void __user *)data); } @@ -180,7 +180,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) } static struct block_device_operations virtblk_fops = { - .ioctl = virtblk_ioctl, + .locked_ioctl = virtblk_ioctl, .owner = THIS_MODULE, .getgeo = virtblk_getgeo, }; @@ -196,12 +196,22 @@ static int virtblk_probe(struct virtio_device *vdev) int err; u64 cap; u32 v; - u32 blk_size; + u32 blk_size, sg_elems; if (index_to_minor(index) >= 1 << MINORBITS) return -ENOSPC; - vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); + /* We need to know how many segments before we allocate. */ + err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, + offsetof(struct virtio_blk_config, seg_max), + &sg_elems); + if (err) + sg_elems = 1; + + /* We need an extra sg elements at head and tail. */ + sg_elems += 2; + vdev->priv = vblk = kmalloc(sizeof(*vblk) + + sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL); if (!vblk) { err = -ENOMEM; goto out; @@ -210,6 +220,8 @@ static int virtblk_probe(struct virtio_device *vdev) INIT_LIST_HEAD(&vblk->reqs); spin_lock_init(&vblk->lock); vblk->vdev = vdev; + vblk->sg_elems = sg_elems; + sg_init_table(vblk->sg, vblk->sg_elems); /* We expect one virtqueue, for output. */ vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); @@ -237,6 +249,8 @@ static int virtblk_probe(struct virtio_device *vdev) goto out_put_disk; } + queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue); + if (index < 26) { sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); } else if (index < (26 + 1) * 26) { @@ -277,6 +291,13 @@ static int 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(vblk->disk->queue, vblk->sg_elems-2); + blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); + + /* No real sector limit. */ + blk_queue_max_sectors(vblk->disk->queue, -1U); + /* Host can optionally specify maximum segment size and number of * segments. */ err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, @@ -284,12 +305,8 @@ static int virtblk_probe(struct virtio_device *vdev) &v); if (!err) blk_queue_max_segment_size(vblk->disk->queue, 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 + blk_queue_max_segment_size(vblk->disk->queue, -1U); /* Host can optionally specify the block size of the device */ err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 624d30f7da3f..64b496fce98b 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -132,7 +132,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo); static struct block_device_operations xd_fops = { .owner = THIS_MODULE, - .ioctl = xd_ioctl, + .locked_ioctl = xd_ioctl, .getgeo = xd_getgeo, }; static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); @@ -343,7 +343,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /* xd_ioctl: handle device ioctl's */ -static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) +static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) { switch (cmd) { case HDIO_SET_DMA: diff --git a/drivers/block/xd.h b/drivers/block/xd.h index cffd44a20383..37cacef16e93 100644 --- a/drivers/block/xd.h +++ b/drivers/block/xd.h @@ -105,7 +105,7 @@ static u_char xd_detect (u_char *controller, unsigned int *address); static u_char xd_initdrives (void (*init_drive)(u_char drive)); static void do_xd_request (struct request_queue * q); -static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); +static int xd_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg); static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 1a50ae70f716..918ef725de41 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -156,11 +156,10 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) return 0; } -static int blkif_ioctl(struct inode *inode, struct file *filep, +static int blkif_ioctl(struct block_device *bdev, fmode_t mode, unsigned command, unsigned long argument) { - struct blkfront_info *info = - inode->i_bdev->bd_disk->private_data; + struct blkfront_info *info = bdev->bd_disk->private_data; int i; dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n", @@ -344,7 +343,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) if (rq == NULL) return -1; - elevator_init(rq, "noop"); + queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); /* Hard sector size and max sectors impersonate the equiv. hardware. */ blk_queue_hardsect_size(rq, sector_size); @@ -1014,16 +1013,16 @@ static int blkfront_is_ready(struct xenbus_device *dev) return info->is_ready; } -static int blkif_open(struct inode *inode, struct file *filep) +static int blkif_open(struct block_device *bdev, fmode_t mode) { - struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; + struct blkfront_info *info = bdev->bd_disk->private_data; info->users++; return 0; } -static int blkif_release(struct inode *inode, struct file *filep) +static int blkif_release(struct gendisk *disk, fmode_t mode) { - struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; + struct blkfront_info *info = disk->private_data; info->users--; if (info->users == 0) { /* Check whether we have been instructed to close. We will @@ -1044,7 +1043,7 @@ static struct block_device_operations xlvbd_block_fops = .open = blkif_open, .release = blkif_release, .getgeo = blkif_getgeo, - .ioctl = blkif_ioctl, + .locked_ioctl = blkif_ioctl, }; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 4a7a059ebaf7..29e1dfafb7c6 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -194,7 +194,7 @@ struct ace_device { int in_irq; /* Details of hardware device */ - unsigned long physaddr; + resource_size_t physaddr; void __iomem *baseaddr; int irq; int bus_width; /* 0 := 8 bit; 1 := 16 bit */ @@ -628,8 +628,8 @@ static void ace_fsm_dostate(struct ace_device *ace) /* Okay, it's a data request, set it up for transfer */ dev_dbg(ace->dev, - "request: sec=%lx hcnt=%lx, ccnt=%x, dir=%i\n", - req->sector, req->hard_nr_sectors, + "request: sec=%llx hcnt=%lx, ccnt=%x, dir=%i\n", + (unsigned long long) req->sector, req->hard_nr_sectors, req->current_nr_sectors, rq_data_dir(req)); ace->req = req; @@ -870,25 +870,24 @@ static int ace_revalidate_disk(struct gendisk *gd) return ace->id_result; } -static int ace_open(struct inode *inode, struct file *filp) +static int ace_open(struct block_device *bdev, fmode_t mode) { - struct ace_device *ace = inode->i_bdev->bd_disk->private_data; + struct ace_device *ace = bdev->bd_disk->private_data; unsigned long flags; dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1); - filp->private_data = ace; spin_lock_irqsave(&ace->lock, flags); ace->users++; spin_unlock_irqrestore(&ace->lock, flags); - check_disk_change(inode->i_bdev); + check_disk_change(bdev); return 0; } -static int ace_release(struct inode *inode, struct file *filp) +static int ace_release(struct gendisk *disk, fmode_t mode) { - struct ace_device *ace = inode->i_bdev->bd_disk->private_data; + struct ace_device *ace = disk->private_data; unsigned long flags; u16 val; @@ -936,7 +935,8 @@ static int __devinit ace_setup(struct ace_device *ace) int rc; dev_dbg(ace->dev, "ace_setup(ace=0x%p)\n", ace); - dev_dbg(ace->dev, "physaddr=0x%lx irq=%i\n", ace->physaddr, ace->irq); + dev_dbg(ace->dev, "physaddr=0x%llx irq=%i\n", + (unsigned long long)ace->physaddr, ace->irq); spin_lock_init(&ace->lock); init_completion(&ace->id_completion); @@ -1018,8 +1018,8 @@ static int __devinit ace_setup(struct ace_device *ace) /* Print the identification */ dev_info(ace->dev, "Xilinx SystemACE revision %i.%i.%i\n", (version >> 12) & 0xf, (version >> 8) & 0x0f, version & 0xff); - dev_dbg(ace->dev, "physaddr 0x%lx, mapped to 0x%p, irq=%i\n", - ace->physaddr, ace->baseaddr, ace->irq); + dev_dbg(ace->dev, "physaddr 0x%llx, mapped to 0x%p, irq=%i\n", + (unsigned long long) ace->physaddr, ace->baseaddr, ace->irq); ace->media_change = 1; ace_revalidate_disk(ace->gd); @@ -1036,8 +1036,8 @@ err_alloc_disk: err_blk_initq: iounmap(ace->baseaddr); err_ioremap: - dev_info(ace->dev, "xsysace: error initializing device at 0x%lx\n", - ace->physaddr); + dev_info(ace->dev, "xsysace: error initializing device at 0x%llx\n", + (unsigned long long) ace->physaddr); return -ENOMEM; } @@ -1060,7 +1060,7 @@ static void __devexit ace_teardown(struct ace_device *ace) } static int __devinit -ace_alloc(struct device *dev, int id, unsigned long physaddr, +ace_alloc(struct device *dev, int id, resource_size_t physaddr, int irq, int bus_width) { struct ace_device *ace; @@ -1120,7 +1120,7 @@ static void __devexit ace_free(struct device *dev) static int __devinit ace_probe(struct platform_device *dev) { - unsigned long physaddr = 0; + resource_size_t physaddr = 0; int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */ int id = dev->id; int irq = NO_IRQ; @@ -1166,7 +1166,7 @@ static int __devinit ace_of_probe(struct of_device *op, const struct of_device_id *match) { struct resource res; - unsigned long physaddr; + resource_size_t physaddr; const u32 *id; int irq, bus_width, rc; diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index be20a67f1fa8..80754cdd3119 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -137,8 +137,7 @@ get_chipram( void ) return; } -static int -z2_open( struct inode *inode, struct file *filp ) +static int z2_open(struct block_device *bdev, fmode_t mode) { int device; int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) * @@ -147,7 +146,7 @@ z2_open( struct inode *inode, struct file *filp ) sizeof( z2ram_map[0] ); int rc = -ENOMEM; - device = iminor(inode); + device = MINOR(bdev->bd_dev); if ( current_device != -1 && current_device != device ) { @@ -299,7 +298,7 @@ err_out: } static int -z2_release( struct inode *inode, struct file *filp ) +z2_release(struct gendisk *disk, fmode_t mode) { if ( current_device == -1 ) return 0; |