From d6d4f98075cfd83da1a25cfd6fe61a726b671080 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sat, 20 Jul 2002 20:47:24 -0700 Subject: [PATCH] Use wipe_partitions() where appropriate a bunch of places doing invalidate_device() either didn't need it at all or actually wanted wipe_partitions(). Switched. --- drivers/block/cciss.c | 21 +++------------------ drivers/block/umem.c | 36 +++++------------------------------- 2 files changed, 8 insertions(+), 49 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e06fd274b653..5f288efeab7e 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -860,18 +860,9 @@ static int deregister_disk(int ctlr, int logvol) /* invalidate the devices and deregister the disk */ max_p = 1 << gdev->minor_shift; start = logvol << gdev->minor_shift; + wipe_partitions(mk_kdev(MAJOR_NR+ctlr, start)); for (i=max_p-1; i>=0; i--) - { - int minor = start+i; - kdev_t kdev = mk_kdev(MAJOR_NR+ctlr, minor); - // printk("invalidating( %d %d)\n", ctlr, minor); - invalidate_device(kdev, 1); - /* so open will now fail */ - h->sizes[minor] = 0; - /* so it will no longer appear in /proc/partitions */ - gdev->part[minor].start_sect = 0; - gdev->part[minor].nr_sects = 0; - } + h->sizes[start + i] = 0; /* check to see if it was the last disk */ if (logvol == h->highest_lun) { @@ -1314,13 +1305,7 @@ static int register_new_disk(kdev_t dev, int ctlr) max_p = 1 << gdev->minor_shift; start = logvol<< gdev->minor_shift; - for(i=max_p-1; i>=0; i--) { - int minor = start+i; - kdev = mk_kdev(MAJOR_NR + ctlr, minor); - invalidate_device(kdev, 1); - gdev->part[minor].start_sect = 0; - gdev->part[minor].nr_sects = 0; - } + wipe_partitions(MAJOR_NR + ctlr, start); ++hba[ctlr]->num_luns; gdev->nr_real = hba[ctlr]->highest_lun + 1; diff --git a/drivers/block/umem.c b/drivers/block/umem.c index e046885bb67b..c2953c7afbc9 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -65,7 +65,7 @@ #define MM_BLKSIZE 1024 /* 1k blocks */ #define MM_HARDSECT 512 /* 512-byte hardware sectors */ #define MM_SHIFT 6 /* max 64 partitions on 4 cards */ -#define DEVICE_NR(device) (MINOR(device)>>MM_SHIFT) +#define DEVICE_NR(device) (minor(device)>>MM_SHIFT) /* * Version Information @@ -150,7 +150,6 @@ struct cardinfo { unsigned long last_change; } battery[2]; - atomic_t usage; spinlock_t lock; int check_batteries; @@ -818,7 +817,7 @@ static int mm_revalidate(kdev_t i_rdev) { int i; - int card_number = DEVICE_NR(kdev_val(i_rdev)); + int card_number = DEVICE_NR(i_rdev); /* first partition, # of partitions */ int part1 = (card_number << MM_SHIFT) + 1; int npart = (1 << MM_SHIFT) -1; @@ -905,7 +904,7 @@ static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned */ static int mm_check_change(kdev_t i_rdev) { - int card_number = DEVICE_NR(kdev_val(i_rdev)); + int card_number = DEVICE_NR(i_rdev); /* struct cardinfo *dev = cards + card_number; */ if (card_number >= num_cards) /* paranoid */ return 0; @@ -920,18 +919,8 @@ static int mm_check_change(kdev_t i_rdev) */ static int mm_open(struct inode *i, struct file *filp) { - int num; - struct cardinfo *card; - - num = DEVICE_NR(kdev_val(i->i_rdev)); - if (num >= num_cards) + if (DEVICE_NR(i->i_rdev) >= num_cards) return -ENXIO; - - card = cards + num; - - atomic_inc(&card->usage); - MOD_INC_USE_COUNT; - return 0; } /* @@ -941,17 +930,6 @@ static int mm_open(struct inode *i, struct file *filp) */ static int mm_do_release(struct inode *i, struct file *filp) { - int num; - struct cardinfo *card; - - num = DEVICE_NR(kdev_val(i->i_rdev)); - - card = cards + num; - - if (atomic_dec_and_test(&card->usage)) - invalidate_device(i->i_rdev, 1); - - MOD_DEC_USE_COUNT; return 0; } /* @@ -1243,7 +1221,7 @@ static struct pci_driver mm_pci_driver = { static request_queue_t * mm_queue_proc(kdev_t dev) { - int c = DEVICE_NR(kdev_val(dev)); + int c = DEVICE_NR(dev); if (c < MM_MAXCARDS) return &cards[c].queue; @@ -1293,7 +1271,6 @@ int __init mm_init(void) blk_dev[MAJOR_NR].queue = mm_queue_proc; add_gendisk(&mm_gendisk); - blk_size[MAJOR_NR] = mm_gendisk.sizes; for (i = 0; i < num_cards; i++) { register_disk(&mm_gendisk, mk_kdev(MAJOR_NR, i< Date: Sat, 20 Jul 2002 20:47:53 -0700 Subject: [PATCH] block device size cleanups for partitioned devices we use ->nr_sect to find the size; blk_size[] is still used for things like floppy.c, etc.; that will go away later. There was only one place (do_open()) that needed it - the rest uses ->bd_inode->i_size now. So blkdev_size_in_bytes() is gone - it's expanded in its only caller. Same place (do_open()) finds the partition offset and stores it in new field ->bd_offset. As the result, call of get_gendisk() is gone from the IO path - in blk_partition_remap() we just add ->bd_offset. Additionally, we take driver probing (get_blkfops()) outside of ->bd_sem (again, do_open()) - that will allow to kill ad-hackery in check_partitions() (opening bdev by hand). --- drivers/block/ll_rw_blk.c | 8 +------ fs/block_dev.c | 57 ++++++++++++++++++++++++++++------------------- include/linux/blkdev.h | 14 ------------ include/linux/fs.h | 1 + 4 files changed, 36 insertions(+), 44 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 48616f94f5ee..8ada278181c8 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1573,16 +1573,10 @@ end_io: static inline void blk_partition_remap(struct bio *bio) { struct block_device *bdev = bio->bi_bdev; - struct gendisk *g; - if (bdev == bdev->bd_contains) return; - g = get_gendisk(to_kdev_t(bdev->bd_dev)); - if (!g) - BUG(); - - bio->bi_sector += g->part[minor(to_kdev_t((bdev->bd_dev)))].start_sect; + bio->bi_sector += bdev->bd_offset; bio->bi_bdev = bdev->bd_contains; /* lots of checks are possible */ } diff --git a/fs/block_dev.c b/fs/block_dev.c index aa496e1bdd29..90c46b454f3c 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -37,14 +37,6 @@ static unsigned long max_block(struct block_device *bdev) return retval; } -static loff_t blkdev_size(kdev_t dev) -{ - loff_t sz = blkdev_size_in_bytes(dev); - if (sz) - return sz; - return ~0ULL; -} - /* Kill _all_ buffers, dirty or not.. */ static void kill_bdev(struct block_device *bdev) { @@ -538,17 +530,23 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * int ret = -ENXIO; kdev_t dev = to_kdev_t(bdev->bd_dev); struct module *owner = NULL; + struct block_device_operations *ops, *current_ops; - down(&bdev->bd_sem); lock_kernel(); - if (!bdev->bd_op) { - bdev->bd_op = get_blkfops(major(dev)); - if (!bdev->bd_op) - goto out; - owner = bdev->bd_op->owner; + ops = get_blkfops(major(dev)); + if (ops) { + owner = ops->owner; if (owner) __MOD_INC_USE_COUNT(owner); } + + down(&bdev->bd_sem); + if (!bdev->bd_op) + current_ops = ops; + else + current_ops = bdev->bd_op; + if (!current_ops) + goto out; if (!bdev->bd_contains) { unsigned minor = minor(dev); struct gendisk *g = get_gendisk(dev); @@ -569,15 +567,30 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } } } - if (bdev->bd_op->open) { - ret = bdev->bd_op->open(inode, file); + if (current_ops->open) { + ret = current_ops->open(inode, file); if (ret) goto out2; } - bdev->bd_inode->i_size = blkdev_size(dev); + if (!bdev->bd_op) + bdev->bd_op = ops; + else if (owner) + __MOD_DEC_USE_COUNT(owner); if (!bdev->bd_openers) { struct blk_dev_struct *p = blk_dev + major(dev); + struct gendisk *g = get_gendisk(dev); unsigned bsize = bdev_hardsect_size(bdev); + + bdev->bd_offset = 0; + if (g) { + bdev->bd_inode->i_size = + (loff_t) g->part[minor(dev)].nr_sects << 9; + bdev->bd_offset = g->part[minor(dev)].start_sect; + } else if (blk_size[major(dev)]) + bdev->bd_inode->i_size = + (loff_t) blk_size[major(dev)][minor(dev)] << 10; + else + bdev->bd_inode->i_size = 0; while (bsize < PAGE_CACHE_SIZE) { if (bdev->bd_inode->i_size & bsize) break; @@ -601,14 +614,12 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } } bdev->bd_openers++; - unlock_kernel(); up(&bdev->bd_sem); + unlock_kernel(); return 0; out2: if (!bdev->bd_openers) { - bdev->bd_op = NULL; - bdev->bd_queue = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; if (bdev != bdev->bd_contains) { blkdev_put(bdev->bd_contains, BDEV_RAW); @@ -619,8 +630,8 @@ out1: if (owner) __MOD_DEC_USE_COUNT(owner); out: - unlock_kernel(); up(&bdev->bd_sem); + unlock_kernel(); if (ret) bdput(bdev); return ret; @@ -679,9 +690,9 @@ int blkdev_put(struct block_device *bdev, int kind) kill_bdev(bdev); if (bdev->bd_op->release) ret = bdev->bd_op->release(bd_inode, NULL); - if (bdev->bd_op->owner) - __MOD_DEC_USE_COUNT(bdev->bd_op->owner); if (!bdev->bd_openers) { + if (bdev->bd_op->owner) + __MOD_DEC_USE_COUNT(bdev->bd_op->owner); bdev->bd_op = NULL; bdev->bd_queue = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 297cb0ba10c1..7460a98bb0b3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -389,20 +389,6 @@ extern inline unsigned int block_size(struct block_device *bdev) return bdev->bd_block_size; } -static inline loff_t blkdev_size_in_bytes(kdev_t dev) -{ -#if 0 - if (blk_size_in_bytes[major(dev)]) - return blk_size_in_bytes[major(dev)][minor(dev)]; - else -#endif - if (blk_size[major(dev)]) - return (loff_t) blk_size[major(dev)][minor(dev)] - << BLOCK_SIZE_BITS; - else - return 0; -} - typedef struct {struct page *v;} Sector; unsigned char *read_dev_sector(struct block_device *, unsigned long, Sector *); diff --git a/include/linux/fs.h b/include/linux/fs.h index 84413138923e..83f5a21b5d26 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -350,6 +350,7 @@ struct block_device { int bd_holders; struct block_device * bd_contains; unsigned bd_block_size; + unsigned long bd_offset; }; struct inode { -- cgit v1.2.3 From 81d4c00c63a03a1a2fa54c6a2fde84454550338c Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sat, 20 Jul 2002 20:48:09 -0700 Subject: [PATCH] partition handling locking cleanups Horrors with open/reread_partition exclusion are starting to get fixed. It's not the final variant, but at least we are getting the logics into one place; switch to final variant will happen once we get per-disk analog of gendisks. New fields - ->bd_part_sem and ->bd_part_count. The latter counts the amount of opened partitions. The former protects said count _and_ is held while we are rereading partition tables. Helpers - dev_part_lock()/dev_part_unlock() (currently taking kdev_t; that will change pretty soon). No more ->open() and ->release() for partitions, all that logics went to generic code. Lock hierachy is currently messy: ->bd_sem for partitions -> ->bd_part_sem -> ->bd_sem for entire disks Ugly, but that'll go away and to get the final variant of locking right now would take _really_ big patch - with a lot of steps glued together. The damn thing is large as it is... --- drivers/acorn/block/mfmhd.c | 52 +++++++-------------------------------- drivers/block/acsi.c | 36 +++++++-------------------- drivers/block/cciss.c | 9 ++++--- drivers/block/cpqarray.c | 3 +++ drivers/block/paride/pd.c | 42 ++++++++++++------------------- drivers/block/ps2esdi.c | 55 +++++++++-------------------------------- drivers/block/umem.c | 40 ++++++++---------------------- drivers/block/xd.c | 54 ++++++++++------------------------------ drivers/block/xd.h | 1 - drivers/ide/hd.c | 60 ++++++++------------------------------------- drivers/ide/ide.c | 3 --- drivers/ide/main.c | 29 ++++++++-------------- drivers/mtd/ftl.c | 41 ++++++++++++++----------------- drivers/mtd/nftlcore.c | 27 ++++++++++---------- drivers/scsi/sd.c | 31 ++++++----------------- fs/block_dev.c | 32 +++++++++++++++++------- fs/partitions/check.c | 25 +++---------------- include/linux/fs.h | 32 ++++++++++++++++++++++-- 18 files changed, 192 insertions(+), 380 deletions(-) (limited to 'drivers/block') diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c index 18a646b13141..5a209981436c 100644 --- a/drivers/acorn/block/mfmhd.c +++ b/drivers/acorn/block/mfmhd.c @@ -184,8 +184,6 @@ struct mfm_info { #define NEED_1_RECAL -2 #define NEED_2_RECAL -3 int cylinder; - unsigned int access_count; - unsigned int busy; struct { char recal; char report; @@ -197,7 +195,6 @@ struct mfm_info { static struct hd_struct mfm[MFM_MAXDRIVES << 6]; static int mfm_sizes[MFM_MAXDRIVES << 6]; -static DECLARE_WAIT_QUEUE_HEAD(mfm_wait_open); /* Stuff from the assembly routines */ extern unsigned int hdc63463_baseaddress; /* Controller base address */ @@ -1219,24 +1216,8 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a static int mfm_open(struct inode *inode, struct file *file) { int dev = DEVICE_NR(minor(inode->i_rdev)); - if (dev >= mfm_drives) return -ENODEV; - - while (mfm_info[dev].busy) - sleep_on (&mfm_wait_open); - - mfm_info[dev].access_count++; - return 0; -} - -/* - * Releasing a block device means we sync() it, so that it can safely - * be forgotten about... - */ -static int mfm_release(struct inode *inode, struct file *file) -{ - mfm_info[DEVICE_NR(minor(inode->i_rdev))].access_count--; return 0; } @@ -1296,7 +1277,6 @@ static struct block_device_operations mfm_fops = { owner: THIS_MODULE, open: mfm_open, - release: mfm_release, ioctl: mfm_ioctl, }; @@ -1425,33 +1405,19 @@ int mfm_init (void) /* * This routine is called to flush all partitions and partition tables * for a changed MFM disk, and then re-read the new partition table. - * If we are revalidating due to an ioctl, we have USAGE == 1. */ static int mfm_reread_partitions(kdev_t dev) { - unsigned int start, i, maxp, target = DEVICE_NR(minor(dev)); - unsigned long flags; - - local_irq_save(flags); - if (mfm_info[target].busy || mfm_info[target].access_count > 1) { - local_irq_restore (flags); - return -EBUSY; - } - mfm_info[target].busy = 1; - local_irq_restore (flags); - - maxp = 1 << mfm_gendisk.minor_shift; - start = target << mfm_gendisk.minor_shift; - - wipe_partitions(mk_kdev(MAJOR_NR, start)); - + unsigned int unit = DEVICE_NR(minor(dev)); + kdev_t device = mk_kdev(MAJOR_NR, unit << mfm_gendisk.minor_shift); + int err = dev_lock_part(device); + if (err) + return err; + wipe_partitions(device); /* Divide by 2, since sectors are 2 times smaller than usual ;-) */ - - grok_partitions(&mfm_gendisk, target, 1<<6, mfm_info[target].heads * - mfm_info[target].cylinders * mfm_info[target].sectors / 2); - - mfm_info[target].busy = 0; - wake_up (&mfm_wait_open); + grok_partitions(device, mfm_info[unit].heads * + mfm_info[unit].cylinders * mfm_info[unit].sectors / 2); + dev_unlock_part(device); return 0; } diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c index c35ef7f77e40..7ca3722d8ce9 100644 --- a/drivers/block/acsi.c +++ b/drivers/block/acsi.c @@ -248,8 +248,6 @@ static int NDevices = 0; static int acsi_sizes[MAX_DEV<<4] = { 0, }; static struct hd_struct acsi_part[MAX_DEV<<4] = { {0,0}, }; static int access_count[MAX_DEV] = { 0, }; -static char busy[MAX_DEV] = { 0, }; -static DECLARE_WAIT_QUEUE_HEAD(busy_wait); static int CurrentNReq; static int CurrentNSect; @@ -1161,8 +1159,6 @@ static int acsi_open( struct inode * inode, struct file * filp ) if (device >= NDevices) return -ENXIO; aip = &acsi_info[device]; - while (busy[device]) - sleep_on(&busy_wait); if (access_count[device] == 0 && aip->removable) { #if 0 @@ -1803,10 +1799,6 @@ void cleanup_module(void) } #endif -#define DEVICE_BUSY busy[device] -#define USAGE access_count[device] -#define GENDISK_STRUCT acsi_gendisk - /* * This routine is called to flush all partitions and partition tables * for a changed scsi disk, and then re-read the new partition table. @@ -1828,24 +1820,15 @@ void cleanup_module(void) static int revalidate_acsidisk( int dev, int maxusage ) { - int device; - struct gendisk * gdev; - int res; - struct acsi_info_struct *aip; - - device = DEVICE_NR(minor(dev)); - aip = &acsi_info[device]; - gdev = &GENDISK_STRUCT; + int unit = DEVICE_NR(minor(dev)); + struct acsi_info_struct *aip = &acsi_info[unit]; + kdev_t device = mk_kdev(MAJOR_NR, unit<<4); + int res = dev_lock_part(device); - cli(); - if (DEVICE_BUSY || USAGE > maxusage) { - sti(); - return -EBUSY; - }; - DEVICE_BUSY = 1; - sti(); + if (res < 0) + return res; - res = wipe_partitions(dev); + res = wipe_partitions(device); stdma_lock( NULL, NULL ); @@ -1862,10 +1845,9 @@ static int revalidate_acsidisk( int dev, int maxusage ) stdma_release(); if (!res) - grok_partitions(dev, aip->size); + grok_partitions(device, aip->size); - DEVICE_BUSY = 0; - wake_up(&busy_wait); + dev_unlock_part(device); return res; } diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 5f288efeab7e..8c7033f3220b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -735,6 +735,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, } /* Borrowed and adapted from sd.c */ +/* + * FIXME: we are missing the exclusion with ->open() here - it can happen + * just as we are rereading partition tables. + */ static int revalidate_logvol(kdev_t dev, int maxusage) { int ctlr, target; @@ -1304,13 +1308,12 @@ static int register_new_disk(kdev_t dev, int ctlr) hba[ctlr]->drv[logvol].usage_count = 0; max_p = 1 << gdev->minor_shift; start = logvol<< gdev->minor_shift; + kdev = mk_kdev(MAJOR_NR + ctlr, logvol<< gdev->minor_shift); - wipe_partitions(MAJOR_NR + ctlr, start); - + wipe_partitions(kdev); ++hba[ctlr]->num_luns; gdev->nr_real = hba[ctlr]->highest_lun + 1; /* setup partitions per disk */ - kdev = mk_kdev(MAJOR_NR + ctlr, logvol<< gdev->minor_shift); grok_partitions(kdev, hba[ctlr]->drv[logvol].nr_blocks); kfree(ld_buff); diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index fccef1bb792c..124cbf046ce3 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -1533,6 +1533,9 @@ static int revalidate_allvol(kdev_t dev) } /* Borrowed and adapted from sd.c */ +/* + * FIXME: exclusion with ->open() + */ static int revalidate_logvol(kdev_t dev, int maxusage) { int ctlr, target; diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index cb10da16d136..6e661e064da0 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -414,12 +414,11 @@ int pd_init (void) } static int pd_open (struct inode *inode, struct file *file) +{ + int unit = DEVICE_NR(inode->i_rdev); -{ int unit = DEVICE_NR(inode->i_rdev); - - if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV; - - wait_event (pd_wait_open, pd_valid); + if ((unit >= PD_UNITS) || (!PD.present)) + return -ENODEV; PD.access++; @@ -480,12 +479,8 @@ static int pd_ioctl(struct inode *inode,struct file *file, } static int pd_release (struct inode *inode, struct file *file) - -{ kdev_t devp; - int unit; - - devp = inode->i_rdev; - unit = DEVICE_NR(devp); +{ + int unit = DEVICE_NR(inode->i_rdev); if ((unit >= PD_UNITS) || (PD.access <= 0)) return -EINVAL; @@ -513,29 +508,22 @@ static int pd_check_media( kdev_t dev) static int pd_revalidate(kdev_t dev) { - int unit, res; - long flags; + int unit = DEVICE_NR(dev); + kdev_t device = mk_kdev(MAJOR_NR, unit << PD_BITS); + int res; - unit = DEVICE_NR(dev); if ((unit >= PD_UNITS) || !PD.present) return -ENODEV; - save_flags(flags); - cli(); - if (PD.access > 1) { - restore_flags(flags); - return -EBUSY; - } - pd_valid = 0; - restore_flags(flags); - - res = wipe_partitions(dev); + res = dev_part_lock(device); + if (res < 0) + return res; + res = wipe_partitions(device); if (res == 0 && pd_identify(unit)) - grok_partitions(dev, PD.capacity); + grok_partitions(device, PD.capacity); - pd_valid = 1; - wake_up(&pd_wait_open); + dev_unlock_part(device); return res; } diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c index bd604cee4663..65b7d9999e6c 100644 --- a/drivers/block/ps2esdi.c +++ b/drivers/block/ps2esdi.c @@ -93,8 +93,6 @@ static void ps2esdi_geometry_int_handler(u_int); static int ps2esdi_open(struct inode *inode, struct file *file); -static int ps2esdi_release(struct inode *inode, struct file *file); - static int ps2esdi_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg); @@ -111,11 +109,8 @@ static void ps2esdi_reset_timer(unsigned long unused); static u_int dma_arb_level; /* DMA arbitration level */ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int); -static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open); static int no_int_yet; -static int access_count[MAX_HD]; -static char ps2esdi_valid[MAX_HD]; static int ps2esdi_sizes[MAX_HD << 6]; static int ps2esdi_drives; static struct hd_struct ps2esdi[MAX_HD << 6]; @@ -152,7 +147,6 @@ static struct block_device_operations ps2esdi_fops = { owner: THIS_MODULE, open: ps2esdi_open, - release: ps2esdi_release, ioctl: ps2esdi_ioctl, }; @@ -441,13 +435,11 @@ static int __init ps2esdi_geninit(void) } blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 128); - for (i = 0; i < ps2esdi_drives; i++) { + for (i = 0; i < ps2esdi_drives; i++) register_disk(&ps2esdi_gendisk,mk_kdev(MAJOR_NR,i<<6),1<<6, &ps2esdi_fops, ps2esdi_info[i].head * ps2esdi_info[i].sect * ps2esdi_info[i].cyl); - ps2esdi_valid[i] = 1; - } return 0; err_out3: @@ -1083,32 +1075,11 @@ static void dump_cmd_complete_status(u_int int_ret_code) static int ps2esdi_open(struct inode *inode, struct file *file) { int dev = DEVICE_NR(inode->i_rdev); - - if (dev < ps2esdi_drives) { - while (!ps2esdi_valid[dev]) - sleep_on(&ps2esdi_wait_open); - - access_count[dev]++; - - return (0); - } else - return (-ENODEV); -} - - - -static int ps2esdi_release(struct inode *inode, struct file *file) -{ - int dev = DEVICE_NR(inode->i_rdev); - - if (dev < ps2esdi_drives) { - access_count[dev]--; - } + if (dev >= ps2esdi_drives) + return -ENODEV; return 0; } - - static int ps2esdi_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { @@ -1155,24 +1126,20 @@ static int ps2esdi_ioctl(struct inode *inode, static int ps2esdi_reread_partitions(kdev_t dev) { int target = DEVICE_NR(dev); - int res; + kdev_t device = mk_kdev(MAJOR_NR, target << 6); + int res = dev_lock_part(device); - cli(); - ps2esdi_valid[target] = (access_count[target] != 1); - sti(); - if (ps2esdi_valid[target]) - return (-EBUSY); + if (res < 0) + return res; - res = wipe_partitions(dev); + res = wipe_partitions(device); if (res == 0) - grok_partitions(dev, ps2esdi_info[target].head + grok_partitions(device, ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect); - ps2esdi_valid[target] = 1; - wake_up(&ps2esdi_wait_open); - - return (res); + dev_unlock_part(device); + return res; } static void ps2esdi_reset_timer(unsigned long unused) diff --git a/drivers/block/umem.c b/drivers/block/umem.c index c2953c7afbc9..719a7a6a6261 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -812,31 +812,21 @@ static void del_battery_timer(void) * Note no locks taken out here. In a worst case scenario, we could drop * a chunk of system memory. But that should never happen, since validation * happens at open or mount time, when locks are held. + * + * That's crap, since doing that while some partitions are opened + * or mounted will give you really nasty results. */ static int mm_revalidate(kdev_t i_rdev) { - int i; - int card_number = DEVICE_NR(i_rdev); - /* first partition, # of partitions */ - int part1 = (card_number << MM_SHIFT) + 1; - int npart = (1 << MM_SHIFT) -1; - - /* first clear old partition information */ - for (i=0; ii_rdev); - - if (dev < xd_drives) { - while (!xd_valid[dev]) - sleep_on(&xd_wait_open); - - xd_access[dev]++; - - return (0); - } - - return -ENXIO; + if (dev >= xd_drives) + return -ENXIO; + return 0; } /* do_xd_request: handle an incoming request */ @@ -364,37 +350,23 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) } } -/* xd_release: release the device */ -static int xd_release (struct inode *inode, struct file *file) -{ - int target = DEVICE_NR(inode->i_rdev); - if (target < xd_drives) - xd_access[target]--; - return 0; -} - /* xd_reread_partitions: rereads the partition table from a drive */ static int xd_reread_partitions(kdev_t dev) { - int target; - int res; + int target = DEVICE_NR(dev); + kdev_t device = mk_kdev(MAJOR_NR, target << 6); + int res = dev_lock_part(device); - target = DEVICE_NR(dev); - - cli(); - xd_valid[target] = (xd_access[target] != 1); - sti(); - if (xd_valid[target]) - return -EBUSY; + if (res < 0) + return 0; - res = wipe_partitions(dev); + res = wipe_partitions(device); if (!res) - grok_partitions(dev, xd_info[target].heads + grok_partitions(device, xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors); - xd_valid[target] = 1; - wake_up(&xd_wait_open); + dev_unlock_part(device); return res; } diff --git a/drivers/block/xd.h b/drivers/block/xd.h index 7babb59b96d0..3df2d4e98410 100644 --- a/drivers/block/xd.h +++ b/drivers/block/xd.h @@ -113,7 +113,6 @@ static void xd_geninit (void); static int xd_open (struct inode *inode,struct file *file); static void do_xd_request (request_queue_t * q); static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); -static int xd_release (struct inode *inode,struct file *file); static int xd_reread_partitions (kdev_t dev); static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c index a34945a2382f..689933665d17 100644 --- a/drivers/ide/hd.c +++ b/drivers/ide/hd.c @@ -83,9 +83,6 @@ static void bad_rw_intr(void); static char recalibrate[MAX_HD]; static char special_op[MAX_HD]; -static int access_count[MAX_HD]; -static char busy[MAX_HD]; -static DECLARE_WAIT_QUEUE_HEAD(busy_wait); static int reset; static int hd_error; @@ -668,14 +665,9 @@ static int hd_ioctl(struct inode * inode, struct file * file, static int hd_open(struct inode * inode, struct file * filp) { - int target; - target = DEVICE_NR(inode->i_rdev); - + int target = DEVICE_NR(inode->i_rdev); if (target >= NR_HD) return -ENODEV; - while (busy[target]) - sleep_on(&busy_wait); - access_count[target]++; return 0; } @@ -683,12 +675,6 @@ static int hd_open(struct inode * inode, struct file * filp) * Releasing a block device means we sync() it, so that it can safely * be forgotten about... */ -static int hd_release(struct inode * inode, struct file * file) -{ - int target = DEVICE_NR(inode->i_rdev); - access_count[target]--; - return 0; -} extern struct block_device_operations hd_fops; @@ -715,7 +701,6 @@ static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct block_device_operations hd_fops = { .open = hd_open, - .release = hd_release, .ioctl = hd_ioctl, }; @@ -854,13 +839,9 @@ int __init hd_init(void) return 0; } -#define DEVICE_BUSY busy[target] -#define USAGE access_count[target] #define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl) /* We assume that the BIOS parameters do not change, so the disk capacity will not change */ -#undef MAYBE_REINIT -#define GENDISK_STRUCT hd_gendisk /* * This routine is called to flush all partitions and partition tables @@ -872,36 +853,15 @@ int __init hd_init(void) */ static int revalidate_hddisk(kdev_t dev, int maxusage) { - int target; - struct gendisk * gdev; - int res; - long flags; - - target = DEVICE_NR(dev); - gdev = &GENDISK_STRUCT; - - save_flags(flags); - cli(); - if (DEVICE_BUSY || USAGE > maxusage) { - restore_flags(flags); - return -EBUSY; - } - DEVICE_BUSY = 1; - restore_flags(flags); - - res = wipe_partitions(dev); - if (res) - goto leave; - -#ifdef MAYBE_REINIT - MAYBE_REINIT; -#endif - - grok_partitions(dev, CAPACITY); - -leave: - DEVICE_BUSY = 0; - wake_up(&busy_wait); + int target = DEVICE_NR(dev); + kdev_t device = mk_kdev(MAJOR_NR, target << 6); + int res = dev_lock_part(device); + if (res < 0) + return res; + res = wipe_partitions(device); + if (!res) + grok_partitions(device, CAPACITY); + dev_unlock_part(device); return res; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index a83f8e7ee6d6..ce566e1b0645 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1105,9 +1105,6 @@ static int ide_open(struct inode * inode, struct file * filp) if (drive->driver == NULL) ide_driver_module(); - while (drive->busy) - sleep_on(&drive->wqueue); - ++drive->usage; if (ata_ops(drive) && ata_ops(drive)->open) return ata_ops(drive)->open(inode, filp, drive); diff --git a/drivers/ide/main.c b/drivers/ide/main.c index 24cc8bc9a75e..2f5f34953263 100644 --- a/drivers/ide/main.c +++ b/drivers/ide/main.c @@ -249,28 +249,22 @@ struct ata_device *get_info_ptr(kdev_t i_rdev) */ int ata_revalidate(kdev_t i_rdev) { + kdev_t device = mk_kdev(major(i_rdev), minor(i_rdev) & ~PARTN_MASK); struct ata_device *drive; - unsigned long flags; int res; - if ((drive = get_info_ptr(i_rdev)) == NULL) + if ((drive = get_info_ptr(device)) == NULL) return -ENODEV; - /* FIXME: The locking here doesn't make the slightest sense! */ - spin_lock_irqsave(&ide_lock, flags); - - if (drive->busy || (drive->usage > 1)) { - spin_unlock_irqrestore(&ide_lock, flags); - - return -EBUSY; - } - - drive->busy = 1; MOD_INC_USE_COUNT; - spin_unlock_irqrestore(&ide_lock, flags); + res = dev_lock_part(device); + if (res < 0) { + MOD_DEC_USE_COUNT; + return res; + } - res = wipe_partitions(i_rdev); + res = wipe_partitions(device); if (!res) { if (ata_ops(drive) && ata_ops(drive)->revalidate) { ata_get(ata_ops(drive)); @@ -281,14 +275,11 @@ int ata_revalidate(kdev_t i_rdev) ata_ops(drive)->revalidate(drive); ata_put(ata_ops(drive)); } else - grok_partitions(i_rdev, ata_capacity(drive)); + grok_partitions(device, ata_capacity(drive)); } - drive->busy = 0; - wake_up(&drive->wqueue); - + dev_unlock_part(device); MOD_DEC_USE_COUNT; - return res; } diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index bd4684dd648e..34ecf2f82ccb 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -1154,25 +1154,20 @@ static int ftl_ioctl(struct inode *inode, struct file *file, static int ftl_reread_partitions(kdev_t dev) { - int minor = minor(dev); - partition_t *part = myparts[minor >> 4]; - int res; - - DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor); - if ((atomic_read(&part->open) > 1)) { - return -EBUSY; - } - - res = wipe_partitions(dev); - if (res) - goto leave; - - scan_header(part); - - register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART, - &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE); - - return res; + int minor = minor(dev); + partition_t *part = myparts[minor >> 4]; + kdev_t device = mk_kdev(MAJOR_NR, minor & ~15); + int res = dev_lock_part(device); + if (rec < 0) + return res; + res = wipe_partitions(device); + if (!res) { + scan_header(part); + grok_partitions(device, + le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE); + } + dev_unlock_part(device); + return res; } /*====================================================================== @@ -1282,13 +1277,13 @@ static void ftl_notify_add(struct mtd_info *mtd) partition->mtd = mtd; - if ((scan_header(partition) == 0) && - (build_maps(partition) == 0)) { - + if ((scan_header(partition) == 0) && (build_maps(partition) == 0)) { partition->state = FTL_FORMATTED; atomic_set(&partition->open, 0); myparts[device] = partition; - ftl_reread_partitions(device << 4); + register_disk(&ftl_gendisk, mk_kdev(MAJOR_NR, device << 4), + MAX_PART, &ftl_blk_fops, + le32_to_cpu(partition->header.FormattedSize)/SECTOR_SIZE); #ifdef PCMCIA_DEBUG printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n", le32_to_cpu(partition->header.FormattedSize) >> 10); diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index 18607155f84a..9560e5a30faa 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c @@ -115,7 +115,6 @@ static void NFTL_setup(struct mtd_info *mtd) #endif /* linux stuff */ - nftl->usecount = 0; nftl->cylinders = 1024; nftl->heads = 16; @@ -153,8 +152,9 @@ static void NFTL_setup(struct mtd_info *mtd) #if LINUX_VERSION_CODE < 0x20328 resetup_one_dev(&nftl_gendisk, firstfree); #else - grok_partitions(mk_kdev(MAJOR_NR,firstfree<nr_sects); + register_disk(&nftl_gendisk, + mk_kdev(MAJOR_NR,firstfree<nr_sects); #endif } @@ -800,16 +800,17 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd case BLKRRPART: if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (nftl->usecount > 1) return -EBUSY; - /* - * We have to flush all buffers and invalidate caches, - * or we won't be able to re-use the partitions, - * if there was a change and we don't want to reboot - */ - res = wipe_partitions(inode->i_rdev); + { + kdev_t device = mk_kdev(MAJOR_NR, + minor(inode->i_rdev) & -(1<i_rdev, nftl->nr_sects); - + grok_partitions(device, nftl->nr_sects); + dev_unlock_part(device); + } return res; #if (LINUX_VERSION_CODE < 0x20303) @@ -955,7 +956,6 @@ static int nftl_open(struct inode *ip, struct file *fp) return -EROFS; #endif /* !CONFIG_NFTL_RW */ - thisNFTL->usecount++; if (!get_mtd_device(thisNFTL->mtd, -1)) return /* -E'SBUGGEREDOFF */ -ENXIO; @@ -972,7 +972,6 @@ static int nftl_release(struct inode *inode, struct file *fp) if (thisNFTL->mtd->sync) thisNFTL->mtd->sync(thisNFTL->mtd); - thisNFTL->usecount--; put_mtd_device(thisNFTL->mtd); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fd92ed1924f1..1ca2ac95292f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -506,16 +506,6 @@ static int sd_open(struct inode *inode, struct file *filp) */ if (!scsi_block_when_processing_errors(sdp)) return -ENXIO; - /* - * Make sure that only one process can do a check_change_disk at - * one time. This is also used to lock out further access when - * the partition table is being re-read. - */ - - while (sdp->busy) { - barrier(); - cpu_relax(); - } /* * The following code can sleep. * Module unloading must be prevented @@ -527,9 +517,7 @@ static int sd_open(struct inode *inode, struct file *filp) sdp->access_count++; if (sdp->removable) { - sdp->allow_revalidate = 1; check_disk_change(inode->i_rdev); - sdp->allow_revalidate = 0; /* * If the drive is empty, just let the open fail. @@ -1464,9 +1452,10 @@ static int sd_attach(Scsi_Device * sdp) int revalidate_scsidisk(kdev_t dev, int maxusage) { int dsk_nr = DEVICE_NR(dev); - int res; Scsi_Disk * sdkp; Scsi_Device * sdp; + kdev_t device = mk_kdev(major(dev), minor(dev) & ~15); + int res; SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", DEVICE_NR(dev))); @@ -1474,24 +1463,20 @@ int revalidate_scsidisk(kdev_t dev, int maxusage) if ((NULL == sdkp) || (NULL == (sdp = sdkp->device))) return -ENODEV; - if (sdp->busy || ((sdp->allow_revalidate == 0) && - (sdp->access_count > maxusage))) { - printk(KERN_WARNING "Device busy for revalidation " - "(access_count=%d)\n", sdp->access_count); - return -EBUSY; - } - sdp->busy = 1; + res = dev_lock_part(device); + if (res < 0) + return res; - res = wipe_partitions(dev); + res = wipe_partitions(device); if (res) goto leave; sd_init_onedisk(sdkp, dsk_nr); - grok_partitions(dev, sdkp->capacity); + grok_partitions(device, sdkp->capacity); leave: - sdp->busy = 0; + dev_unlock_part(device); return res; } diff --git a/fs/block_dev.c b/fs/block_dev.c index 90c46b454f3c..8166aea9be6a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -293,6 +293,8 @@ struct block_device *bdget(dev_t dev) new_bdev->bd_queue = NULL; new_bdev->bd_contains = NULL; new_bdev->bd_inode = inode; + new_bdev->bd_part_count = 0; + sema_init(&new_bdev->bd_part_sem, 1); inode->i_mode = S_IFBLK; inode->i_rdev = kdev; inode->i_bdev = new_bdev; @@ -415,9 +417,9 @@ int get_blkdev_list(char * p) Return the function table of a device. Load the driver if needed. */ -const struct block_device_operations * get_blkfops(unsigned int major) +struct block_device_operations * get_blkfops(unsigned int major) { - const struct block_device_operations *ret = NULL; + struct block_device_operations *ret = NULL; /* major 0 is used for non-device mounts */ if (major && major < MAX_BLKDEV) { @@ -479,7 +481,7 @@ int unregister_blkdev(unsigned int major, const char * name) int check_disk_change(kdev_t dev) { int i; - const struct block_device_operations * bdops = NULL; + struct block_device_operations * bdops = NULL; i = major(dev); if (i < MAX_BLKDEV) @@ -567,10 +569,16 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } } } - if (current_ops->open) { - ret = current_ops->open(inode, file); - if (ret) - goto out2; + if (bdev->bd_contains == bdev) { + if (current_ops->open) { + ret = current_ops->open(inode, file); + if (ret) + goto out2; + } + } else { + down(&bdev->bd_contains->bd_part_sem); + bdev->bd_contains->bd_part_count++; + up(&bdev->bd_contains->bd_part_sem); } if (!bdev->bd_op) bdev->bd_op = ops; @@ -688,8 +696,14 @@ int blkdev_put(struct block_device *bdev, int kind) } if (!--bdev->bd_openers) kill_bdev(bdev); - if (bdev->bd_op->release) - ret = bdev->bd_op->release(bd_inode, NULL); + if (bdev->bd_contains == bdev) { + if (bdev->bd_op->release) + ret = bdev->bd_op->release(bd_inode, NULL); + } else { + down(&bdev->bd_contains->bd_part_sem); + bdev->bd_contains->bd_part_count--; + up(&bdev->bd_contains->bd_part_sem); + } if (!bdev->bd_openers) { if (bdev->bd_op->owner) __MOD_DEC_USE_COUNT(bdev->bd_op->owner); diff --git a/fs/partitions/check.c b/fs/partitions/check.c index e7009bc3e421..8192096fad16 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -372,23 +372,8 @@ static void check_partition(struct gendisk *hd, kdev_t dev) sprintf(state->name, "p"); } bdev = bdget(kdev_t_to_nr(dev)); - bdev->bd_contains = bdev; - bdev->bd_inode->i_size = (loff_t)hd->part[minor(dev)].nr_sects << 9; - if (!bdev->bd_openers) { - struct blk_dev_struct *p = blk_dev + major(dev); - unsigned bsize = bdev_hardsect_size(bdev); - while (bsize < PAGE_CACHE_SIZE) { - if (bdev->bd_inode->i_size & bsize) - break; - bsize <<= 1; - } - if (p->queue) - bdev->bd_queue = p->queue(dev); - else - bdev->bd_queue = &p->request_queue; - bdev->bd_block_size = bsize; - bdev->bd_inode->i_blkbits = blksize_bits(bsize); - } + if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW)) + goto out; state->limit = 1<minor_shift; for (i = 0; check_part[i]; i++) { int res, j; @@ -417,10 +402,8 @@ static void check_partition(struct gendisk *hd, kdev_t dev) printk(" unknown partition table\n"); setup_devfs: - invalidate_bdev(bdev, 1); - truncate_inode_pages(bdev->bd_inode->i_mapping, 0); - bdput(bdev); - + blkdev_put(bdev, BDEV_RAW); +out: /* Setup driverfs tree */ if (hd->sizes) driverfs_create_partitions(hd, minor(dev)); diff --git a/include/linux/fs.h b/include/linux/fs.h index 83f5a21b5d26..b58c1b43f734 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -342,7 +342,7 @@ struct block_device { struct inode * bd_inode; dev_t bd_dev; /* not a kdev_t - it's a search key */ int bd_openers; - const struct block_device_operations *bd_op; + struct block_device_operations *bd_op; struct request_queue *bd_queue; struct semaphore bd_sem; /* open/close mutex */ struct list_head bd_inodes; @@ -351,6 +351,8 @@ struct block_device { struct block_device * bd_contains; unsigned bd_block_size; unsigned long bd_offset; + struct semaphore bd_part_sem; + unsigned bd_part_count; }; struct inode { @@ -1083,7 +1085,7 @@ extern void bd_release(struct block_device *); extern void blk_run_queues(void); /* fs/devices.c */ -extern const struct block_device_operations *get_blkfops(unsigned int); +extern struct block_device_operations *get_blkfops(unsigned int); extern int register_chrdev(unsigned int, const char *, struct file_operations *); extern int unregister_chrdev(unsigned int, const char *); extern int chrdev_open(struct inode *, struct file *); @@ -1293,5 +1295,31 @@ static inline ino_t parent_ino(struct dentry *dentry) return res; } +/* NOTE NOTE NOTE: this interface _will_ change in a couple of patches */ + +static inline int dev_lock_part(kdev_t dev) +{ + struct block_device *bdev = bdget(kdev_t_to_nr(dev)); + if (!bdev) + return -ENOMEM; + if (!down_trylock(&bdev->bd_part_sem)) { + if (!bdev->bd_part_count) + return 0; + up(&bdev->bd_part_sem); + } + bdput(bdev); + return -EBUSY; +} + +static inline void dev_unlock_part(kdev_t dev) +{ + struct block_device *bdev = bdget(kdev_t_to_nr(dev)); + if (!bdev) + BUG(); + up(&bdev->bd_part_sem); + bdput(bdev); + bdput(bdev); +} + #endif /* __KERNEL__ */ #endif /* _LINUX_FS_H */ -- cgit v1.2.3 From 9d16ed715038fbe847f896320d5f50ceab7bfc53 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sat, 20 Jul 2002 20:48:25 -0700 Subject: [PATCH] blk_ioctl() not exported anymore blk_ioctl() not exported anymore; calls moved from drivers to block_dev.c. --- drivers/acorn/block/mfmhd.c | 11 ------- drivers/block/DAC960.c | 37 +++++++---------------- drivers/block/acsi.c | 10 +------ drivers/block/ataflop.c | 6 ---- drivers/block/blkpg.c | 66 +++++++++++++---------------------------- drivers/block/cciss.c | 9 ------ drivers/block/cpqarray.c | 12 +------- drivers/block/floppy.c | 6 ---- drivers/block/genhd.c | 25 ---------------- drivers/block/loop.c | 4 --- drivers/block/paride/pd.c | 11 ++----- drivers/block/paride/pf.c | 4 --- drivers/block/ps2esdi.c | 12 +------- drivers/block/rd.c | 6 ---- drivers/block/umem.c | 15 ++-------- drivers/block/xd.c | 10 +------ drivers/cdrom/cdrom.c | 5 ---- drivers/ide/hd.c | 10 +------ drivers/ide/hptraid.c | 5 ---- drivers/ide/ioctl.c | 13 -------- drivers/ide/pdcraid.c | 5 ---- drivers/md/lvm.c | 11 ------- drivers/md/md.c | 24 +-------------- drivers/message/i2o/i2o_block.c | 10 +------ drivers/mtd/ftl.c | 13 +------- drivers/mtd/nftlcore.c | 14 +-------- drivers/s390/block/dasd_ioctl.c | 17 ++--------- drivers/s390/block/xpram.c | 8 ----- drivers/sbus/char/jsflash.c | 8 ----- drivers/scsi/sd.c | 15 +--------- fs/block_dev.c | 45 ++++++++++++++++++++-------- fs/partitions/check.c | 14 ++++----- include/linux/genhd.h | 6 ++-- 33 files changed, 92 insertions(+), 375 deletions(-) (limited to 'drivers/block') diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c index 5a209981436c..309fc7c4d47d 100644 --- a/drivers/acorn/block/mfmhd.c +++ b/drivers/acorn/block/mfmhd.c @@ -1192,22 +1192,11 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a return -EFAULT; return 0; - case BLKSECTGET: - return put_user(max_sectors[major][minor], (long *) arg); - case BLKRRPART: if (!capable(CAP_SYS_ADMIN)) return -EACCES; return mfm_reread_partitions(dev); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKFLSBUF: - case BLKROSET: - case BLKROGET: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: return -EINVAL; } diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 210449ad1715..dc372aa4dbb1 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -2055,29 +2055,20 @@ static void DAC960_ComputeGenericDiskInfo(DAC960_Controller_T *Controller) static void DAC960_RegisterDisk(DAC960_Controller_T *Controller, int LogicalDriveNumber) { - if (Controller->FirmwareType == DAC960_V1_Controller) - { + long size; + if (Controller->FirmwareType == DAC960_V1_Controller) { if (LogicalDriveNumber > Controller->LogicalDriveCount - 1) return; - register_disk(&Controller->GenericDiskInfo, - DAC960_KernelDevice(Controller->ControllerNumber, - LogicalDriveNumber, 0), - DAC960_MaxPartitions, - &DAC960_BlockDeviceOperations, - Controller->V1.LogicalDriveInformation - [LogicalDriveNumber].LogicalDriveSize); - } - else - { + size = Controller->V1.LogicalDriveInformation + [LogicalDriveNumber].LogicalDriveSize; + } else { DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo = Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]; if (LogicalDeviceInfo == NULL) return; - register_disk(&Controller->GenericDiskInfo, - DAC960_KernelDevice(Controller->ControllerNumber, - LogicalDriveNumber, 0), - DAC960_MaxPartitions, - &DAC960_BlockDeviceOperations, - LogicalDeviceInfo->ConfigurableDeviceSize); - } + size = LogicalDeviceInfo->ConfigurableDeviceSize; + } + register_disk(&Controller->GenericDiskInfo, + DAC960_KernelDevice(Controller->ControllerNumber, LogicalDriveNumber, 0), + DAC960_MaxPartitions, &DAC960_BlockDeviceOperations, size); } @@ -5399,15 +5390,9 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File, LogicalDeviceInfo->ConfigurableDeviceSize / (Geometry.heads * Geometry.sectors); } - Geometry.start = get_start_sect(Inode->i_rdev); + Geometry.start = get_start_sect(Inode->i_bdev); return (copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T)) ? -EFAULT : 0); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKFLSBUF: - case BLKBSZGET: - case BLKBSZSET: - return blk_ioctl(Inode->i_bdev, Request, Argument); case BLKRRPART: /* Re-Read Partition Table. */ diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c index 7ca3722d8ce9..f616f01847b7 100644 --- a/drivers/block/acsi.c +++ b/drivers/block/acsi.c @@ -1105,7 +1105,7 @@ static int acsi_ioctl( struct inode *inode, struct file *file, put_user( 64, &geo->heads ); put_user( 32, &geo->sectors ); put_user( acsi_info[dev].size >> 11, &geo->cylinders ); - put_user(get_start_sect(inode->i_rdev), &geo->start); + put_user(get_start_sect(inode->i_bdev), &geo->start); return 0; } @@ -1116,14 +1116,6 @@ static int acsi_ioctl( struct inode *inode, struct file *file, put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id ); return 0; - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); - case BLKRRPART: /* Re-read partition tables */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index af8f966f4eb3..04a8ce00c6a7 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1559,12 +1559,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp, struct floppy_struct setprm; device = inode->i_rdev; - switch (cmd) { - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - return blk_ioctl(inode->i_bdev, cmd, param); - } drive = minor (device); type = drive >> 2; drive &= 3; diff --git a/drivers/block/blkpg.c b/drivers/block/blkpg.c index 37e244777963..83826af84b6a 100644 --- a/drivers/block/blkpg.c +++ b/drivers/block/blkpg.c @@ -69,8 +69,9 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p) struct gendisk *g; long long ppstart, pplength; long pstart, plength; - int i, drive, first_minor, end_minor, minor; + int i; kdev_t dev = to_kdev_t(bdev->bd_dev); + struct hd_struct *part; /* convert bytes to sectors, check for fit in a hd_struct */ ppstart = (p->start >> 9); @@ -85,37 +86,32 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p) g = get_gendisk(dev); if (!g) return -ENXIO; + part = g->part + minor(dev); /* existing drive? */ - drive = (minor(dev) >> g->minor_shift); - first_minor = (drive << g->minor_shift); - end_minor = first_minor + (1 << g->minor_shift); - if (drive >= g->nr_real) - return -ENXIO; /* drive and partition number OK? */ - if (first_minor != minor(dev)) + if (bdev != bdev->bd_contains) return -EINVAL; if (p->pno <= 0 || p->pno >= (1 << g->minor_shift)) return -EINVAL; /* partition number in use? */ - minor = first_minor + p->pno; - if (g->part[minor].nr_sects != 0) + if (part[p->pno].nr_sects != 0) return -EBUSY; /* overlap? */ - for (i=first_minor+1; ipart[i].start_sect || - pstart >= g->part[i].start_sect + g->part[i].nr_sects)) + for (i = 1; i < (1<minor_shift); i++) + if (!(pstart+plength <= part[i].start_sect || + pstart >= part[i].start_sect + part[i].nr_sects)) return -EBUSY; /* all seems OK */ - g->part[minor].start_sect = pstart; - g->part[minor].nr_sects = plength; + part[p->pno].start_sect = pstart; + part[p->pno].nr_sects = plength; if (g->sizes) - g->sizes[minor] = (plength >> (BLOCK_SIZE_BITS - 9)); - devfs_register_partitions (g, first_minor, 0); + g->sizes[minor(dev)+p->pno] = (plength >> (BLOCK_SIZE_BITS-9)); + devfs_register_partitions (g, minor(dev), 0); return 0; } @@ -133,33 +129,27 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p) { kdev_t dev = to_kdev_t(bdev->bd_dev); struct gendisk *g; - kdev_t devp; struct block_device *bdevp; - int drive, first_minor, minor; + struct hd_struct *part; int holder; /* find the drive major */ g = get_gendisk(dev); if (!g) return -ENXIO; + part = g->part + minor(dev); - /* drive and partition number OK? */ - drive = (minor(dev) >> g->minor_shift); - first_minor = (drive << g->minor_shift); - - if (first_minor != minor(dev)) + if (bdev != bdev->bd_contains) return -EINVAL; if (p->pno <= 0 || p->pno >= (1 << g->minor_shift)) return -EINVAL; /* existing drive and partition? */ - minor = first_minor + p->pno; - if (drive >= g->nr_real || g->part[minor].nr_sects == 0) + if (part[p->pno].nr_sects == 0) return -ENXIO; /* partition in use? Incomplete check for now. */ - devp = mk_kdev(major(dev), minor); - bdevp = bdget(kdev_t_to_nr(devp)); + bdevp = bdget(MKDEV(major(dev), minor(dev) + p->pno)); if (!bdevp) return -ENOMEM; if (bd_claim(bdevp, &holder) < 0) { @@ -171,11 +161,11 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p) fsync_bdev(bdevp); invalidate_bdev(bdevp, 0); - g->part[minor].start_sect = 0; - g->part[minor].nr_sects = 0; + part[p->pno].start_sect = 0; + part[p->pno].nr_sects = 0; if (g->sizes) - g->sizes[minor] = 0; - devfs_register_partitions (g, first_minor, 0); + g->sizes[minor(dev) + p->pno] = 0; + devfs_register_partitions (g, minor(dev), 0); bd_release(bdevp); bdput(bdevp); @@ -223,10 +213,6 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg) int holder; struct backing_dev_info *bdi; - intval = block_ioctl(bdev, cmd, arg); - if (intval != -ENOTTY) - return intval; - switch (cmd) { case BLKROSET: if (!capable(CAP_SYS_ADMIN)) @@ -296,14 +282,6 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg) case BLKPG: return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg); - - /* - * deprecated, use the /proc/iosched interface instead - */ - case BLKELVGET: - case BLKELVSET: - return -ENOTTY; - case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ intval = block_size(bdev); @@ -330,5 +308,3 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg) return -EINVAL; } } - -EXPORT_SYMBOL(blk_ioctl); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 8c7033f3220b..939d70269415 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -440,15 +440,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case BLKRRPART: return revalidate_logvol(inode->i_rdev, 1); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKFLSBUF: - case BLKBSZSET: - case BLKBSZGET: - case BLKROSET: - case BLKROGET: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); case CCISS_GETPCIINFO: { cciss_pci_info_struct pciinfo; diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 124cbf046ce3..31276ef0e87c 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -1116,7 +1116,7 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, put_user(diskinfo[0], &geo->heads); put_user(diskinfo[1], &geo->sectors); put_user(diskinfo[2], &geo->cylinders); - put_user(get_start_sect(inode->i_rdev), &geo->start); + put_user(get_start_sect(inode->i_bdev), &geo->start); return 0; case IDAGETDRVINFO: if (copy_to_user(&io->c.drv, &hba[ctlr]->drv[dsk], @@ -1157,16 +1157,6 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, return(0); } - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKFLSBUF: - case BLKBSZSET: - case BLKBSZGET: - case BLKROSET: - case BLKROGET: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: return -EINVAL; } diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index aff8acff0ef3..fdc6e904464a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3468,12 +3468,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, const char *outparam; /* parameters passed back to user space */ device = inode->i_rdev; - switch (cmd) { - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - return blk_ioctl(inode->i_bdev, cmd, param); - } type = TYPE(device); drive = DRIVE(device); diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 7c30fbe37c16..6bb06af38980 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -117,31 +117,6 @@ get_gendisk(kdev_t dev) EXPORT_SYMBOL(get_gendisk); - -unsigned long -get_start_sect(kdev_t dev) -{ - struct gendisk *gp; - - gp = get_gendisk(dev); - if (gp) - return gp->part[minor(dev)].start_sect; - return 0; -} - -EXPORT_SYMBOL(get_start_sect); - -unsigned long -get_nr_sects(kdev_t dev) -{ - struct gendisk *gp; - - gp = get_gendisk(dev); - if (gp) - return gp->part[minor(dev)].nr_sects; - return 0; -} - #ifdef CONFIG_PROC_FS /* iterator */ static void *part_start(struct seq_file *part, loff_t *pos) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 982604ff6bfd..50c1052cae74 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -912,10 +912,6 @@ static int lo_ioctl(struct inode * inode, struct file * file, } err = put_user((u64)loop_sizes[lo->lo_number] << 10, (u64*)arg); break; - case BLKBSZGET: - case BLKBSZSET: - err = blk_ioctl(inode->i_bdev, cmd, arg); - break; default: err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 6e661e064da0..3c1492428a3c 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -460,19 +460,12 @@ static int pd_ioctl(struct inode *inode,struct file *file, put_user(PD.heads, (char *) &geo->heads); put_user(PD.sectors, (char *) &geo->sectors); } - put_user(get_start_sect(inode->i_rdev), (long *)&geo->start); + put_user(get_start_sect(inode->i_bdev), (long *)&geo->start); return 0; case BLKRRPART: if (!capable(CAP_SYS_ADMIN)) return -EACCES; return pd_revalidate(inode->i_rdev); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); default: return -EINVAL; } @@ -515,7 +508,7 @@ static int pd_revalidate(kdev_t dev) if ((unit >= PD_UNITS) || !PD.present) return -ENODEV; - res = dev_part_lock(device); + res = dev_lock_part(device); if (res < 0) return res; res = wipe_partitions(device); diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 578feaadbb38..b60847f9f25e 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -423,10 +423,6 @@ static int pf_ioctl(struct inode *inode,struct file *file, return put_user(PF.capacity,(long *) arg); case BLKGETSIZE64: return put_user((u64)PF.capacity << 9,(u64 *)arg); - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - return blk_ioctl(inode->i_bdev, cmd, arg); default: return -EINVAL; } diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c index 65b7d9999e6c..1d734f15cab2 100644 --- a/drivers/block/ps2esdi.c +++ b/drivers/block/ps2esdi.c @@ -1096,7 +1096,7 @@ static int ps2esdi_ioctl(struct inode *inode, put_user(ps2esdi_info[dev].head, (char *) &geometry->heads); put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors); put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders); - put_user(get_start_sect(inode->i_rdev), + put_user(get_start_sect(inode->b_rdev), (long *) &geometry->start); return 0; @@ -1107,16 +1107,6 @@ static int ps2esdi_ioctl(struct inode *inode, if (!capable(CAP_SYS_ADMIN)) return -EACCES; return (ps2esdi_reread_partitions(inode->i_rdev)); - - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKBSZGET: - case BLKBSZSET: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); } return (-EINVAL); } diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 7b60e75d5584..662020429ba6 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -303,12 +303,6 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un } up(&inode->i_bdev->bd_sem); break; - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKSSZGET: - error = blk_ioctl(inode->i_bdev, cmd, arg); } out: return error; diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 719a7a6a6261..a1575eb830b0 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -848,16 +848,6 @@ static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned switch(cmd) { - - case BLKGETSIZE: - /* Return the device size, expressed in sectors */ - err = ! access_ok (VERIFY_WRITE, arg, sizeof(long)); - if (err) return -EFAULT; - size = mm_gendisk.part[minor].nr_sects; - if (copy_to_user((long *) arg, &size, sizeof (long))) - return -EFAULT; - return 0; - case BLKRRPART: return (mm_revalidate(i->i_rdev)); @@ -872,16 +862,15 @@ static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned size = cards[card_number].mm_size * (1024 / MM_HARDSECT); geo.heads = 64; geo.sectors = 32; - geo.start = mm_gendisk.part[minor].start_sect; + geo.start = get_start_sect(inode->i_bdev); geo.cylinders = size / (geo.heads * geo.sectors); if (copy_to_user((void *) arg, &geo, sizeof(geo))) return -EFAULT; return 0; - default: - return blk_ioctl(i->i_bdev, cmd, arg); + return -EINVAL; } return -ENOTTY; /* unknown command */ diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 0474a027190c..a1166a4e1394 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -315,7 +315,7 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) g.heads = xd_info[dev].heads; g.sectors = xd_info[dev].sectors; g.cylinders = xd_info[dev].cylinders; - g.start = get_start_sect(inode->i_rdev); + g.start = get_start_sect(inode->i_bdev); return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0; } case HDIO_SET_DMA: @@ -337,14 +337,6 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) return -EACCES; return xd_reread_partitions(inode->i_rdev); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKFLSBUF: - case BLKROSET: - case BLKROGET: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: return -EINVAL; } diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 494aa03dc273..7b6dbbee9d95 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1732,11 +1732,6 @@ int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, because they fill up the sys log when CD players poll the drive. */ switch (cmd) { - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKSSZGET: - return blk_ioctl(ip->i_bdev, cmd, arg); case CDROMSUBCHNL: { struct cdrom_subchnl q; u_char requested, back; diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c index 689933665d17..f5fb26632eb2 100644 --- a/drivers/ide/hd.c +++ b/drivers/ide/hd.c @@ -641,7 +641,7 @@ static int hd_ioctl(struct inode * inode, struct file * file, g.heads = hd_info[dev].head; g.sectors = hd_info[dev].sect; g.cylinders = hd_info[dev].cyl; - g.start = get_start_sect(inode->i_rdev); + g.start = get_start_sect(inode->i_bdev); return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; } @@ -650,14 +650,6 @@ static int hd_ioctl(struct inode * inode, struct file * file, return -EACCES; return revalidate_hddisk(inode->i_rdev, 1); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: return -EINVAL; } diff --git a/drivers/ide/hptraid.c b/drivers/ide/hptraid.c index 9e8e07b35a2f..43b45c6e06eb 100644 --- a/drivers/ide/hptraid.c +++ b/drivers/ide/hptraid.c @@ -122,11 +122,6 @@ static int hptraid_ioctl(struct inode *inode, struct file *file, return 0; } - case BLKROSET: - case BLKROGET: - case BLKSSZGET: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: return -EINVAL; }; diff --git a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c index 1c86cbc9c177..003b743b4772 100644 --- a/drivers/ide/ioctl.c +++ b/drivers/ide/ioctl.c @@ -343,19 +343,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned case BLKRRPART: /* Re-read partition tables */ return ata_revalidate(inode->i_rdev); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKSSZGET: - case BLKPG: - case BLKELVGET: - case BLKELVSET: - case BLKBSZGET: - case BLKBSZSET: - return blk_ioctl(inode->i_bdev, cmd, arg); - /* Now check whatever this particular ioctl has a device type * specific implementation. */ diff --git a/drivers/ide/pdcraid.c b/drivers/ide/pdcraid.c index 4d6f81507582..d1bd67ba7f45 100644 --- a/drivers/ide/pdcraid.c +++ b/drivers/ide/pdcraid.c @@ -152,11 +152,6 @@ static int pdcraid_ioctl(struct inode *inode, struct file *file, return 0; } - case BLKROSET: - case BLKROGET: - case BLKSSZGET: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: printk("Invalid ioctl \n"); return -EINVAL; diff --git a/drivers/md/lvm.c b/drivers/md/lvm.c index c44a1b8a74b2..ab05b01ee4ce 100644 --- a/drivers/md/lvm.c +++ b/drivers/md/lvm.c @@ -872,17 +872,6 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file, return -EFAULT; break; - - case BLKFLSBUF: - /* flush buffer cache */ - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - - P_IOCTL("BLKFLSBUF\n"); - - fsync_bdev(inode->i_bdev); - invalidate_buffers(inode->i_rdev); - break; - case HDIO_GETGEO: /* get disk geometry */ P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name); diff --git a/drivers/md/md.c b/drivers/md/md.c index 549063948426..d08613aea3bb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2241,28 +2241,6 @@ static int md_ioctl(struct inode *inode, struct file *file, autostart_arrays(); goto done; #endif - - case BLKGETSIZE: /* Return device size */ - if (!arg) { - err = -EINVAL; - MD_BUG(); - goto abort; - } - err = put_user(md_hd_struct[minor].nr_sects, - (unsigned long *) arg); - goto done; - - case BLKGETSIZE64: /* Return device size */ - err = put_user((u64)md_hd_struct[minor].nr_sects << 9, - (u64 *) arg); - goto done; - - case BLKFLSBUF: - case BLKBSZGET: - case BLKBSZSET: - err = blk_ioctl(inode->i_bdev, cmd, arg); - goto abort; - default:; } @@ -2386,7 +2364,7 @@ static int md_ioctl(struct inode *inode, struct file *file, (short *) &loc->cylinders); if (err) goto abort_unlock; - err = put_user (get_start_sect(dev), + err = put_user (get_start_sect(inode->i_bdev), (long *) &loc->start); goto done_unlock; } diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 73c17cf22699..b82610655b49 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -1083,7 +1083,7 @@ static int i2ob_ioctl(struct inode *inode, struct file *file, int u = minor(inode->i_rdev) & 0xF0; i2o_block_biosparam(i2ob_sizes[u]<<1, &g.cylinders, &g.heads, &g.sectors); - g.start = get_start_sect(inode->i_rdev); + g.start = get_start_sect(inode->i_bdev); return copy_to_user((void *)arg, &g, sizeof(g)) ? -EFAULT : 0; } @@ -1093,14 +1093,6 @@ static int i2ob_ioctl(struct inode *inode, struct file *file, return -EACCES; return do_i2ob_revalidate(inode->i_rdev,1); - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKFLSBUF: - case BLKROSET: - case BLKROGET: - case BLKPG: - return blk_ioctl(inode->i_bdev, cmd, arg); - default: return -EINVAL; } diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 34ecf2f82ccb..c68d10d829f9 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -1123,22 +1123,11 @@ static int ftl_ioctl(struct inode *inode, struct file *file, put_user(1, (char *)&geo->heads); put_user(8, (char *)&geo->sectors); put_user((sect>>3), (short *)&geo->cylinders); - put_user(get_start_sect(inode->i_rdev), (u_long *)&geo->start); - break; - case BLKGETSIZE: - ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg); - break; - case BLKGETSIZE64: - ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg); + put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start); break; case BLKRRPART: ret = ftl_reread_partitions(inode->i_rdev); break; - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - ret = blk_ioctl(inode->i_bdev, cmd, arg); - break; default: ret = -EINVAL; } diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index 9560e5a30faa..f54e17f14540 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c @@ -787,7 +787,7 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd g.heads = nftl->heads; g.sectors = nftl->sectors; g.cylinders = nftl->cylinders; - g.start = get_start_sect(inode->i_rdev); + g.start = get_start_sect(inode->i_bdev); return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; } case BLKFLSBUF: @@ -812,18 +812,6 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd dev_unlock_part(device); } return res; - -#if (LINUX_VERSION_CODE < 0x20303) - RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ -#else - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKSSZGET: - return blk_ioctl(inode->i_bdev, cmd, arg); -#endif - default: return -EINVAL; } diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index ca62073e1009..beea10ab977d 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -447,11 +447,6 @@ static int dasd_ioctl_set_ro(void *inp, int no, long args) return 0; } -static int dasd_ioctl_blkioctl(void *inp, int no, long args) -{ - return blk_ioctl(((struct inode *) inp)->i_bdev, no, args); -} - /* * Return device size in number of sectors. */ @@ -517,12 +512,12 @@ static int dasd_ioctl_rr_partition(void *inp, int no, long args) static int dasd_ioctl_getgeo(void *inp, int no, long args) { struct hd_geometry geo = { 0, }; + struct inode *inode = inp; dasd_devmap_t *devmap; dasd_device_t *device; - kdev_t kdev; + kdev_t kdev = inode->i_rdev; int rc; - kdev = ((struct inode *) inp)->i_rdev; devmap = dasd_devmap_from_kdev(kdev); device = (devmap != NULL) ? dasd_get_device(devmap) : ERR_PTR(-ENODEV); @@ -532,7 +527,7 @@ static int dasd_ioctl_getgeo(void *inp, int no, long args) if (device != NULL && device->discipline != NULL && device->discipline->fill_geometry != NULL) { device->discipline->fill_geometry(device, &geo); - geo.start = get_start_sect(kdev); + geo.start = get_start_sect(inode->i_bdev); if (copy_to_user((struct hd_geometry *) args, &geo, sizeof (struct hd_geometry))) rc = -EFAULT; @@ -554,16 +549,10 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = { BIODASDINFO2, dasd_ioctl_information }, { BIODASDPRRD, dasd_ioctl_read_profile }, { BIODASDPRRST, dasd_ioctl_reset_profile }, - { BLKELVGET, dasd_ioctl_blkioctl }, - { BLKELVSET, dasd_ioctl_blkioctl }, - { BLKFLSBUF, dasd_ioctl_blkioctl }, { BLKGETSIZE, dasd_ioctl_blkgetsize }, { BLKGETSIZE64, dasd_ioctl_blkgetsize64 }, - { BLKPG, dasd_ioctl_blkioctl }, - { BLKROGET, dasd_ioctl_blkioctl }, { BLKROSET, dasd_ioctl_set_ro }, { BLKRRPART, dasd_ioctl_rr_partition }, - { BLKSSZGET, dasd_ioctl_blkioctl }, { DASDAPIVER, dasd_ioctl_api_version }, { HDIO_GETGEO, dasd_ioctl_getgeo }, { -1, NULL } diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index be899c77943a..3985f4274eac 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -342,14 +342,6 @@ static int xpram_ioctl (struct inode *inode, struct file *filp, if (idx >= xpram_devs) return -ENODEV; switch (cmd) { - case BLKGETSIZE: - /* Return the device size, expressed in sectors */ - return put_user(xpram_sizes[idx] << 1, (unsigned long *) arg); - case BLKGETSIZE64: - /* Return the device size, expressed in bytes */ - return put_user((u64) xpram_sizes[idx] << 10, (u64 *) arg); - case BLKFLSBUF: - return blk_ioctl(((struct inode *) inode)->i_bdev, cmd, arg); case BLKRRPART: /* re-read partition table: can't do it */ return -EINVAL; diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index a2c58e179445..c7d5306043c6 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -464,14 +464,6 @@ static int jsfd_ioctl(struct inode *inode, struct file *file, case BLKGETSIZE64: return put_user(jsfd_bytesizes[dev], (u64 *) arg); -#if 0 - case BLKROSET: - case BLKROGET: - case BLKSSZGET: - return blk_ioctl(inode->i_bdev, cmd, arg); -#endif - - /* case BLKFLSBUF: */ /* Program, then read, what happens? Stale? */ default: ; } return -ENOTTY; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 1ca2ac95292f..7ab403cf9848 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -241,25 +241,12 @@ static int sd_ioctl(struct inode * inode, struct file * filp, put_user(diskinfo[1], &loc->sectors) || put_user(diskinfo[2], &loc->cylinders) || put_user((unsigned) - get_start_sect(inode->i_rdev), + get_start_sect(inode->i_bdev), (unsigned long *) &loc->start)) return -EFAULT; return 0; } - case BLKGETSIZE: - case BLKGETSIZE64: - case BLKROSET: - case BLKROGET: - case BLKFLSBUF: - case BLKSSZGET: - case BLKPG: - case BLKELVGET: - case BLKELVSET: - case BLKBSZGET: - case BLKBSZSET: - return blk_ioctl(inode->i_bdev, cmd, arg); - case BLKRRPART: /* Re-read partition tables */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/fs/block_dev.c b/fs/block_dev.c index 8166aea9be6a..2a0304c00c77 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -514,19 +514,6 @@ int check_disk_change(kdev_t dev) return 1; } -int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) -{ - int res; - mm_segment_t old_fs = get_fs(); - - if (!bdev->bd_op->ioctl) - return -EINVAL; - set_fs(KERNEL_DS); - res = bdev->bd_op->ioctl(bdev->bd_inode, NULL, cmd, arg); - set_fs(old_fs); - return res; -} - static int do_open(struct block_device *bdev, struct inode *inode, struct file *file) { int ret = -ENXIO; @@ -731,15 +718,37 @@ static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, { int ret = -EINVAL; switch (cmd) { + /* + * deprecated, use the /proc/iosched interface instead + */ + case BLKELVGET: + case BLKELVSET: + ret = -ENOTTY; + break; case BLKRAGET: + case BLKROGET: + case BLKBSZGET: + case BLKSSZGET: case BLKFRAGET: + case BLKSECTGET: case BLKRASET: case BLKFRASET: + case BLKBSZSET: + case BLKPG: ret = blk_ioctl(inode->i_bdev, cmd, arg); break; default: if (inode->i_bdev->bd_op->ioctl) ret =inode->i_bdev->bd_op->ioctl(inode, file, cmd, arg); + if (ret == -EINVAL) { + switch (cmd) { + case BLKGETSIZE: + case BLKGETSIZE64: + case BLKFLSBUF: + case BLKROSET: + ret = blk_ioctl(inode->i_bdev,cmd,arg); + } + } break; } return ret; @@ -767,6 +776,16 @@ struct file_operations def_blk_fops = { ioctl: blkdev_ioctl, }; +int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) +{ + int res; + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg); + set_fs(old_fs); + return res; +} + const char *__bdevname(kdev_t dev) { static char buffer[32]; diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 8192096fad16..462405eabad8 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -236,6 +236,7 @@ void driverfs_create_partitions(struct gendisk *hd, int minor) int max_p; int part; devfs_handle_t dir = 0; + struct hd_struct *p = hd->part + minor; /* get parent driverfs device structure */ if (hd->driverfs_dev_arr) @@ -260,9 +261,9 @@ void driverfs_create_partitions(struct gendisk *hd, int minor) /* for all partitions setup parents and device node names */ for(part=0; part < max_p; part++) { - if ((part == 0) || (hd->part[minor + part].nr_sects >= 1)) { + if ((part == 0) || (p[part].nr_sects >= 1)) { struct device * current_driverfs_dev = - &hd->part[minor+part].hd_driverfs_dev; + &p[part].hd_driverfs_dev; current_driverfs_dev->parent = parent; /* handle disc case */ current_driverfs_dev->driver_data = @@ -300,7 +301,6 @@ void driverfs_create_partitions(struct gendisk *hd, int minor) &partition_device_kdev_file); } } - return; } void driverfs_remove_partitions(struct gendisk *hd, int minor) @@ -308,14 +308,14 @@ void driverfs_remove_partitions(struct gendisk *hd, int minor) int max_p; int part; struct device * current_driverfs_dev; + struct hd_struct *p = hd->part + minor; max_p=(1 << hd->minor_shift); /* for all parts setup parent relationships and device node names */ for(part=1; part < max_p; part++) { - if ((hd->part[minor + part].nr_sects >= 1)) { - current_driverfs_dev = - &hd->part[minor + part].hd_driverfs_dev; + if ((p[part].nr_sects >= 1)) { + current_driverfs_dev = &p[part].hd_driverfs_dev; device_remove_file(current_driverfs_dev, partition_device_type_file.name); device_remove_file(current_driverfs_dev, @@ -323,7 +323,7 @@ void driverfs_remove_partitions(struct gendisk *hd, int minor) put_device(current_driverfs_dev); } } - current_driverfs_dev = &hd->part[minor].hd_driverfs_dev; + current_driverfs_dev = &p->hd_driverfs_dev; device_remove_file(current_driverfs_dev, partition_device_type_file.name); device_remove_file(current_driverfs_dev, diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 44a954b2c370..93755fee7f36 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -90,8 +90,10 @@ struct gendisk { extern void add_gendisk(struct gendisk *gp); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(kdev_t dev); -extern unsigned long get_start_sect(kdev_t dev); -extern unsigned long get_nr_sects(kdev_t dev); +static inline unsigned long get_start_sect(struct block_device *bdev) +{ + return bdev->bd_offset; +} #endif /* __KERNEL__ */ -- cgit v1.2.3 From b92b31a3efb48ce9bd1a0aa58e7925cd97e362ee Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sat, 20 Jul 2002 20:48:41 -0700 Subject: [PATCH] paride cleanup and fixes somewhat related to the above - drivers/block/paride/* switched to module_init()/module_exit(), pd.c taught to use LBA if disks support it (needed for paride disks >8Gb; change is fairly trivial and I've got 40Gb one ;-) --- drivers/block/paride/Makefile | 16 ++-- drivers/block/paride/aten.c | 53 ++++++----- drivers/block/paride/bpck.c | 55 ++++++------ drivers/block/paride/bpck6.c | 71 +++++---------- drivers/block/paride/comm.c | 53 ++++++----- drivers/block/paride/dstr.c | 53 ++++++----- drivers/block/paride/epat.c | 54 ++++++------ drivers/block/paride/epia.c | 55 ++++++------ drivers/block/paride/fit2.c | 53 ++++++----- drivers/block/paride/fit3.c | 53 ++++++----- drivers/block/paride/friq.c | 54 ++++++------ drivers/block/paride/frpw.c | 54 ++++++------ drivers/block/paride/kbic.c | 92 ++++++++++--------- drivers/block/paride/ktti.c | 53 ++++++----- drivers/block/paride/on20.c | 53 ++++++----- drivers/block/paride/on26.c | 55 ++++++------ drivers/block/paride/paride.c | 133 ---------------------------- drivers/block/paride/pcd.c | 124 +++++++++++--------------- drivers/block/paride/pd.c | 200 ++++++++++++++++++------------------------ drivers/block/paride/pf.c | 106 +++++++++------------- drivers/block/paride/pg.c | 107 ++++++++-------------- drivers/block/paride/pt.c | 116 +++++++++--------------- 22 files changed, 677 insertions(+), 986 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile index d62c39cb9b55..b1294e64f414 100644 --- a/drivers/block/paride/Makefile +++ b/drivers/block/paride/Makefile @@ -5,14 +5,9 @@ # Rewritten to use lists instead of if-statements. # -export-objs := paride.o bpck6.o +export-objs := paride.o obj-$(CONFIG_PARIDE) += paride.o -obj-$(CONFIG_PARIDE_PD) += pd.o -obj-$(CONFIG_PARIDE_PCD) += pcd.o -obj-$(CONFIG_PARIDE_PF) += pf.o -obj-$(CONFIG_PARIDE_PT) += pt.o -obj-$(CONFIG_PARIDE_PG) += pg.o obj-$(CONFIG_PARIDE_ATEN) += aten.o obj-$(CONFIG_PARIDE_BPCK) += bpck.o obj-$(CONFIG_PARIDE_COMM) += comm.o @@ -20,13 +15,18 @@ obj-$(CONFIG_PARIDE_DSTR) += dstr.o obj-$(CONFIG_PARIDE_KBIC) += kbic.o obj-$(CONFIG_PARIDE_EPAT) += epat.o obj-$(CONFIG_PARIDE_EPIA) += epia.o -obj-$(CONFIG_PARIDE_FIT2) += fit2.o -obj-$(CONFIG_PARIDE_FIT3) += fit3.o obj-$(CONFIG_PARIDE_FRPW) += frpw.o obj-$(CONFIG_PARIDE_FRIQ) += friq.o +obj-$(CONFIG_PARIDE_FIT2) += fit2.o +obj-$(CONFIG_PARIDE_FIT3) += fit3.o obj-$(CONFIG_PARIDE_ON20) += on20.o obj-$(CONFIG_PARIDE_ON26) += on26.o obj-$(CONFIG_PARIDE_KTTI) += ktti.o obj-$(CONFIG_PARIDE_BPCK6) += bpck6.o +obj-$(CONFIG_PARIDE_PD) += pd.o +obj-$(CONFIG_PARIDE_PCD) += pcd.o +obj-$(CONFIG_PARIDE_PF) += pf.o +obj-$(CONFIG_PARIDE_PT) += pt.o +obj-$(CONFIG_PARIDE_PG) += pg.o include $(TOPDIR)/Rules.make diff --git a/drivers/block/paride/aten.c b/drivers/block/paride/aten.c index b22d34da348a..763fc50d7f76 100644 --- a/drivers/block/paride/aten.c +++ b/drivers/block/paride/aten.c @@ -18,6 +18,7 @@ #define ATEN_VERSION "1.01" #include +#include #include #include #include @@ -140,35 +141,33 @@ static void aten_release_proto( PIA *pi ) { MOD_DEC_USE_COUNT; } -struct pi_protocol aten = {"aten",0,2,2,1,1, - aten_write_regr, - aten_read_regr, - aten_write_block, - aten_read_block, - aten_connect, - aten_disconnect, - 0, - 0, - 0, - aten_log_adapter, - aten_init_proto, - aten_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &aten ) - 1; +static struct pi_protocol aten = { + .name = "aten", + .max_mode = 2, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = aten_write_regr, + .read_regr = aten_read_regr, + .write_block = aten_write_block, + .read_block = aten_read_block, + .connect = aten_connect, + .disconnect = aten_disconnect, + .log_adapter = aten_log_adapter, + .init_proto = aten_init_proto, + .release_proto = aten_release_proto, +}; + +static int __init aten_init(void) +{ + return pi_register(&aten)-1; } -void cleanup_module(void) - -{ pi_unregister( &aten ); +static void __exit aten_exit(void) +{ + pi_unregister( &aten ); } -#endif - -/* end of aten.c */ MODULE_LICENSE("GPL"); +module_init(aten_init) +module_exit(aten_exit) diff --git a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c index 3e20e6b7054a..b15ff97fe7af 100644 --- a/drivers/block/paride/bpck.c +++ b/drivers/block/paride/bpck.c @@ -17,6 +17,7 @@ #define BPCK_VERSION "1.02" #include +#include #include #include #include @@ -452,34 +453,36 @@ static void bpck_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol bpck = { "bpck",0,5,2,4,256, - bpck_write_regr, - bpck_read_regr, - bpck_write_block, - bpck_read_block, - bpck_connect, - bpck_disconnect, - bpck_test_port, - bpck_probe_unit, - bpck_test_proto, - bpck_log_adapter, - bpck_init_proto, - bpck_release_proto - }; - -#ifdef MODULE - -int init_module(void) - -{ return pi_register(&bpck) - 1; +static struct pi_protocol bpck = { + .name = "bpck", + .max_mode = 5, + .epp_first = 2, + .default_delay = 4, + .max_units = 255, + .write_regr = bpck_write_regr, + .read_regr = bpck_read_regr, + .write_block = bpck_write_block, + .read_block = bpck_read_block, + .connect = bpck_connect, + .disconnect = bpck_disconnect, + .test_port = bpck_test_port, + .probe_unit = bpck_probe_unit, + .test_proto = bpck_test_proto, + .log_adapter = bpck_log_adapter, + .init_proto = bpck_init_proto, + .release_proto = bpck_release_proto, +}; + +static int __init bpck_init(void) +{ + return pi_register(&bpck)-1; } -void cleanup_module(void) - -{ pi_unregister(&bpck); +static void __exit bpck_exit(void) +{ + pi_unregister(&bpck); } -#endif - -/* end of bpck.c */ MODULE_LICENSE("GPL"); +module_init(bpck_init) +module_exit(bpck_exit) diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c index f2febfcfd268..c1fcdd9f4e94 100644 --- a/drivers/block/paride/bpck6.c +++ b/drivers/block/paride/bpck6.c @@ -26,6 +26,7 @@ int verbose=0; /* set this to 1 to see debugging messages and whatnot */ #define BACKPACK_VERSION "2.0.2" #include +#include #include #include #include @@ -252,65 +253,41 @@ static void bpck6_release_proto(PIA *pi) kfree((void *)(pi->private)); } -struct pi_protocol bpck6 = { "bpck6", /* name for proto*/ - 0, /* index into proto table */ - 5, /* max mode =5 */ - 2, /* 2-5 use epp (need 8 ports) */ - 0, /* no delay (not used anyway) */ - 255, /* we can have units up to 255 */ - bpck6_write_regr, - bpck6_read_regr, - bpck6_write_block, - bpck6_read_block, - bpck6_connect, - bpck6_disconnect, - bpck6_test_port, - bpck6_probe_unit, - 0, - bpck6_log_adapter, - bpck6_init_proto, - bpck6_release_proto - }; - - -EXPORT_SYMBOL(bpck6_write_regr); -EXPORT_SYMBOL(bpck6_read_regr); -EXPORT_SYMBOL(bpck6_write_block); -EXPORT_SYMBOL(bpck6_read_block); -EXPORT_SYMBOL(bpck6_connect); -EXPORT_SYMBOL(bpck6_disconnect); -EXPORT_SYMBOL(bpck6_test_port); -EXPORT_SYMBOL(bpck6_probe_unit); -EXPORT_SYMBOL(bpck6_log_adapter); -EXPORT_SYMBOL(bpck6_init_proto); -EXPORT_SYMBOL(bpck6_release_proto); - -/*---------------------------MODULE STUFF-----------------------*/ - -#ifdef MODULE -/*module information*/ - -static int init_module(void) +static struct pi_protocol bpck6 = { + .name = "bpck6", + .max_mode = 5, + .epp_first = 2, /* 2-5 use epp (need 8 ports) */ + .max_units = 255, + .write_regr = bpck6_write_regr, + .read_regr = bpck6_read_regr, + .write_block = bpck6_write_block, + .read_block = bpck6_read_block, + .connect = bpck6_connect, + .disconnect = bpck6_disconnect, + .test_port = bpck6_test_port, + .probe_unit = bpck6_probe_unit, + .log_adapter = bpck6_log_adapter, + .init_proto = bpck6_init_proto, + .release_proto = bpck6_release_proto, +}; + +static int __init bpck6_init(void) { printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n"); printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n"); - if(verbose) - { printk(KERN_DEBUG "bpck6: verbose debug enabled.\n"); - } - return pi_register(&bpck6) - 1; } -void cleanup_module(void) +static void __exit bpck6_exit(void) { pi_unregister(&bpck6); } +MODULE_LICENSE("GPL"); MODULE_AUTHOR("Micro Solutions Inc."); MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE"); MODULE_PARM(verbose,"i"); - -#endif - +module_init(bpck6_init) +module_exit(bpck6_exit) diff --git a/drivers/block/paride/comm.c b/drivers/block/paride/comm.c index 058a7d68572c..f3010d6fc73b 100644 --- a/drivers/block/paride/comm.c +++ b/drivers/block/paride/comm.c @@ -17,6 +17,7 @@ #define COMM_VERSION "1.01" #include +#include #include #include #include @@ -196,35 +197,33 @@ static void comm_release_proto(PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol comm = {"comm",0,5,2,1,1, - comm_write_regr, - comm_read_regr, - comm_write_block, - comm_read_block, - comm_connect, - comm_disconnect, - 0, - 0, - 0, - comm_log_adapter, - comm_init_proto, - comm_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &comm ) - 1; +static struct pi_protocol comm = { + .name = "comm", + .max_mode = 5, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = comm_write_regr, + .read_regr = comm_read_regr, + .write_block = comm_write_block, + .read_block = comm_read_block, + .connect = comm_connect, + .disconnect = comm_disconnect, + .log_adapter = comm_log_adapter, + .init_proto = comm_init_proto, + .release_proto = comm_release_proto, +}; + +static int __init comm_init(void) +{ + return pi_register(&comm)-1; } -void cleanup_module(void) - -{ pi_unregister( &comm ); +static void __exit comm_exit(void) +{ + pi_unregister(&comm); } -#endif - -/* end of comm.c */ MODULE_LICENSE("GPL"); +module_init(comm_init) +module_exit(comm_exit) diff --git a/drivers/block/paride/dstr.c b/drivers/block/paride/dstr.c index 438735b6ce10..204fe75df233 100644 --- a/drivers/block/paride/dstr.c +++ b/drivers/block/paride/dstr.c @@ -16,6 +16,7 @@ #define DSTR_VERSION "1.01" #include +#include #include #include #include @@ -211,35 +212,33 @@ static void dstr_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol dstr = {"dstr",0,5,2,1,1, - dstr_write_regr, - dstr_read_regr, - dstr_write_block, - dstr_read_block, - dstr_connect, - dstr_disconnect, - 0, - 0, - 0, - dstr_log_adapter, - dstr_init_proto, - dstr_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &dstr ) - 1; +static struct pi_protocol dstr = { + .name = "dstr", + .max_mode = 5, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = dstr_write_regr, + .read_regr = dstr_read_regr, + .write_block = dstr_write_block, + .read_block = dstr_read_block, + .connect = dstr_connect, + .disconnect = dstr_disconnect, + .log_adapter = dstr_log_adapter, + .init_proto = dstr_init_proto, + .release_proto = dstr_release_proto, +}; + +static int __init dstr_init(void) +{ + return pi_register(&dstr)-1; } -void cleanup_module(void) - -{ pi_unregister( &dstr ); +static void __exit dstr_exit(void) +{ + pi_unregister(&dstr); } -#endif - -/* end of dstr.c */ MODULE_LICENSE("GPL"); +module_init(dstr_init) +module_exit(dstr_exit) diff --git a/drivers/block/paride/epat.c b/drivers/block/paride/epat.c index 624a5ba32cfd..0a7126756371 100644 --- a/drivers/block/paride/epat.c +++ b/drivers/block/paride/epat.c @@ -19,6 +19,7 @@ #define EPAT_VERSION "1.02" #include +#include #include #include #include @@ -311,35 +312,34 @@ static void epat_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol epat = {"epat",0,6,3,1,1, - epat_write_regr, - epat_read_regr, - epat_write_block, - epat_read_block, - epat_connect, - epat_disconnect, - 0, - 0, - epat_test_proto, - epat_log_adapter, - epat_init_proto, - epat_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &epat) - 1; +static struct pi_protocol epat = { + .name = "epat", + .max_mode = 6, + .epp_first = 3, + .default_delay = 1, + .max_units = 1, + .write_regr = epat_write_regr, + .read_regr = epat_read_regr, + .write_block = epat_write_block, + .read_block = epat_read_block, + .connect = epat_connect, + .disconnect = epat_disconnect, + .test_proto = epat_test_proto, + .log_adapter = epat_log_adapter, + .init_proto = epat_init_proto, + .release_proto = epat_release_proto, +}; + +static int __init epat_init(void) +{ + return pi_register(&epat)-1; } -void cleanup_module(void) - -{ pi_unregister( &epat); +static void __exit epat_exit(void) +{ + pi_unregister(&epat); } -#endif - -/* end of epat.c */ MODULE_LICENSE("GPL"); +module_init(epat_init) +module_exit(epat_exit) diff --git a/drivers/block/paride/epia.c b/drivers/block/paride/epia.c index c27edd64ecc1..c2728af843dd 100644 --- a/drivers/block/paride/epia.c +++ b/drivers/block/paride/epia.c @@ -20,6 +20,7 @@ #define EPIA_VERSION "1.02" #include +#include #include #include #include @@ -293,36 +294,34 @@ static void epia_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol epia = {"epia",0,6,3,1,1, - epia_write_regr, - epia_read_regr, - epia_write_block, - epia_read_block, - epia_connect, - epia_disconnect, - 0, - 0, - epia_test_proto, - epia_log_adapter, - epia_init_proto, - epia_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &epia ) - 1; +static struct pi_protocol epia = { + .name = "epia", + .max_mode = 6, + .epp_first = 3, + .default_delay = 1, + .max_units = 1, + .write_regr = epia_write_regr, + .read_regr = epia_read_regr, + .write_block = epia_write_block, + .read_block = epia_read_block, + .connect = epia_connect, + .disconnect = epia_disconnect, + .test_proto = epia_test_proto, + .log_adapter = epia_log_adapter, + .init_proto = epia_init_proto, + .release_proto = epia_release_proto, +}; + +static int __init epia_init(void) +{ + return pi_register(&epia)-1; } -void cleanup_module(void) - -{ pi_unregister( &epia ); +static void __exit epia_exit(void) +{ + pi_unregister(&epia); } -#endif - -/* end of epia.c */ - MODULE_LICENSE("GPL"); +module_init(epia_init) +module_exit(epia_exit) diff --git a/drivers/block/paride/fit2.c b/drivers/block/paride/fit2.c index 7f45529c80b1..42b2880a82ac 100644 --- a/drivers/block/paride/fit2.c +++ b/drivers/block/paride/fit2.c @@ -16,6 +16,7 @@ #define FIT2_VERSION "1.0" #include +#include #include #include #include @@ -129,35 +130,33 @@ static void fit2_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol fit2 = {"fit2",0,1,2,1,1, - fit2_write_regr, - fit2_read_regr, - fit2_write_block, - fit2_read_block, - fit2_connect, - fit2_disconnect, - 0, - 0, - 0, - fit2_log_adapter, - fit2_init_proto, - fit2_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &fit2 ) - 1; +static struct pi_protocol fit2 = { + .name = "fit2", + .max_mode = 1, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = fit2_write_regr, + .read_regr = fit2_read_regr, + .write_block = fit2_write_block, + .read_block = fit2_read_block, + .connect = fit2_connect, + .disconnect = fit2_disconnect, + .log_adapter = fit2_log_adapter, + .init_proto = fit2_init_proto, + .release_proto = fit2_release_proto, +}; + +static int __init fit2_init(void) +{ + return pi_register(&fit2)-1; } -void cleanup_module(void) - -{ pi_unregister( &fit2 ); +static void __exit fit2_exit(void) +{ + pi_unregister(&fit2); } -#endif - -/* end of fit2.c */ MODULE_LICENSE("GPL"); +module_init(fit2_init) +module_exit(fit2_exit) diff --git a/drivers/block/paride/fit3.c b/drivers/block/paride/fit3.c index 8b5ad4bd5ad0..4d9286562c3c 100644 --- a/drivers/block/paride/fit3.c +++ b/drivers/block/paride/fit3.c @@ -20,6 +20,7 @@ #define FIT3_VERSION "1.0" #include +#include #include #include #include @@ -189,35 +190,33 @@ static void fit3_release_proto(PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol fit3 = {"fit3",0,3,2,1,1, - fit3_write_regr, - fit3_read_regr, - fit3_write_block, - fit3_read_block, - fit3_connect, - fit3_disconnect, - 0, - 0, - 0, - fit3_log_adapter, - fit3_init_proto, - fit3_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &fit3 ) - 1; +static struct pi_protocol fit3 = { + .name = "fit3", + .max_mode = 3, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = fit3_write_regr, + .read_regr = fit3_read_regr, + .write_block = fit3_write_block, + .read_block = fit3_read_block, + .connect = fit3_connect, + .disconnect = fit3_disconnect, + .log_adapter = fit3_log_adapter, + .init_proto = fit3_init_proto, + .release_proto = fit3_release_proto, +}; + +static int __init fit3_init(void) +{ + return pi_register(&fit3)-1; } -void cleanup_module(void) - -{ pi_unregister( &fit3 ); +static void __exit fit3_exit(void) +{ + pi_unregister(&fit3); } -#endif - -/* end of fit3.c */ MODULE_LICENSE("GPL"); +module_init(fit3_init) +module_exit(fit3_exit) diff --git a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c index 74b2eaab1c19..10b994a456da 100644 --- a/drivers/block/paride/friq.c +++ b/drivers/block/paride/friq.c @@ -28,6 +28,7 @@ #define FRIQ_VERSION "1.01" #include +#include #include #include #include @@ -250,35 +251,34 @@ static void friq_release_proto( PIA *pi) MOD_DEC_USE_COUNT; } -struct pi_protocol friq = {"friq",0,5,2,1,1, - friq_write_regr, - friq_read_regr, - friq_write_block, - friq_read_block, - friq_connect, - friq_disconnect, - 0, - 0, - friq_test_proto, - friq_log_adapter, - friq_init_proto, - friq_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &friq ) - 1; +static struct pi_protocol friq = { + .name = "friq", + .max_mode = 5, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = friq_write_regr, + .read_regr = friq_read_regr, + .write_block = friq_write_block, + .read_block = friq_read_block, + .connect = friq_connect, + .disconnect = friq_disconnect, + .test_proto = friq_test_proto, + .log_adapter = friq_log_adapter, + .init_proto = friq_init_proto, + .release_proto = friq_release_proto, +}; + +static int __init friq_init(void) +{ + return pi_register(&friq)-1; } -void cleanup_module(void) - -{ pi_unregister( &friq ); +static void __exit friq_exit(void) +{ + pi_unregister(&friq); } -#endif - -/* end of friq.c */ MODULE_LICENSE("GPL"); +module_init(friq_init) +module_exit(friq_exit) diff --git a/drivers/block/paride/frpw.c b/drivers/block/paride/frpw.c index 817004a3f7dc..ee0cad3807a1 100644 --- a/drivers/block/paride/frpw.c +++ b/drivers/block/paride/frpw.c @@ -26,6 +26,7 @@ #define FRPW_VERSION "1.03" #include +#include #include #include #include @@ -291,35 +292,34 @@ static void frpw_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol frpw = {"frpw",0,6,2,2,1, - frpw_write_regr, - frpw_read_regr, - frpw_write_block, - frpw_read_block, - frpw_connect, - frpw_disconnect, - 0, - 0, - frpw_test_proto, - frpw_log_adapter, - frpw_init_proto, - frpw_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &frpw ) - 1; +static struct pi_protocol frpw = { + .name = "frpw", + .max_mode = 6, + .epp_first = 2, + .default_delay = 2, + .max_units = 1, + .write_regr = frpw_write_regr, + .read_regr = frpw_read_regr, + .write_block = frpw_write_block, + .read_block = frpw_read_block, + .connect = frpw_connect, + .disconnect = frpw_disconnect, + .test_proto = frpw_test_proto, + .log_adapter = frpw_log_adapter, + .init_proto = frpw_init_proto, + .release_proto = frpw_release_proto, +}; + +static int __init frpw_init(void) +{ + return pi_register(&frpw)-1; } -void cleanup_module(void) - -{ pi_unregister( &frpw ); +static void __exit frpw_exit(void) +{ + pi_unregister(&frpw); } -#endif - -/* end of frpw.c */ MODULE_LICENSE("GPL"); +module_init(frpw_init) +module_exit(frpw_exit) diff --git a/drivers/block/paride/kbic.c b/drivers/block/paride/kbic.c index 2f20c9b0fa4e..f97233b39b7b 100644 --- a/drivers/block/paride/kbic.c +++ b/drivers/block/paride/kbic.c @@ -21,6 +21,7 @@ #define KBIC_VERSION "1.01" #include +#include #include #include #include @@ -258,56 +259,51 @@ static void kbic_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol k951 = {"k951",0,6,3,1,1, - kbic_write_regr, - kbic_read_regr, - kbic_write_block, - kbic_read_block, - k951_connect, - k951_disconnect, - 0, - 0, - 0, - k951_log_adapter, - kbic_init_proto, - kbic_release_proto - }; - - -struct pi_protocol k971 = {"k971",0,6,3,1,1, - kbic_write_regr, - kbic_read_regr, - kbic_write_block, - kbic_read_block, - k971_connect, - k971_disconnect, - 0, - 0, - 0, - k971_log_adapter, - kbic_init_proto, - kbic_release_proto - }; - -#ifdef MODULE - -int init_module(void) - -{ int s5,s7; - - s5 = pi_register(&k951); - s7 = pi_register(&k971); - - return (s5 || s7) - 1; +static struct pi_protocol k951 = { + .name = "k951", + .max_mode = 6, + .epp_first = 3, + .default_delay = 1, + .max_units = 1, + .write_regr = kbic_write_regr, + .read_regr = kbic_read_regr, + .write_block = kbic_write_block, + .read_block = kbic_read_block, + .connect = k951_connect, + .disconnect = k951_disconnect, + .log_adapter = k951_log_adapter, + .init_proto = kbic_init_proto, + .release_proto = kbic_release_proto +}; + +static struct pi_protocol k971 = { + .name = "k971", + .max_mode = 6, + .epp_first = 3, + .default_delay = 1, + .max_units = 1, + .write_regr = kbic_write_regr, + .read_regr = kbic_read_regr, + .write_block = kbic_write_block, + .read_block = kbic_read_block, + .connect = k971_connect, + .disconnect = k971_disconnect, + .log_adapter = k971_log_adapter, + .init_proto = kbic_init_proto, + .release_proto = kbic_release_proto +}; + +static int __init kbic_init(void) +{ + return (pi_register(&k951)||pi_register(&k971))-1; } -void cleanup_module(void) - -{ pi_unregister( &k951 ); - pi_unregister( &k971 ); +static void __exit kbic_exit(void) +{ + pi_unregister(&k951); + pi_unregister(&k971); } -#endif - -/* end of kbic.c */ MODULE_LICENSE("GPL"); +module_init(kbic_init) +module_exit(kbic_exit) diff --git a/drivers/block/paride/ktti.c b/drivers/block/paride/ktti.c index 60778192e0c1..bee083b4da9c 100644 --- a/drivers/block/paride/ktti.c +++ b/drivers/block/paride/ktti.c @@ -12,6 +12,7 @@ #define KTTI_VERSION "1.0" #include +#include #include #include #include @@ -106,35 +107,33 @@ static void ktti_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol ktti = {"ktti",0,1,2,1,1, - ktti_write_regr, - ktti_read_regr, - ktti_write_block, - ktti_read_block, - ktti_connect, - ktti_disconnect, - 0, - 0, - 0, - ktti_log_adapter, - ktti_init_proto, - ktti_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &ktti ) - 1; +static struct pi_protocol ktti = { + .name = "ktti", + .max_mode = 1, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = ktti_write_regr, + .read_regr = ktti_read_regr, + .write_block = ktti_write_block, + .read_block = ktti_read_block, + .connect = ktti_connect, + .disconnect = ktti_disconnect, + .log_adapter = ktti_log_adapter, + .init_proto = ktti_init_proto, + .release_proto = ktti_release_proto, +}; + +static int __init ktti_init(void) +{ + return pi_register(&ktti)-1; } -void cleanup_module(void) - -{ pi_unregister( &ktti ); +static void __exit ktti_exit(void) +{ + pi_unregister(&ktti); } -#endif - -/* end of ktti.c */ MODULE_LICENSE("GPL"); +module_init(ktti_init) +module_exit(ktti_exit) diff --git a/drivers/block/paride/on20.c b/drivers/block/paride/on20.c index b3c8d3d325e0..8528e0212591 100644 --- a/drivers/block/paride/on20.c +++ b/drivers/block/paride/on20.c @@ -15,6 +15,7 @@ #define ON20_VERSION "1.01" #include +#include #include #include #include @@ -131,35 +132,33 @@ static void on20_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol on20 = {"on20",0,2,2,1,1, - on20_write_regr, - on20_read_regr, - on20_write_block, - on20_read_block, - on20_connect, - on20_disconnect, - 0, - 0, - 0, - on20_log_adapter, - on20_init_proto, - on20_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &on20 ) - 1; +static struct pi_protocol on20 = { + .name = "on20", + .max_mode = 2, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = on20_write_regr, + .read_regr = on20_read_regr, + .write_block = on20_write_block, + .read_block = on20_read_block, + .connect = on20_connect, + .disconnect = on20_disconnect, + .log_adapter = on20_log_adapter, + .init_proto = on20_init_proto, + .release_proto = on20_release_proto, +}; + +static int __init on20_init(void) +{ + return pi_register(&on20)-1; } -void cleanup_module(void) - -{ pi_unregister( &on20 ); +static void __exit on20_exit(void) +{ + pi_unregister(&on20); } -#endif - -/* end of on20.c */ MODULE_LICENSE("GPL"); +module_init(on20_init) +module_exit(on20_exit) diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c index 0688c6317972..c08111db5a21 100644 --- a/drivers/block/paride/on26.c +++ b/drivers/block/paride/on26.c @@ -19,6 +19,7 @@ #define ON26_VERSION "1.04" #include +#include #include #include #include @@ -296,36 +297,34 @@ static void on26_release_proto( PIA *pi) { MOD_DEC_USE_COUNT; } -struct pi_protocol on26 = {"on26",0,5,2,1,1, - on26_write_regr, - on26_read_regr, - on26_write_block, - on26_read_block, - on26_connect, - on26_disconnect, - on26_test_port, - 0, - 0, - on26_log_adapter, - on26_init_proto, - on26_release_proto - }; - - -#ifdef MODULE - -int init_module(void) - -{ return pi_register( &on26 ) - 1; +static struct pi_protocol on26 = { + .name = "on26", + .max_mode = 5, + .epp_first = 2, + .default_delay = 1, + .max_units = 1, + .write_regr = on26_write_regr, + .read_regr = on26_read_regr, + .write_block = on26_write_block, + .read_block = on26_read_block, + .connect = on26_connect, + .disconnect = on26_disconnect, + .test_port = on26_test_port, + .log_adapter = on26_log_adapter, + .init_proto = on26_init_proto, + .release_proto = on26_release_proto, +}; + +static int __init on26_init(void) +{ + return pi_register(&on26)-1; } -void cleanup_module(void) - -{ pi_unregister( &on26 ); +static void __exit on26_exit(void) +{ + pi_unregister(&on26); } -#endif - -/* end of on26.c */ - MODULE_LICENSE("GPL"); +module_init(on26_init) +module_exit(on26_exit) diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c index e3a6150acff6..18bd7892269c 100644 --- a/drivers/block/paride/paride.c +++ b/drivers/block/paride/paride.c @@ -431,136 +431,3 @@ int pi_init(PIA *pi, int autoprobe, int port, int mode, } EXPORT_SYMBOL(pi_init); - -#ifdef MODULE - -int init_module(void) - -{ - int k; - const char *indicate_pp = ""; -#ifdef CONFIG_PARPORT - indicate_pp = " (parport)"; -#endif - - for (k=0;k +#include #include #include #include @@ -200,9 +201,6 @@ MODULE_PARM(drive3,"1-6i"); #define IDE_READY 0x40 #define IDE_BUSY 0x80 -int pcd_init(void); -void cleanup_module( void ); - static int pcd_open(struct cdrom_device_info *cdi, int purpose); static void pcd_release(struct cdrom_device_info *cdi); static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr); @@ -327,84 +325,18 @@ static void pcd_init_units( void ) } } -int pcd_init (void) /* preliminary initialisation */ -{ - int unit; - - if (disable) return -1; - - pcd_init_units(); - - if (pcd_detect()) return -1; - - /* get the atapi capabilities page */ - pcd_probe_capabilities(); - - if (register_blkdev(MAJOR_NR,name,&pcd_bdops)) { - printk("pcd: unable to get major number %d\n",MAJOR_NR); - return -1; - } - - for (unit=0;unitdev); - - if ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV; - +{ + int unit = DEVICE_NR(cdi->dev); + if ((unit >= PCD_UNITS) || (!PCD.present)) + return -ENODEV; return 0; } static void pcd_release(struct cdrom_device_info *cdi) - { } -#ifdef MODULE - -/* Glue for modules ... */ - -int init_module(void) - -{ int err; - -#ifdef PARIDE_JUMBO - { extern paride_init(); - paride_init(); - } -#endif - - err = pcd_init(); - - return err; -} - -void cleanup_module(void) - -{ int unit; - - for (unit=0;unit #include -#include #include -#include -#include #include -#include #include #include /* for the eject ioctl */ -#include #include @@ -181,8 +177,8 @@ static STT pd_stt[7] = {{"drive0",8,drive0}, {"nice",1,&nice}}; void pd_setup( char *str, int *ints) - -{ generic_setup(pd_stt,7,str); +{ + generic_setup(pd_stt,7,str); } #endif @@ -199,19 +195,15 @@ MODULE_PARM(drive3,"1-8i"); #include "paride.h" -#define PD_BITS 4 - -/* set up defines for blk.h, why don't all drivers do it this way ? */ - #define MAJOR_NR major -#define DEVICE_NR(device) (minor(device)>>PD_BITS) -#define DEVICE_OFF(device) #include #include #include "pseudo.h" +#define PD_BITS 4 +#define DEVICE_NR(device) (minor(device)>>PD_BITS) #define PD_PARTNS (1<i_rdev); @@ -433,11 +387,8 @@ static int pd_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg) { struct hd_geometry *geo = (struct hd_geometry *) arg; - int err, unit; + int err, unit = DEVICE_NR(inode->i_rdev); - if (!inode || kdev_none(inode->i_rdev)) - return -EINVAL; - unit = DEVICE_NR(inode->i_rdev); if (!PD.present) return -ENODEV; @@ -475,24 +426,19 @@ static int pd_release (struct inode *inode, struct file *file) { int unit = DEVICE_NR(inode->i_rdev); - if ((unit >= PD_UNITS) || (PD.access <= 0)) - return -EINVAL; - - PD.access--; - - if (!PD.access && PD.removable) + if (!--PD.access && PD.removable) pd_doorlock(unit,IDE_DOORUNLOCK); return 0; } static int pd_check_media( kdev_t dev) - -{ int r, unit; - - unit = DEVICE_NR(dev); - if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV; - if (!PD.removable) return 0; +{ + int r, unit = DEVICE_NR(dev); + if ((unit >= PD_UNITS) || (!PD.present)) + return -ENODEV; + if (!PD.removable) + return 0; pd_media_check(unit); r = PD.changed; PD.changed = 0; @@ -521,37 +467,6 @@ static int pd_revalidate(kdev_t dev) return res; } -#ifdef MODULE - -/* Glue for modules ... */ - -void cleanup_module(void); - -int init_module(void) - -{ - -#ifdef PARIDE_JUMBO - { extern paride_init(); - paride_init(); - } -#endif - return pd_init(); -} - -void cleanup_module(void) -{ - int unit; - - devfs_unregister_blkdev(MAJOR_NR, name); - del_gendisk(&pd_gendisk); - - for (unit=0; unit>= 8) & 255; + c1 = (block >>= 8) & 255; + h = ((block >>= 8) & 15) + 0x40; + } else { + s = ( block % PD.sectors) + 1; + h = ( block /= PD.sectors) % PD.heads; + c0 = ( block /= PD.heads) % 256; + c1 = (block >>= 8); + } pd_send_command(unit,count,s,h,c0,c1,func); } @@ -723,10 +641,14 @@ static int pd_identify( int unit ) } pi_read_block(PI,pd_scratch,512); pi_disconnect(PI); - PD.sectors = word_val(6); - PD.heads = word_val(3); - PD.cylinders = word_val(1); - PD.capacity = PD.sectors*PD.heads*PD.cylinders; + PD.can_lba = pd_scratch[99] & 2; + PD.sectors = le16_to_cpu(*(u16*)(pd_scratch+12)); + PD.heads = le16_to_cpu(*(u16*)(pd_scratch+6)); + PD.cylinders = le16_to_cpu(*(u16*)(pd_scratch+2)); + if (PD.can_lba) + PD.capacity = le32_to_cpu(*(u32*)(pd_scratch + 120)); + else + PD.capacity = PD.sectors*PD.heads*PD.cylinders; for(j=0;j -#include +#include #include -#include #include -#include #include #include #include @@ -240,7 +238,6 @@ MODULE_PARM(drive3,"1-7i"); #define ATAPI_READ_10 0x28 #define ATAPI_WRITE_10 0x2a -int pf_init(void); #ifdef MODULE void cleanup_module( void ); #endif @@ -337,34 +334,6 @@ void pf_init_units( void ) } } -int pf_init (void) /* preliminary initialisation */ - -{ int i; - request_queue_t * q; - - if (disable) return -1; - - pf_init_units(); - - if (pf_detect()) return -1; - pf_busy = 0; - - if (register_blkdev(MAJOR_NR,name,&pf_fops)) { - printk("pf_init: unable to get major number %d\n", - major); - return -1; - } - q = BLK_DEFAULT_QUEUE(MAJOR_NR); - blk_init_queue(q, do_pf_request, &pf_spin_lock); - blk_queue_max_phys_segments(q, cluster); - blk_queue_max_hw_segments(q, cluster); - - for (i=0;ii_rdev); @@ -454,39 +423,6 @@ static int pf_check_media( kdev_t dev) { return 1; } -#ifdef MODULE - -/* Glue for modules ... */ - -void cleanup_module(void); - -int init_module(void) - -{ int err; - -#ifdef PARIDE_JUMBO - { extern paride_init(); - paride_init(); - } -#endif - - err = pf_init(); - - return err; -} - -void cleanup_module(void) - -{ int unit; - - unregister_blkdev(MAJOR_NR,name); - - for (unit=0;unit -#include +#include #include #include -#include #include #include #include #include -#include -#include #include @@ -218,11 +215,6 @@ MODULE_PARM(drive3,"1-6i"); #define ATAPI_IDENTIFY 0x12 -int pg_init(void); -#ifdef MODULE -void cleanup_module( void ); -#endif - static int pg_open(struct inode *inode, struct file *file); static int pg_release (struct inode *inode, struct file *file); static ssize_t pg_read(struct file * filp, char * buf, @@ -291,64 +283,6 @@ void pg_init_units( void ) static devfs_handle_t devfs_handle; -int pg_init (void) /* preliminary initialisation */ - -{ int unit; - - if (disable) return -1; - - pg_init_units(); - - if (pg_detect()) return -1; - - if (devfs_register_chrdev(major,name,&pg_fops)) { - printk("pg_init: unable to get major number %d\n", - major); - for (unit=0;unit -#include +#include #include #include -#include #include #include #include -#include -#include #include @@ -209,11 +206,6 @@ MODULE_PARM(drive3,"1-6i"); #define ATAPI_MODE_SENSE 0x1a #define ATAPI_LOG_SENSE 0x4d -int pt_init(void); -#ifdef MODULE -void cleanup_module( void ); -#endif - static int pt_open(struct inode *inode, struct file *file); static int pt_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg); @@ -291,71 +283,9 @@ void pt_init_units( void ) PT.name[j] = 0; if (DU[D_PRT]) pt_drive_count++; } -} - -static devfs_handle_t devfs_handle; - -int pt_init (void) /* preliminary initialisation */ - -{ int unit; - - if (disable) return -1; - - pt_init_units(); - - if (pt_detect()) return -1; - - if (devfs_register_chrdev(major,name,&pt_fops)) { - printk("pt_init: unable to get major number %d\n", - major); - for (unit=0;unit Date: Sun, 21 Jul 2002 02:11:12 -0700 Subject: [PATCH] "big IRQ lock" removal, IRQ cleanups This is a massive cleanup of the IRQ subsystem. It's losely based on Linus' original idea and DaveM's original implementation, to fold our various irq, softirq and bh counters into the preemption counter. with this approach it was possible: - to remove the 'big IRQ lock' on SMP - on which sti() and cli() relied. - to streamline/simplify arch/i386/kernel/irq.c significantly. - to simplify the softirq code. - to remove the preemption count increase/decrease code from the lowlevel IRQ assembly code. - to speed up schedule() a bit. Global sti() and cli() is gone forever on SMP, there is no more globally synchronizing irq-disabling capability. All code that relied on sti() and cli() and restore_flags() must use other locking mechanisms from now on (spinlocks and __cli()/__sti()). obviously this patch breaks massive amounts of code, so only limited .configs are working at the moment (UP is expected to be unaffected, but SMP will require various driver updates). The patch was developed and tested on SMP systems, and while the code is still a bit rough in places, the base IRQ code appears to be pretty robust and clean. while it boots already so the worst is over, there is lots of work left: eg. to fix the serial layer to not use cli()/sti() and bhs ... --- arch/i386/kernel/apic.c | 4 +- arch/i386/kernel/apm.c | 42 ++++--- arch/i386/kernel/entry.S | 9 +- arch/i386/kernel/i386_ksyms.c | 8 +- arch/i386/kernel/io_apic.c | 2 +- arch/i386/kernel/irq.c | 277 ++---------------------------------------- arch/i386/kernel/mca.c | 26 ++-- arch/i386/kernel/nmi.c | 2 +- arch/i386/kernel/process.c | 2 +- arch/i386/kernel/smpboot.c | 1 - arch/i386/kernel/vm86.c | 19 +-- arch/i386/mm/fault.c | 30 +++-- drivers/block/genhd.c | 1 - drivers/block/ll_rw_blk.c | 3 - drivers/char/n_tty.c | 4 +- drivers/char/tty_io.c | 13 +- drivers/char/tty_ioctl.c | 4 +- drivers/char/vt.c | 6 +- drivers/ide/main.c | 10 +- drivers/net/eepro100.c | 2 +- include/asm-generic/smplock.h | 3 +- include/asm-i386/hardirq.h | 76 ++---------- include/asm-i386/smplock.h | 14 +-- include/asm-i386/softirq.h | 55 +++------ include/asm-i386/system.h | 26 ++-- include/linux/irq_cpustat.h | 2 - include/linux/preempt.h | 46 +++++++ include/linux/smp_lock.h | 2 +- include/linux/spinlock.h | 37 +----- init/main.c | 2 +- kernel/exit.c | 4 +- kernel/panic.c | 2 +- kernel/sched.c | 9 +- kernel/softirq.c | 16 +-- net/core/skbuff.c | 2 +- sound/pci/intel8x0.c | 4 +- 36 files changed, 209 insertions(+), 556 deletions(-) create mode 100644 include/linux/preempt.h (limited to 'drivers/block') diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index c86358a1249f..15ba757d2d6b 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -1084,9 +1084,9 @@ void smp_apic_timer_interrupt(struct pt_regs regs) * Besides, if we don't timer interrupts ignore the global * interrupt lock, which is the WrongThing (tm) to do. */ - irq_enter(cpu, 0); + irq_enter(); smp_local_timer_interrupt(®s); - irq_exit(cpu, 0); + irq_exit(); if (softirq_pending(cpu)) do_softirq(); diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 11c3c42185cd..7202bc4ac19d 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -222,6 +222,8 @@ #include +extern rwlock_t xtime_lock; +extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -1141,40 +1143,25 @@ out: static void set_time(void) { - unsigned long flags; - - if (got_clock_diff) { /* Must know time zone in order to set clock */ - save_flags(flags); - cli(); + if (got_clock_diff) /* Must know time zone in order to set clock */ CURRENT_TIME = get_cmos_time() + clock_cmos_diff; - restore_flags(flags); - } } static void get_time_diff(void) { #ifndef CONFIG_APM_RTC_IS_GMT - unsigned long flags; - /* * Estimate time zone so that set_time can update the clock */ - save_flags(flags); clock_cmos_diff = -get_cmos_time(); - cli(); clock_cmos_diff += CURRENT_TIME; got_clock_diff = 1; - restore_flags(flags); #endif } -static void reinit_timer(void) +static inline void reinit_timer(void) { #ifdef INIT_TIMER_AFTER_SUSPEND - unsigned long flags; - - save_flags(flags); - cli(); /* set the clock to 100 Hz */ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ udelay(10); @@ -1182,7 +1169,6 @@ static void reinit_timer(void) udelay(10); outb(LATCH >> 8 , 0x40); /* MSB */ udelay(10); - restore_flags(flags); #endif } @@ -1203,13 +1189,21 @@ static int suspend(int vetoable) } printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); } + /* serialize with the timer interrupt */ + write_lock_irq(&xtime_lock); + + /* protect against access to timer chip registers */ + spin_lock(&i8253_lock); + get_time_diff(); - cli(); err = set_system_power_state(APM_STATE_SUSPEND); reinit_timer(); set_time(); ignore_normal_resume = 1; - sti(); + + spin_unlock(&i8253_lock); + write_unlock_irq(&xtime_lock); + if (err == APM_NO_ERROR) err = APM_SUCCESS; if (err != APM_SUCCESS) @@ -1232,8 +1226,12 @@ static void standby(void) { int err; + /* serialize with the timer interrupt */ + write_lock_irq(&xtime_lock); /* If needed, notify drivers here */ get_time_diff(); + write_unlock_irq(&xtime_lock); + err = set_system_power_state(APM_STATE_STANDBY); if ((err != APM_SUCCESS) && (err != APM_NO_ERROR)) apm_error("standby", err); @@ -1321,7 +1319,9 @@ static void check_events(void) ignore_bounce = 1; if ((event != APM_NORMAL_RESUME) || (ignore_normal_resume == 0)) { + write_lock_irq(&xtime_lock); set_time(); + write_unlock_irq(&xtime_lock); pm_send_all(PM_RESUME, (void *)0); queue_event(event, NULL); } @@ -1336,7 +1336,9 @@ static void check_events(void) break; case APM_UPDATE_TIME: + write_lock_irq(&xtime_lock); set_time(); + write_unlock_irq(&xtime_lock); break; case APM_CRITICAL_SUSPEND: diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index c068803128c8..e5f506df8533 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -72,12 +72,8 @@ VM_MASK = 0x00020000 #ifdef CONFIG_PREEMPT #define preempt_stop cli -#define INC_PRE_COUNT(reg) incl TI_PRE_COUNT(reg); -#define DEC_PRE_COUNT(reg) decl TI_PRE_COUNT(reg); #else #define preempt_stop -#define INC_PRE_COUNT(reg) -#define DEC_PRE_COUNT(reg) #define resume_kernel restore_all #endif @@ -191,7 +187,6 @@ ENTRY(ret_from_fork) ALIGN ret_from_intr: preempt_stop - DEC_PRE_COUNT(%ebx) ret_from_exception: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al @@ -338,9 +333,8 @@ vector=vector+1 ALIGN common_interrupt: SAVE_ALL - GET_THREAD_INFO(%ebx) - INC_PRE_COUNT(%ebx) call do_IRQ + GET_THREAD_INFO(%ebx) jmp ret_from_intr #define BUILD_INTERRUPT(name, nr) \ @@ -348,7 +342,6 @@ ENTRY(name) \ pushl $nr-256; \ SAVE_ALL \ GET_THREAD_INFO(%ebx); \ - INC_PRE_COUNT(%ebx) \ call smp_/**/name; \ jmp ret_from_intr; diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 86ce6170a11d..04bbafb264ec 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -132,13 +132,7 @@ EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL_NOVERS(__write_lock_failed); EXPORT_SYMBOL_NOVERS(__read_lock_failed); -/* Global SMP irq stuff */ -EXPORT_SYMBOL(synchronize_irq); -EXPORT_SYMBOL(global_irq_holder); -EXPORT_SYMBOL(__global_cli); -EXPORT_SYMBOL(__global_sti); -EXPORT_SYMBOL(__global_save_flags); -EXPORT_SYMBOL(__global_restore_flags); +/* Global SMP stuff */ EXPORT_SYMBOL(smp_call_function); /* TLB flushing */ diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d09e00d867da..2862186fbd07 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1219,7 +1219,7 @@ static int __init timer_irq_works(void) { unsigned int t1 = jiffies; - sti(); + __sti(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 4265cb038a5a..0f61d288c37e 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -184,250 +184,12 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } -/* - * Global interrupt locks for SMP. Allow interrupts to come in on any - * CPU, yet make cli/sti act globally to protect critical regions.. - */ - -#ifdef CONFIG_SMP -unsigned char global_irq_holder = NO_PROC_ID; -unsigned volatile long global_irq_lock; /* pendantic: long for set_bit --RR */ - -extern void show_stack(unsigned long* esp); - -static void show(char * str) -{ - int i; - int cpu = smp_processor_id(); - - printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [",irqs_running()); - for(i=0;i < NR_CPUS;i++) - printk(" %d",local_irq_count(i)); - printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0); - for(i=0;i < NR_CPUS;i++) - printk(" %d",local_bh_count(i)); - - printk(" ]\nStack dumps:"); - for(i = 0; i < NR_CPUS; i++) { - unsigned long esp; - if (i == cpu) - continue; - printk("\nCPU %d:",i); - esp = init_tss[i].esp0; - if (!esp) { - /* tss->esp0 is set to NULL in cpu_init(), - * it's initialized when the cpu returns to user - * space. -- manfreds - */ - printk(" "); - continue; - } - esp &= ~(THREAD_SIZE-1); - esp += sizeof(struct thread_info); - show_stack((void*)esp); - } - printk("\nCPU %d:",cpu); - show_stack(NULL); - printk("\n"); -} - -#define MAXCOUNT 100000000 - -/* - * I had a lockup scenario where a tight loop doing - * spin_unlock()/spin_lock() on CPU#1 was racing with - * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but - * apparently the spin_unlock() information did not make it - * through to CPU#0 ... nasty, is this by design, do we have to limit - * 'memory update oscillation frequency' artificially like here? - * - * Such 'high frequency update' races can be avoided by careful design, but - * some of our major constructs like spinlocks use similar techniques, - * it would be nice to clarify this issue. Set this define to 0 if you - * want to check whether your system freezes. I suspect the delay done - * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but - * i thought that such things are guaranteed by design, since we use - * the 'LOCK' prefix. - */ -#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0 - -#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND -# define SYNC_OTHER_CORES(x) udelay(x+1) -#else -/* - * We have to allow irqs to arrive between __sti and __cli - */ -# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop") -#endif - -static inline void wait_on_irq(int cpu) -{ - int count = MAXCOUNT; - - for (;;) { - - /* - * Wait until all interrupts are gone. Wait - * for bottom half handlers unless we're - * already executing in one.. - */ - if (!irqs_running()) - if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) - break; - - /* Duh, we have to loop. Release the lock to avoid deadlocks */ - clear_bit(0,&global_irq_lock); - - for (;;) { - if (!--count) { - show("wait_on_irq"); - count = ~0; - } - __sti(); - SYNC_OTHER_CORES(cpu); - __cli(); - if (irqs_running()) - continue; - if (global_irq_lock) - continue; - if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) - continue; - if (!test_and_set_bit(0,&global_irq_lock)) - break; - } - } -} - -/* - * This is called when we want to synchronize with - * interrupts. We may for example tell a device to - * stop sending interrupts: but to make sure there - * are no interrupts that are executing on another - * CPU we need to call this function. - */ -void synchronize_irq(void) -{ - if (irqs_running()) { - /* Stupid approach */ - cli(); - sti(); - } -} - -static inline void get_irqlock(int cpu) -{ - if (test_and_set_bit(0,&global_irq_lock)) { - /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait.. */ - do { - do { - rep_nop(); - } while (test_bit(0,&global_irq_lock)); - } while (test_and_set_bit(0,&global_irq_lock)); - } - /* - * We also to make sure that nobody else is running - * in an interrupt context. - */ - wait_on_irq(cpu); - - /* - * Ok, finally.. - */ - global_irq_holder = cpu; -} - -#define EFLAGS_IF_SHIFT 9 - -/* - * A global "cli()" while in an interrupt context - * turns into just a local cli(). Interrupts - * should use spinlocks for the (very unlikely) - * case that they ever want to protect against - * each other. - * - * If we already have local interrupts disabled, - * this will not turn a local disable into a - * global one (problems with spinlocks: this makes - * save_flags+cli+sti usable inside a spinlock). - */ -void __global_cli(void) -{ - unsigned int flags; - - __save_flags(flags); - if (flags & (1 << EFLAGS_IF_SHIFT)) { - int cpu; - __cli(); - cpu = smp_processor_id(); - if (!local_irq_count(cpu)) - get_irqlock(cpu); - } -} - -void __global_sti(void) -{ - int cpu = get_cpu(); - - if (!local_irq_count(cpu)) - release_irqlock(cpu); - __sti(); - put_cpu(); -} - -/* - * SMP flags value to restore to: - * 0 - global cli - * 1 - global sti - * 2 - local cli - * 3 - local sti - */ -unsigned long __global_save_flags(void) -{ - int retval; - int local_enabled; - unsigned long flags; - int cpu = smp_processor_id(); - - __save_flags(flags); - local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1; - /* default to local */ - retval = 2 + local_enabled; - - /* check for global flags if we're not in an interrupt */ - if (!local_irq_count(cpu)) { - if (local_enabled) - retval = 1; - if (global_irq_holder == cpu) - retval = 0; - } - return retval; -} - -void __global_restore_flags(unsigned long flags) +#if CONFIG_SMP +inline void synchronize_irq(unsigned int irq) { - switch (flags) { - case 0: - __global_cli(); - break; - case 1: - __global_sti(); - break; - case 2: - __cli(); - break; - case 3: - __sti(); - break; - default: - printk("global_restore_flags: %08lx (%08lx)\n", - flags, (&flags)[-1]); - } + while (irq_desc[irq].status & IRQ_INPROGRESS) + cpu_relax(); } - #endif /* @@ -439,12 +201,7 @@ void __global_restore_flags(unsigned long flags) */ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) { - int status; - int cpu = smp_processor_id(); - - irq_enter(cpu, irq); - - status = 1; /* Force the "do bottom halves" bit */ + int status = 1; /* Force the "do bottom halves" bit */ if (!(action->flags & SA_INTERRUPT)) __sti(); @@ -458,8 +215,6 @@ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * add_interrupt_randomness(irq); __cli(); - irq_exit(cpu, irq); - return status; } @@ -511,13 +266,7 @@ inline void disable_irq_nosync(unsigned int irq) void disable_irq(unsigned int irq) { disable_irq_nosync(irq); - - if (!local_irq_count(smp_processor_id())) { - do { - barrier(); - cpu_relax(); - } while (irq_desc[irq].status & IRQ_INPROGRESS); - } + synchronize_irq(irq); } /** @@ -581,6 +330,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) struct irqaction * action; unsigned int status; + irq_enter(); kstat.irqs[cpu][irq]++; spin_lock(&desc->lock); desc->handler->ack(irq); @@ -640,6 +390,8 @@ out: desc->handler->end(irq); spin_unlock(&desc->lock); + irq_exit(); + if (softirq_pending(cpu)) do_softirq(); return 1; @@ -768,13 +520,8 @@ void free_irq(unsigned int irq, void *dev_id) } spin_unlock_irqrestore(&desc->lock,flags); -#ifdef CONFIG_SMP /* Wait to make sure it's not being used on another CPU */ - while (desc->status & IRQ_INPROGRESS) { - barrier(); - cpu_relax(); - } -#endif + synchronize_irq(irq); kfree(action); return; } @@ -826,7 +573,7 @@ unsigned long probe_irq_on(void) /* Wait for longstanding interrupts to trigger. */ for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) - /* about 20ms delay */ synchronize_irq(); + /* about 20ms delay */ barrier(); /* * enable any unassigned irqs @@ -849,7 +596,7 @@ unsigned long probe_irq_on(void) * Wait for spurious interrupts to trigger */ for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) - /* about 100ms delay */ synchronize_irq(); + /* about 100ms delay */ barrier(); /* * Now filter out any obviously spurious interrupts diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c index dc7db1cdce4c..067dafca3a6c 100644 --- a/arch/i386/kernel/mca.c +++ b/arch/i386/kernel/mca.c @@ -102,6 +102,12 @@ struct MCA_info { static struct MCA_info* mca_info = NULL; +/* + * Motherboard register spinlock. Untested on SMP at the moment, but + * are there any MCA SMP boxes? + */ +static spinlock_t mca_lock = SPIN_LOCK_UNLOCKED; + /* MCA registers */ #define MCA_MOTHERBOARD_SETUP_REG 0x94 @@ -213,8 +219,11 @@ void __init mca_init(void) } memset(mca_info, 0, sizeof(struct MCA_info)); - save_flags(flags); - cli(); + /* + * We do not expect many MCA interrupts during initialization, + * but let us be safe: + */ + spin_lock_irq(&mca_lock); /* Make sure adapter setup is off */ @@ -300,8 +309,7 @@ void __init mca_init(void) outb_p(0, MCA_ADAPTER_SETUP_REG); /* Enable interrupts and return memory start */ - - restore_flags(flags); + spin_unlock_irq(&mca_lock); for (i = 0; i < MCA_STANDARD_RESOURCES; i++) request_resource(&ioport_resource, mca_standard_resources + i); @@ -514,8 +522,7 @@ unsigned char mca_read_pos(int slot, int reg) if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0; if(reg < 0 || reg >= 8) return 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&mca_lock, flags); /* Make sure motherboard setup is off */ @@ -566,7 +573,7 @@ unsigned char mca_read_pos(int slot, int reg) mca_info->slot[slot].pos[reg] = byte; - restore_flags(flags); + spin_unlock_irqrestore(&mca_lock, flags); return byte; } /* mca_read_pos() */ @@ -610,8 +617,7 @@ void mca_write_pos(int slot, int reg, unsigned char byte) if(mca_info == NULL) return; - save_flags(flags); - cli(); + spin_lock_irqsave(&mca_lock, flags); /* Make sure motherboard setup is off */ @@ -623,7 +629,7 @@ void mca_write_pos(int slot, int reg, unsigned char byte) outb_p(byte, MCA_POS_REG(reg)); outb_p(0, MCA_ADAPTER_SETUP_REG); - restore_flags(flags); + spin_unlock_irqrestore(&mca_lock, flags); /* Update the global register list, while we have the byte */ diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index a2447287092d..679e63e9d2cb 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -78,7 +78,7 @@ int __init check_nmi_watchdog (void) printk(KERN_INFO "testing NMI watchdog ... "); memcpy(tmp, irq_stat, sizeof(tmp)); - sti(); + __sti(); mdelay((10*1000)/nmi_hz); // wait 10 ticks for (cpu = 0; cpu < NR_CPUS; cpu++) { diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 57bc712dbc66..24aed22022a3 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -290,7 +290,7 @@ void machine_real_restart(unsigned char *code, int length) { unsigned long flags; - cli(); + __cli(); /* Write zero to CMOS register number 0x0f, which the BIOS POST routine will recognize as telling it to do a proper reboot. (Well diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index d77a1fb38d0f..178e3431ab9e 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1060,7 +1060,6 @@ void __init smp_boot_cpus(void) boot_cpu_logical_apicid = logical_smp_processor_id(); map_cpu_to_boot_apicid(0, boot_cpu_apicid); - global_irq_holder = NO_PROC_ID; current_thread_info()->cpu = 0; smp_tune_scheduling(); diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 195a2b943908..7c60b661f713 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -571,6 +571,8 @@ static struct vm86_irqs { struct task_struct *tsk; int sig; } vm86_irqs[16]; + +static spinlock_t irqbits_lock = SPIN_LOCK_UNLOCKED; static int irqbits; #define ALLOWED_SIGS ( 1 /* 0 = don't send a signal */ \ @@ -580,9 +582,8 @@ static int irqbits; static void irq_handler(int intno, void *dev_id, struct pt_regs * regs) { int irq_bit; unsigned long flags; - - save_flags(flags); - cli(); + + spin_lock_irqsave(&irqbits_lock, flags); irq_bit = 1 << intno; if ((irqbits & irq_bit) || ! vm86_irqs[intno].tsk) goto out; @@ -591,14 +592,19 @@ static void irq_handler(int intno, void *dev_id, struct pt_regs * regs) { send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1); /* else user will poll for IRQs */ out: - restore_flags(flags); + spin_unlock_irqrestore(&irqbits_lock, flags); } static inline void free_vm86_irq(int irqnumber) { + unsigned long flags; + free_irq(irqnumber,0); vm86_irqs[irqnumber].tsk = 0; + + spin_lock_irqsave(&irqbits_lock, flags); irqbits &= ~(1 << irqnumber); + spin_unlock_irqrestore(&irqbits_lock, flags); } static inline int task_valid(struct task_struct *tsk) @@ -635,11 +641,10 @@ static inline int get_and_reset_irq(int irqnumber) if ( (irqnumber<3) || (irqnumber>15) ) return 0; if (vm86_irqs[irqnumber].tsk != current) return 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&irqbits_lock, flags); bit = irqbits & (1 << irqnumber); irqbits &= ~bit; - restore_flags(flags); + spin_unlock_irqrestore(&irqbits_lock, flags); return bit; } diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 474009886b35..8c4328690ebe 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -107,27 +107,25 @@ extern spinlock_t timerlist_lock; */ void bust_spinlocks(int yes) { + int loglevel_save = console_loglevel; + spin_lock_init(&timerlist_lock); if (yes) { oops_in_progress = 1; -#ifdef CONFIG_SMP - global_irq_lock = 0; /* Many serial drivers do __global_cli() */ -#endif - } else { - int loglevel_save = console_loglevel; + return; + } #ifdef CONFIG_VT - unblank_screen(); + unblank_screen(); #endif - oops_in_progress = 0; - /* - * OK, the message is on the console. Now we call printk() - * without oops_in_progress set so that printk will give klogd - * a poke. Hold onto your hats... - */ - console_loglevel = 15; /* NMI oopser may have shut the console up */ - printk(" "); - console_loglevel = loglevel_save; - } + oops_in_progress = 0; + /* + * OK, the message is on the console. Now we call printk() + * without oops_in_progress set so that printk will give klogd + * a poke. Hold onto your hats... + */ + console_loglevel = 15; /* NMI oopser may have shut the console up */ + printk(" "); + console_loglevel = loglevel_save; } asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 6bb06af38980..0fc011f610d1 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -184,7 +184,6 @@ int __init device_init(void) { rwlock_init(&gendisk_lock); blk_dev_init(); - sti(); #ifdef CONFIG_I2O i2o_init(); #endif diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 8ada278181c8..c23f57a0ed16 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -2041,9 +2041,6 @@ int __init blk_dev_init(void) #if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD) hd_init(); #endif -#if defined(__i386__) /* Do we even need this? */ - outb_p(0xc, 0x3f2); -#endif return 0; }; diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index d748d499da60..7cf8fb5cfcb5 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -807,7 +807,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || I_PARMRK(tty)) { - cli(); + __cli(); // FIXME: is this safe? memset(tty->process_char_map, 0, 256/8); if (I_IGNCR(tty) || I_ICRNL(tty)) @@ -843,7 +843,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) set_bit(SUSP_CHAR(tty), tty->process_char_map); } clear_bit(__DISABLED_CHAR, tty->process_char_map); - sti(); + __sti(); // FIXME: is this safe? tty->raw = 0; tty->real_raw = 0; } else { diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 6789e5ecf6b5..59567e8b8fa6 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -456,11 +456,12 @@ void do_tty_hangup(void *data) } file_list_unlock(); - /* FIXME! What are the locking issues here? This may me overdoing things.. */ + /* FIXME! What are the locking issues here? This may me overdoing things.. + * this question is especially important now that we've removed the irqlock. */ { unsigned long flags; - save_flags(flags); cli(); + __save_flags(flags); __cli(); // FIXME: is this safe? if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); if (tty->driver.flush_buffer) @@ -468,7 +469,7 @@ void do_tty_hangup(void *data) if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); - restore_flags(flags); + __restore_flags(flags); // FIXME: is this safe? } wake_up_interruptible(&tty->write_wait); @@ -1900,7 +1901,7 @@ static void flush_to_ldisc(void *private_) fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; tty->flip.buf_num = 0; - save_flags(flags); cli(); + __save_flags(flags); __cli(); // FIXME: is this safe? tty->flip.char_buf_ptr = tty->flip.char_buf; tty->flip.flag_buf_ptr = tty->flip.flag_buf; } else { @@ -1908,13 +1909,13 @@ static void flush_to_ldisc(void *private_) fp = tty->flip.flag_buf; tty->flip.buf_num = 1; - save_flags(flags); cli(); + __save_flags(flags); __cli(); // FIXME: is this safe? tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE; tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; } count = tty->flip.count; tty->flip.count = 0; - restore_flags(flags); + __restore_flags(flags); // FIXME: is this safe? tty->ldisc.receive_buf(tty, cp, fp, count); } diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 6fe1ef20e409..68662c975de4 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -97,7 +97,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios int canon_change; struct termios old_termios = *tty->termios; - cli(); + __cli(); // FIXME: is this safe? *tty->termios = *new_termios; unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; @@ -107,7 +107,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios tty->canon_data = 0; tty->erasing = 0; } - sti(); + __sti(); // FIXME: is this safe? if (canon_change && !L_ICANON(tty) && tty->read_cnt) /* Get characters left over from canonical mode. */ wake_up_interruptible(&tty->read_wait); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index e59c0cef09e7..87a0b5904263 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -113,8 +113,8 @@ _kd_mksound(unsigned int hz, unsigned int ticks) if (hz > 20 && hz < 32767) count = 1193180 / hz; - save_flags(flags); - cli(); + __save_flags(flags); // FIXME: is this safe? + __cli(); del_timer(&sound_timer); if (count) { /* enable counter 2 */ @@ -131,7 +131,7 @@ _kd_mksound(unsigned int hz, unsigned int ticks) } } else kd_nosound(0); - restore_flags(flags); + __restore_flags(flags); return; } diff --git a/drivers/ide/main.c b/drivers/ide/main.c index 2f5f34953263..6c09337f334f 100644 --- a/drivers/ide/main.c +++ b/drivers/ide/main.c @@ -1082,18 +1082,18 @@ int ide_unregister_subdriver(struct ata_device *drive) { unsigned long flags; - save_flags(flags); /* all CPUs */ - cli(); /* all CPUs */ + __save_flags(flags); // FIXME: is this safe? + __cli(); #if 0 if (__MOD_IN_USE(ata_ops(drive)->owner)) { - restore_flags(flags); + __restore_flags(flags); // FIXME: is this safe? return 1; } #endif if (drive->usage || drive->busy || !ata_ops(drive)) { - restore_flags(flags); /* all CPUs */ + __restore_flags(flags); // FIXME: is this safe? return 1; } @@ -1102,7 +1102,7 @@ int ide_unregister_subdriver(struct ata_device *drive) #endif drive->driver = NULL; - restore_flags(flags); /* all CPUs */ + __restore_flags(flags); // FIXME: is this safe? return 0; } diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index cd6524d58341..485a0a319a98 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -1354,7 +1354,7 @@ static void speedo_tx_timeout(struct net_device *dev) udelay(10); /* Disable interrupts. */ outw(SCBMaskAll, ioaddr + SCBCmd); - synchronize_irq(); + synchronize_irq(dev->irq); speedo_tx_buffer_gc(dev); /* Free as much as possible. It helps to recover from a hang because of out-of-memory. diff --git a/include/asm-generic/smplock.h b/include/asm-generic/smplock.h index 96565069c988..d77431f2cb25 100644 --- a/include/asm-generic/smplock.h +++ b/include/asm-generic/smplock.h @@ -13,11 +13,10 @@ extern spinlock_t kernel_flag; /* * Release global kernel lock and global interrupt lock */ -#define release_kernel_lock(task, cpu) \ +#define release_kernel_lock(task) \ do { \ if (task->lock_depth >= 0) \ spin_unlock(&kernel_flag); \ - release_irqlock(cpu); \ __sti(); \ } while (0) diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h index ed73b0444f6b..cbd78d1dcaa1 100644 --- a/include/asm-i386/hardirq.h +++ b/include/asm-i386/hardirq.h @@ -8,8 +8,6 @@ /* assembly code in softirq.h is sensitive to the offsets of these fields */ typedef struct { unsigned int __softirq_pending; - unsigned int __local_irq_count; - unsigned int __local_bh_count; unsigned int __syscall_count; struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ unsigned long idle_timestamp; @@ -18,77 +16,27 @@ typedef struct { #include /* Standard mappings for irq_cpustat_t above */ +#define IRQ_OFFSET 64 + /* * Are we in an interrupt context? Either doing bottom half * or hardware interrupt processing? */ -#define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) - -#define in_irq() (local_irq_count(smp_processor_id()) != 0) - -#ifndef CONFIG_SMP - -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { } while (0) +#define in_interrupt() \ + ((preempt_count() & ~PREEMPT_ACTIVE) >= IRQ_OFFSET) -#define irq_enter(cpu, irq) (local_irq_count(cpu)++) -#define irq_exit(cpu, irq) (local_irq_count(cpu)--) +#define in_irq in_interrupt -#define synchronize_irq() barrier() +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) -#define release_irqlock(cpu) do { } while (0) +#define irq_enter() (preempt_count() += IRQ_OFFSET) +#define irq_exit() (preempt_count() -= IRQ_OFFSET) +#ifndef CONFIG_SMP +# define synchronize_irq(irq) barrier() #else - -#include -#include - -extern unsigned char global_irq_holder; -extern unsigned volatile long global_irq_lock; /* long for set_bit -RR */ - -static inline int irqs_running (void) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - if (local_irq_count(i)) - return 1; - return 0; -} - -static inline void release_irqlock(int cpu) -{ - /* if we didn't own the irq lock, just ignore.. */ - if (global_irq_holder == (unsigned char) cpu) { - global_irq_holder = NO_PROC_ID; - clear_bit(0,&global_irq_lock); - } -} - -static inline void irq_enter(int cpu, int irq) -{ - ++local_irq_count(cpu); - - while (test_bit(0,&global_irq_lock)) { - cpu_relax(); - } -} - -static inline void irq_exit(int cpu, int irq) -{ - --local_irq_count(cpu); -} - -static inline int hardirq_trylock(int cpu) -{ - return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock); -} - -#define hardirq_endlock(cpu) do { } while (0) - -extern void synchronize_irq(void); - + extern void synchronize_irq(unsigned int irq); #endif /* CONFIG_SMP */ #endif /* __ASM_HARDIRQ_H */ diff --git a/include/asm-i386/smplock.h b/include/asm-i386/smplock.h index 888a7b82f103..8bee3fd434c0 100644 --- a/include/asm-i386/smplock.h +++ b/include/asm-i386/smplock.h @@ -12,15 +12,9 @@ extern spinlock_t kernel_flag; #ifdef CONFIG_SMP #define kernel_locked() spin_is_locked(&kernel_flag) -#define check_irq_holder(cpu) \ -do { \ - if (global_irq_holder == (cpu)) \ - BUG(); \ -} while(0) #else #ifdef CONFIG_PREEMPT -#define kernel_locked() preempt_get_count() -#define check_irq_holder(cpu) do { } while(0) +#define kernel_locked() preempt_count() #else #define kernel_locked() 1 #endif @@ -29,12 +23,10 @@ do { \ /* * Release global kernel lock and global interrupt lock */ -#define release_kernel_lock(task, cpu) \ +#define release_kernel_lock(task) \ do { \ - if (unlikely(task->lock_depth >= 0)) { \ + if (unlikely(task->lock_depth >= 0)) \ spin_unlock(&kernel_flag); \ - check_irq_holder(cpu); \ - } \ } while (0) /* diff --git a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h index c62cbece6ce7..c28019d821af 100644 --- a/include/asm-i386/softirq.h +++ b/include/asm-i386/softirq.h @@ -1,50 +1,27 @@ #ifndef __ASM_SOFTIRQ_H #define __ASM_SOFTIRQ_H -#include +#include #include -#define __cpu_bh_enable(cpu) \ - do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0) -#define cpu_bh_disable(cpu) \ - do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0) +#define local_bh_disable() \ + do { preempt_count() += IRQ_OFFSET; barrier(); } while (0) +#define __local_bh_enable() \ + do { barrier(); preempt_count() -= IRQ_OFFSET; } while (0) -#define local_bh_disable() cpu_bh_disable(smp_processor_id()) -#define __local_bh_enable() __cpu_bh_enable(smp_processor_id()) - -#define in_softirq() (local_bh_count(smp_processor_id()) != 0) - -/* - * NOTE: this assembly code assumes: - * - * (char *)&local_bh_count - 8 == (char *)&softirq_pending - * - * If you change the offsets in irq_stat then you have to - * update this code as well. - */ -#define _local_bh_enable() \ +#define local_bh_enable() \ do { \ - unsigned int *ptr = &local_bh_count(smp_processor_id()); \ - \ - barrier(); \ - if (!--*ptr) \ - __asm__ __volatile__ ( \ - "cmpl $0, -8(%0);" \ - "jnz 2f;" \ - "1:;" \ - \ - LOCK_SECTION_START("") \ - "2: pushl %%eax; pushl %%ecx; pushl %%edx;" \ - "call %c1;" \ - "popl %%edx; popl %%ecx; popl %%eax;" \ - "jmp 1b;" \ - LOCK_SECTION_END \ - \ - : /* no output */ \ - : "r" (ptr), "i" (do_softirq) \ - /* no registers clobbered */ ); \ + if (unlikely((preempt_count() == IRQ_OFFSET) && \ + softirq_pending(smp_processor_id()))) { \ + __local_bh_enable(); \ + do_softirq(); \ + preempt_check_resched(); \ + } else { \ + __local_bh_enable(); \ + preempt_check_resched(); \ + } \ } while (0) -#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0) +#define in_softirq() in_interrupt() #endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index 851f090e4394..7d9fa1282e26 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -324,24 +324,14 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, #define local_irq_disable() __cli() #define local_irq_enable() __sti() -#ifdef CONFIG_SMP - -extern void __global_cli(void); -extern void __global_sti(void); -extern unsigned long __global_save_flags(void); -extern void __global_restore_flags(unsigned long); -#define cli() __global_cli() -#define sti() __global_sti() -#define save_flags(x) ((x)=__global_save_flags()) -#define restore_flags(x) __global_restore_flags(x) - -#else - -#define cli() __cli() -#define sti() __sti() -#define save_flags(x) __save_flags(x) -#define restore_flags(x) __restore_flags(x) - +/* + * Compatibility macros - they will be removed after some time. + */ +#if !CONFIG_SMP +# define sti() __sti() +# define cli() __cli() +# define save_flags(flags) __save_flags(flags) +# define restore_flags(flags) __restore_flags(flags) #endif /* diff --git a/include/linux/irq_cpustat.h b/include/linux/irq_cpustat.h index dfd73c5ec60d..6eab29be1d61 100644 --- a/include/linux/irq_cpustat.h +++ b/include/linux/irq_cpustat.h @@ -29,8 +29,6 @@ extern irq_cpustat_t irq_stat[]; /* defined in asm/hardirq.h */ /* arch independent irq_stat fields */ #define softirq_pending(cpu) __IRQ_STAT((cpu), __softirq_pending) -#define local_irq_count(cpu) __IRQ_STAT((cpu), __local_irq_count) -#define local_bh_count(cpu) __IRQ_STAT((cpu), __local_bh_count) #define syscall_count(cpu) __IRQ_STAT((cpu), __syscall_count) #define ksoftirqd_task(cpu) __IRQ_STAT((cpu), __ksoftirqd_task) /* arch dependent irq_stat fields */ diff --git a/include/linux/preempt.h b/include/linux/preempt.h new file mode 100644 index 000000000000..172471f0dbde --- /dev/null +++ b/include/linux/preempt.h @@ -0,0 +1,46 @@ +#ifndef __LINUX_PREEMPT_H +#define __LINUX_PREEMPT_H + +#include + +#define preempt_count() (current_thread_info()->preempt_count) + +#ifdef CONFIG_PREEMPT + +extern void preempt_schedule(void); + +#define preempt_disable() \ +do { \ + preempt_count()++; \ + barrier(); \ +} while (0) + +#define preempt_enable_no_resched() \ +do { \ + preempt_count()--; \ + barrier(); \ +} while (0) + +#define preempt_enable() \ +do { \ + preempt_enable_no_resched(); \ + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ + preempt_schedule(); \ +} while (0) + +#define preempt_check_resched() \ +do { \ + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ + preempt_schedule(); \ +} while (0) + +#else + +#define preempt_disable() do { } while (0) +#define preempt_enable_no_resched() do {} while(0) +#define preempt_enable() do { } while (0) +#define preempt_check_resched() do { } while (0) + +#endif + +#endif /* __LINUX_PREEMPT_H */ diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h index 13d8c7ace0bb..cfb23f363e61 100644 --- a/include/linux/smp_lock.h +++ b/include/linux/smp_lock.h @@ -7,7 +7,7 @@ #define lock_kernel() do { } while(0) #define unlock_kernel() do { } while(0) -#define release_kernel_lock(task, cpu) do { } while(0) +#define release_kernel_lock(task) do { } while(0) #define reacquire_kernel_lock(task) do { } while(0) #define kernel_locked() 1 diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 194541968c6a..d9f4af4103e4 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -2,6 +2,7 @@ #define __LINUX_SPINLOCK_H #include +#include #include #include #include @@ -120,36 +121,6 @@ #ifdef CONFIG_PREEMPT -asmlinkage void preempt_schedule(void); - -#define preempt_get_count() (current_thread_info()->preempt_count) - -#define preempt_disable() \ -do { \ - ++current_thread_info()->preempt_count; \ - barrier(); \ -} while (0) - -#define preempt_enable_no_resched() \ -do { \ - --current_thread_info()->preempt_count; \ - barrier(); \ -} while (0) - -#define preempt_enable() \ -do { \ - --current_thread_info()->preempt_count; \ - barrier(); \ - if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ - preempt_schedule(); \ -} while (0) - -#define preempt_check_resched() \ -do { \ - if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ - preempt_schedule(); \ -} while (0) - #define spin_lock(lock) \ do { \ preempt_disable(); \ @@ -179,12 +150,6 @@ do { \ #else -#define preempt_get_count() (0) -#define preempt_disable() do { } while (0) -#define preempt_enable_no_resched() do {} while(0) -#define preempt_enable() do { } while (0) -#define preempt_check_resched() do { } while (0) - #define spin_lock(lock) _raw_spin_lock(lock) #define spin_trylock(lock) _raw_spin_trylock(lock) #define spin_unlock(lock) _raw_spin_unlock(lock) diff --git a/init/main.c b/init/main.c index 2133b32001de..3bef5a614a45 100644 --- a/init/main.c +++ b/init/main.c @@ -373,7 +373,7 @@ asmlinkage void __init start_kernel(void) } kmem_cache_init(); - sti(); + __sti(); calibrate_delay(); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && diff --git a/kernel/exit.c b/kernel/exit.c index f727a3c511c8..71d017f2fd8f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -530,10 +530,10 @@ NORET_TYPE void do_exit(long code) tsk->flags |= PF_EXITING; del_timer_sync(&tsk->real_timer); - if (unlikely(preempt_get_count())) + if (unlikely(preempt_count())) printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", current->comm, current->pid, - preempt_get_count()); + preempt_count()); fake_volatile: acct_process(code); diff --git a/kernel/panic.c b/kernel/panic.c index 5281e7cce9f8..9661ad669363 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -94,7 +94,7 @@ NORET_TYPE void panic(const char * fmt, ...) #if defined(CONFIG_ARCH_S390) disabled_wait(caller); #endif - sti(); + __sti(); for(;;) { CHECK_EMERGENCY_SYNC } diff --git a/kernel/sched.c b/kernel/sched.c index c8a11b29794e..3d275a38109e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -727,7 +727,8 @@ void scheduler_tick(int user_tick, int system) task_t *p = current; if (p == rq->idle) { - if (local_bh_count(cpu) || local_irq_count(cpu) > 1) + /* note: this timer irq context must be accounted for as well */ + if (preempt_count() >= 2*IRQ_OFFSET) kstat.per_cpu_system[cpu] += system; #if CONFIG_SMP idle_tick(); @@ -816,7 +817,7 @@ need_resched: prev = current; rq = this_rq(); - release_kernel_lock(prev, smp_processor_id()); + release_kernel_lock(prev); prepare_arch_schedule(prev); prev->sleep_timestamp = jiffies; spin_lock_irq(&rq->lock); @@ -825,7 +826,7 @@ need_resched: * if entering off of a kernel preemption go straight * to picking the next task. */ - if (unlikely(preempt_get_count() & PREEMPT_ACTIVE)) + if (unlikely(preempt_count() & PREEMPT_ACTIVE)) goto pick_next_task; switch (prev->state) { @@ -1694,7 +1695,9 @@ void __init init_idle(task_t *idle, int cpu) __restore_flags(flags); /* Set the preempt count _outside_ the spinlocks! */ +#if CONFIG_PREEMPT idle->thread_info->preempt_count = (idle->lock_depth >= 0); +#endif } extern void init_timervecs(void); diff --git a/kernel/softirq.c b/kernel/softirq.c index e0093420e169..a53dd2828cb5 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -61,17 +61,17 @@ static inline void wakeup_softirqd(unsigned cpu) asmlinkage void do_softirq() { - int cpu; __u32 pending; long flags; __u32 mask; + int cpu; if (in_interrupt()) return; local_irq_save(flags); - cpu = smp_processor_id(); + pending = softirq_pending(cpu); if (pending) { @@ -111,7 +111,7 @@ restart: } /* - * This function must run with irq disabled! + * This function must run with irqs disabled! */ inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr) { @@ -126,7 +126,7 @@ inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr) * Otherwise we wake up ksoftirqd to make sure we * schedule the softirq soon. */ - if (!(local_irq_count(cpu) | local_bh_count(cpu))) + if (!in_interrupt()) wakeup_softirqd(cpu); } @@ -290,22 +290,16 @@ spinlock_t global_bh_lock = SPIN_LOCK_UNLOCKED; static void bh_action(unsigned long nr) { - int cpu = smp_processor_id(); - if (!spin_trylock(&global_bh_lock)) goto resched; - if (!hardirq_trylock(cpu)) - goto resched_unlock; - if (bh_base[nr]) bh_base[nr](); - hardirq_endlock(cpu); + hardirq_endlock(); spin_unlock(&global_bh_lock); return; -resched_unlock: spin_unlock(&global_bh_lock); resched: mark_bh(nr); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 74cbdeb53734..0f327d594231 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -318,7 +318,7 @@ void __kfree_skb(struct sk_buff *skb) dst_release(skb->dst); if(skb->destructor) { - if (in_irq()) + if (0 && in_irq()) printk(KERN_WARNING "Warning: kfree_skb on " "hard IRQ %p\n", NET_CALLER(skb)); skb->destructor(skb); diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index f67cc0f4e9fa..fed9bb159112 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1104,7 +1104,7 @@ static int snd_intel8x0_free(intel8x0_t *chip) outb(ICH_RESETREGS, ICHREG(chip, PO_CR)); outb(ICH_RESETREGS, ICHREG(chip, MC_CR)); /* --- */ - synchronize_irq(); + synchronize_irq(chip->irq); __hw_end: if (chip->bdbars) snd_free_pci_pages(chip->pci, 3 * sizeof(u32) * ICH_MAX_FRAGS * 2, chip->bdbars, chip->bdbars_addr); @@ -1335,7 +1335,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card, } chip->irq = pci->irq; pci_set_master(pci); - synchronize_irq(); + synchronize_irq(chip->irq); /* initialize offsets */ chip->reg_pi_sr = ICH_REG_PI_SR; -- cgit v1.2.3