Message ID | 20170215095353.23888-1-linus.walleij@linaro.org |
---|---|
State | New |
Headers | show |
Hi Linus, some nits below: On 02/15/2017 10:53 AM, Linus Walleij wrote: > I do not know at what point people have wanted to have a system > with MMC/SD support without the block layer. We are anyway now > so tightly integrated with the block layer that this is onlt only ^ > teoretical and it makes no sense to have the block layer interface ^ theoretical > as optional. > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > --- Byte, Johannes -- Johannes Thumshirn Storage jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Feb 15, 2017 at 10:53 AM, Linus Walleij <linus.walleij@linaro.org> wrote: > I do not know at what point people have wanted to have a system > with MMC/SD support without the block layer. We are anyway now > so tightly integrated with the block layer that this is onlt > teoretical and it makes no sense to have the block layer interface > as optional. > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > --- > drivers/mmc/core/Kconfig | 12 ------------ > drivers/mmc/core/Makefile | 5 ++--- > 2 files changed, 2 insertions(+), 15 deletions(-) > > diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig > index cdfa8520a4b1..2920bc4351ed 100644 > --- a/drivers/mmc/core/Kconfig > +++ b/drivers/mmc/core/Kconfig > @@ -23,19 +23,8 @@ config PWRSEQ_SIMPLE > This driver can also be built as a module. If so, the module > will be called pwrseq_simple. > > -config MMC_BLOCK > - tristate "MMC block device driver" > - depends on BLOCK Now you need to move the "depends on BLOCK" into the top-level option. In theory you could have a system that has no MMC storage and no block device but boots from NOR flash and uses an SDIO wifi card, such as this these https://getchip.com/pages/chip http://wiki.chumby.com/index.php?title=Main_Page https://wikidevi.com/wiki/GlobalScale_DreamPlug https://wikidevi.com/wiki/Linksys_HA1000 https://wikidevi.com/wiki/Google_Chromecast_(H2G2-42) https://wikidevi.com/wiki/D-Link_DCH-G021 Most are not too memory constrained, but sometimes you want to squeeze out some kernel memory by turning off CONFIG_BLOCK. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Linus, [auto build test ERROR on linus/master] [also build test ERROR on v4.10-rc8 next-20170215] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Linus-Walleij/mmc-core-make-block-layer-non-optional/20170215-181952 config: i386-randconfig-c0-02151724 (attached as .config) compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from drivers/mmc/core/block.c:48:0: drivers/mmc/core/queue.h: In function 'mmc_req_is_special': >> drivers/mmc/core/queue.h:7:3: error: implicit declaration of function 'req_op' [-Werror=implicit-function-declaration] (req_op(req) == REQ_OP_FLUSH || ^ >> drivers/mmc/core/queue.h:7:19: error: 'REQ_OP_FLUSH' undeclared (first use in this function) (req_op(req) == REQ_OP_FLUSH || ^ drivers/mmc/core/queue.h:7:19: note: each undeclared identifier is reported only once for each function it appears in >> drivers/mmc/core/queue.h:8:19: error: 'REQ_OP_DISCARD' undeclared (first use in this function) req_op(req) == REQ_OP_DISCARD || ^ >> drivers/mmc/core/queue.h:9:19: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function) req_op(req) == REQ_OP_SECURE_ERASE); ^ drivers/mmc/core/block.c: In function 'mmc_blk_get': >> drivers/mmc/core/block.c:137:11: error: dereferencing pointer to incomplete type md = disk->private_data; ^ drivers/mmc/core/block.c: In function 'mmc_get_devidx': drivers/mmc/core/block.c:149:19: error: dereferencing pointer to incomplete type int devidx = disk->first_minor / perdev_minors; ^ drivers/mmc/core/block.c: In function 'mmc_blk_put': >> drivers/mmc/core/block.c:159:3: error: implicit declaration of function 'blk_cleanup_queue' [-Werror=implicit-function-declaration] blk_cleanup_queue(md->queue.queue); ^ >> drivers/mmc/core/block.c:165:3: error: implicit declaration of function 'put_disk' [-Werror=implicit-function-declaration] put_disk(md->disk); ^ drivers/mmc/core/block.c: In function 'power_ro_lock_show': >> drivers/mmc/core/block.c:175:9: error: implicit declaration of function 'dev_to_disk' [-Werror=implicit-function-declaration] struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^ >> drivers/mmc/core/block.c:175:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^ drivers/mmc/core/block.c: In function 'power_ro_lock_store': drivers/mmc/core/block.c:205:19: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast md = mmc_blk_get(dev_to_disk(dev)); ^ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^ In file included from include/linux/kernel.h:13:0, from include/linux/moduleparam.h:6, from drivers/mmc/core/block.c:20: drivers/mmc/core/block.c:215:84: error: dereferencing pointer to incomplete type pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret); ^ include/linux/printk.h:292:33: note: in definition of macro 'pr_err' printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) ^ drivers/mmc/core/block.c:223:12: error: dereferencing pointer to incomplete type md->disk->disk_name); ^ include/linux/printk.h:299:34: note: in definition of macro 'pr_info' printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) ^ >> drivers/mmc/core/block.c:224:3: error: implicit declaration of function 'set_disk_ro' [-Werror=implicit-function-declaration] set_disk_ro(md->disk, 1); ^ In file included from include/linux/kernel.h:13:0, from include/linux/moduleparam.h:6, from drivers/mmc/core/block.c:20: drivers/mmc/core/block.c:228:81: error: dereferencing pointer to incomplete type pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name); ^ include/linux/printk.h:299:34: note: in definition of macro 'pr_info' printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) ^ drivers/mmc/core/block.c: In function 'force_ro_show': drivers/mmc/core/block.c:241:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^ >> drivers/mmc/core/block.c:244:10: error: implicit declaration of function 'get_disk_ro' [-Werror=implicit-function-declaration] get_disk_ro(dev_to_disk(dev)) ^ ^ drivers/mmc/core/block.c: In function 'force_ro_store': drivers/mmc/core/block.c:255:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^ drivers/mmc/core/block.c: In function 'mmc_blk_open': >> drivers/mmc/core/block.c:277:4: error: implicit declaration of function 'check_disk_change' [-Werror=implicit-function-declaration] check_disk_change(bdev); ^ drivers/mmc/core/block.c: In function 'mmc_blk_release': drivers/mmc/core/block.c:292:32: error: dereferencing pointer to incomplete type struct mmc_blk_data *md = disk->private_data; ^ drivers/mmc/core/block.c: In function 'mmc_blk_getgeo': >> drivers/mmc/core/block.c:302:2: error: implicit declaration of function 'get_capacity' [-Werror=implicit-function-declaration] geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16); ^ In file included from include/asm-generic/ioctl.h:4:0, from arch/x86/include/uapi/asm/ioctl.h:1, from include/uapi/linux/ioctl.h:4, from arch/x86/include/uapi/asm/msr.h:7, from arch/x86/include/asm/msr.h:11, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:25, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from drivers/mmc/core/block.c:21: drivers/mmc/core/block.c: In function 'mmc_blk_ioctl': >> include/uapi/linux/mmc/ioctl.h:59:27: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function) #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) ^ include/uapi/asm-generic/ioctl.h:67:5: note: in definition of macro '_IOC' ((type) << _IOC_TYPESHIFT) | \ ^ >> include/uapi/linux/mmc/ioctl.h:59:21: note: in expansion of macro '_IOWR' #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) ^ >> drivers/mmc/core/block.c:698:7: note: in expansion of macro 'MMC_IOC_CMD' case MMC_IOC_CMD: ^ drivers/mmc/core/block.c: At top level: >> drivers/mmc/core/block.c:717:21: error: variable 'mmc_bdops' has initializer but incomplete type static const struct block_device_operations mmc_bdops = { ^ >> drivers/mmc/core/block.c:718:2: error: unknown field 'open' specified in initializer .open = mmc_blk_open, ^ >> drivers/mmc/core/block.c:718:2: warning: excess elements in struct initializer drivers/mmc/core/block.c:718:2: warning: (near initialization for 'mmc_bdops') >> drivers/mmc/core/block.c:719:2: error: unknown field 'release' specified in initializer .release = mmc_blk_release, ^ drivers/mmc/core/block.c:719:2: warning: excess elements in struct initializer drivers/mmc/core/block.c:719:2: warning: (near initialization for 'mmc_bdops') -- In file included from drivers/mmc/core/queue.c:21:0: drivers/mmc/core/queue.h: In function 'mmc_req_is_special': >> drivers/mmc/core/queue.h:7:3: error: implicit declaration of function 'req_op' [-Werror=implicit-function-declaration] (req_op(req) == REQ_OP_FLUSH || ^ >> drivers/mmc/core/queue.h:7:19: error: 'REQ_OP_FLUSH' undeclared (first use in this function) (req_op(req) == REQ_OP_FLUSH || ^ drivers/mmc/core/queue.h:7:19: note: each undeclared identifier is reported only once for each function it appears in >> drivers/mmc/core/queue.h:8:19: error: 'REQ_OP_DISCARD' undeclared (first use in this function) req_op(req) == REQ_OP_DISCARD || ^ >> drivers/mmc/core/queue.h:9:19: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function) req_op(req) == REQ_OP_SECURE_ERASE); ^ drivers/mmc/core/queue.h: At top level: >> drivers/mmc/core/queue.h:38:19: error: field 'thread_sem' has incomplete type struct semaphore thread_sem; ^ drivers/mmc/core/queue.c: In function 'mmc_prep_request': >> drivers/mmc/core/queue.c:31:26: error: dereferencing pointer to incomplete type struct mmc_queue *mq = q->queuedata; ^ drivers/mmc/core/queue.c:36:9: error: dereferencing pointer to incomplete type if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD && ^ >> drivers/mmc/core/queue.c:36:23: error: 'REQ_TYPE_FS' undeclared (first use in this function) if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD && ^ >> drivers/mmc/core/queue.c:36:53: error: 'REQ_OP_DISCARD' undeclared (first use in this function) if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD && ^ >> drivers/mmc/core/queue.c:37:21: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function) req_op(req) != REQ_OP_SECURE_ERASE) { ^ >> drivers/mmc/core/queue.c:38:3: error: implicit declaration of function 'blk_dump_rq_flags' [-Werror=implicit-function-declaration] blk_dump_rq_flags(req, "MMC bad request"); ^ >> drivers/mmc/core/queue.c:39:10: error: 'BLKPREP_KILL' undeclared (first use in this function) return BLKPREP_KILL; ^ drivers/mmc/core/queue.c:45:5: error: dereferencing pointer to incomplete type req->rq_flags |= RQF_DONTPREP; ^ >> drivers/mmc/core/queue.c:45:19: error: 'RQF_DONTPREP' undeclared (first use in this function) req->rq_flags |= RQF_DONTPREP; ^ >> drivers/mmc/core/queue.c:47:9: error: 'BLKPREP_OK' undeclared (first use in this function) return BLKPREP_OK; ^ drivers/mmc/core/queue.c: In function 'mmc_queue_thread': >> drivers/mmc/core/queue.c:58:2: error: implicit declaration of function 'down' [-Werror=implicit-function-declaration] down(&mq->thread_sem); ^ drivers/mmc/core/queue.c:62:18: error: dereferencing pointer to incomplete type spin_lock_irq(q->queue_lock); ^ >> drivers/mmc/core/queue.c:64:3: error: implicit declaration of function 'blk_fetch_request' [-Werror=implicit-function-declaration] req = blk_fetch_request(q); ^ >> drivers/mmc/core/queue.c:64:7: warning: assignment makes pointer from integer without a cast req = blk_fetch_request(q); ^ drivers/mmc/core/queue.c:79:20: error: dereferencing pointer to incomplete type spin_unlock_irq(q->queue_lock); ^ >> drivers/mmc/core/queue.c:110:4: error: implicit declaration of function 'up' [-Werror=implicit-function-declaration] up(&mq->thread_sem); ^ drivers/mmc/core/queue.c: In function 'mmc_request_fn': drivers/mmc/core/queue.c:128:26: error: dereferencing pointer to incomplete type struct mmc_queue *mq = q->queuedata; ^ drivers/mmc/core/queue.c:133:15: warning: assignment makes pointer from integer without a cast while ((req = blk_fetch_request(q)) != NULL) { ^ drivers/mmc/core/queue.c:134:7: error: dereferencing pointer to incomplete type req->rq_flags |= RQF_QUIET; ^ >> drivers/mmc/core/queue.c:134:21: error: 'RQF_QUIET' undeclared (first use in this function) req->rq_flags |= RQF_QUIET; ^ >> drivers/mmc/core/queue.c:135:4: error: implicit declaration of function '__blk_end_request_all' [-Werror=implicit-function-declaration] __blk_end_request_all(req, -EIO); ^ drivers/mmc/core/queue.c: In function 'mmc_queue_setup_discard': >> drivers/mmc/core/queue.c:175:2: error: implicit declaration of function 'queue_flag_set_unlocked' [-Werror=implicit-function-declaration] queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); ^ vim +/req_op +7 drivers/mmc/core/queue.h ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 1 #ifndef MMC_QUEUE_H ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 2 #define MMC_QUEUE_H ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 3 c2df40dfb drivers/mmc/card/queue.h Mike Christie 2016-06-05 4 static inline bool mmc_req_is_special(struct request *req) c2df40dfb drivers/mmc/card/queue.h Mike Christie 2016-06-05 5 { 3a5e02ced drivers/mmc/card/queue.h Mike Christie 2016-06-05 6 return req && 7afafc8a4 drivers/mmc/card/queue.h Adrian Hunter 2016-08-16 @7 (req_op(req) == REQ_OP_FLUSH || 7afafc8a4 drivers/mmc/card/queue.h Adrian Hunter 2016-08-16 @8 req_op(req) == REQ_OP_DISCARD || 7afafc8a4 drivers/mmc/card/queue.h Adrian Hunter 2016-08-16 @9 req_op(req) == REQ_OP_SECURE_ERASE); c2df40dfb drivers/mmc/card/queue.h Mike Christie 2016-06-05 @10 } ef3a69c7a drivers/mmc/card/queue.h Seungwon Jeon 2013-03-14 11 ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 12 struct request; ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 13 struct task_struct; 7db3028e0 drivers/mmc/card/queue.h Linus Walleij 2016-11-18 14 struct mmc_blk_data; ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 15 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 16 struct mmc_blk_request { 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 17 struct mmc_request mrq; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 18 struct mmc_command sbc; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 19 struct mmc_command cmd; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 20 struct mmc_command stop; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 21 struct mmc_data data; b8360a494 drivers/mmc/card/queue.h Adrian Hunter 2015-05-07 22 int retune_retry_done; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 23 }; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 24 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 25 struct mmc_queue_req { 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 26 struct request *req; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 27 struct mmc_blk_request brq; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 28 struct scatterlist *sg; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 29 char *bounce_buf; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 30 struct scatterlist *bounce_sg; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 31 unsigned int bounce_sg_len; ee8a43a51 drivers/mmc/card/queue.h Per Forlin 2011-07-01 32 struct mmc_async_req mmc_active; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 33 }; 97868a2bd drivers/mmc/card/queue.h Per Forlin 2011-07-09 34 ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 35 struct mmc_queue { ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 36 struct mmc_card *card; 87598a2bd drivers/mmc/mmc_queue.h Christoph Hellwig 2006-11-13 37 struct task_struct *thread; ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 @38 struct semaphore thread_sem; ^1da177e4 drivers/mmc/mmc_queue.h Linus Torvalds 2005-04-16 39 unsigned int flags; 2220eedfd drivers/mmc/card/queue.h Konstantin Dorfman 2013-01-14 40 #define MMC_QUEUE_SUSPENDED (1 << 0) 2220eedfd drivers/mmc/card/queue.h Konstantin Dorfman 2013-01-14 41 #define MMC_QUEUE_NEW_REQUEST (1 << 1) :::::: The code at line 7 was first introduced by commit :::::: 7afafc8a44bf0ab841b17d450b02aedb3a138985 block: Fix secure erase :::::: TO: Adrian Hunter <adrian.hunter@intel.com> :::::: CC: Jens Axboe <axboe@fb.com> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Linus, [auto build test ERROR on linus/master] [also build test ERROR on v4.10-rc8 next-20170215] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Linus-Walleij/mmc-core-make-block-layer-non-optional/20170215-181952 config: i386-randconfig-h1-02151737 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): In file included from drivers/mmc/core/block.c:48:0: drivers/mmc/core/queue.h: In function 'mmc_req_is_special': drivers/mmc/core/queue.h:7:4: error: implicit declaration of function 'req_op' [-Werror=implicit-function-declaration] (req_op(req) == REQ_OP_FLUSH || ^~~~~~ drivers/mmc/core/queue.h:7:19: error: 'REQ_OP_FLUSH' undeclared (first use in this function) (req_op(req) == REQ_OP_FLUSH || ^~~~~~~~~~~~ drivers/mmc/core/queue.h:7:19: note: each undeclared identifier is reported only once for each function it appears in drivers/mmc/core/queue.h:8:19: error: 'REQ_OP_DISCARD' undeclared (first use in this function) req_op(req) == REQ_OP_DISCARD || ^~~~~~~~~~~~~~ drivers/mmc/core/queue.h:9:19: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function) req_op(req) == REQ_OP_SECURE_ERASE); ^~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_get': >> drivers/mmc/core/block.c:137:11: error: dereferencing pointer to incomplete type 'struct gendisk' md = disk->private_data; ^~ drivers/mmc/core/block.c: In function 'mmc_blk_put': drivers/mmc/core/block.c:159:3: error: implicit declaration of function 'blk_cleanup_queue' [-Werror=implicit-function-declaration] blk_cleanup_queue(md->queue.queue); ^~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:165:3: error: implicit declaration of function 'put_disk' [-Werror=implicit-function-declaration] put_disk(md->disk); ^~~~~~~~ drivers/mmc/core/block.c: In function 'power_ro_lock_show': drivers/mmc/core/block.c:175:40: error: implicit declaration of function 'dev_to_disk' [-Werror=implicit-function-declaration] struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^~~~~~~~~~~ drivers/mmc/core/block.c:175:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion] drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'power_ro_lock_store': drivers/mmc/core/block.c:205:19: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion] md = mmc_blk_get(dev_to_disk(dev)); ^~~~~~~~~~~ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^~~~~~~~~~~ drivers/mmc/core/block.c:224:3: error: implicit declaration of function 'set_disk_ro' [-Werror=implicit-function-declaration] set_disk_ro(md->disk, 1); ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'force_ro_show': drivers/mmc/core/block.c:241:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion] struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^~~~~~~~~~~ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^~~~~~~~~~~ drivers/mmc/core/block.c:244:10: error: implicit declaration of function 'get_disk_ro' [-Werror=implicit-function-declaration] get_disk_ro(dev_to_disk(dev)) ^ ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'force_ro_store': drivers/mmc/core/block.c:255:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion] struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); ^~~~~~~~~~~ drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_open': drivers/mmc/core/block.c:277:4: error: implicit declaration of function 'check_disk_change' [-Werror=implicit-function-declaration] check_disk_change(bdev); ^~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_getgeo': drivers/mmc/core/block.c:302:19: error: implicit declaration of function 'get_capacity' [-Werror=implicit-function-declaration] geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16); ^~~~~~~~~~~~ In file included from include/asm-generic/ioctl.h:4:0, from arch/x86/include/uapi/asm/ioctl.h:1, from include/uapi/linux/ioctl.h:4, from arch/x86/include/uapi/asm/msr.h:7, from arch/x86/include/asm/msr.h:11, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:25, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from drivers/mmc/core/block.c:21: drivers/mmc/core/block.c: In function 'mmc_blk_ioctl': include/uapi/linux/mmc/ioctl.h:59:27: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function) #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) ^ include/uapi/asm-generic/ioctl.h:67:5: note: in definition of macro '_IOC' ((type) << _IOC_TYPESHIFT) | \ ^~~~ include/uapi/linux/mmc/ioctl.h:59:21: note: in expansion of macro '_IOWR' #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) ^~~~~ drivers/mmc/core/block.c:698:7: note: in expansion of macro 'MMC_IOC_CMD' case MMC_IOC_CMD: ^~~~~~~~~~~ drivers/mmc/core/block.c: At top level: drivers/mmc/core/block.c:717:21: error: variable 'mmc_bdops' has initializer but incomplete type static const struct block_device_operations mmc_bdops = { ^~~~~~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:718:2: error: unknown field 'open' specified in initializer .open = mmc_blk_open, ^ drivers/mmc/core/block.c:718:12: warning: excess elements in struct initializer .open = mmc_blk_open, ^~~~~~~~~~~~ drivers/mmc/core/block.c:718:12: note: (near initialization for 'mmc_bdops') drivers/mmc/core/block.c:719:2: error: unknown field 'release' specified in initializer .release = mmc_blk_release, ^ drivers/mmc/core/block.c:719:14: warning: excess elements in struct initializer .release = mmc_blk_release, ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c:719:14: note: (near initialization for 'mmc_bdops') drivers/mmc/core/block.c:720:2: error: unknown field 'getgeo' specified in initializer .getgeo = mmc_blk_getgeo, ^ drivers/mmc/core/block.c:720:14: warning: excess elements in struct initializer .getgeo = mmc_blk_getgeo, ^~~~~~~~~~~~~~ drivers/mmc/core/block.c:720:14: note: (near initialization for 'mmc_bdops') drivers/mmc/core/block.c:721:2: error: unknown field 'owner' specified in initializer .owner = THIS_MODULE, ^ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from include/linux/moduleparam.h:6, from drivers/mmc/core/block.c:20: include/linux/export.h:37:21: warning: excess elements in struct initializer #define THIS_MODULE ((struct module *)0) ^ drivers/mmc/core/block.c:721:13: note: in expansion of macro 'THIS_MODULE' .owner = THIS_MODULE, ^~~~~~~~~~~ include/linux/export.h:37:21: note: (near initialization for 'mmc_bdops') #define THIS_MODULE ((struct module *)0) ^ drivers/mmc/core/block.c:721:13: note: in expansion of macro 'THIS_MODULE' .owner = THIS_MODULE, ^~~~~~~~~~~ drivers/mmc/core/block.c:722:2: error: unknown field 'ioctl' specified in initializer .ioctl = mmc_blk_ioctl, ^ drivers/mmc/core/block.c:722:13: warning: excess elements in struct initializer .ioctl = mmc_blk_ioctl, ^~~~~~~~~~~~~ drivers/mmc/core/block.c:722:13: note: (near initialization for 'mmc_bdops') In file included from include/linux/kernel.h:13:0, from include/linux/moduleparam.h:6, from drivers/mmc/core/block.c:20: drivers/mmc/core/block.c: In function 'card_busy_detect': >> drivers/mmc/core/block.c:846:14: error: dereferencing pointer to incomplete type 'struct request' req->rq_disk->disk_name, err); ^ include/linux/printk.h:292:33: note: in definition of macro 'pr_err' printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'send_stop': drivers/mmc/core/block.c:889:22: error: implicit declaration of function 'rq_data_dir' [-Werror=implicit-function-declaration] bool use_r1b_resp = rq_data_dir(req) == WRITE; ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_issue_discard_rq': drivers/mmc/core/block.c:1158:9: error: implicit declaration of function 'blk_rq_pos' [-Werror=implicit-function-declaration] from = blk_rq_pos(req); ^~~~~~~~~~ drivers/mmc/core/block.c:1159:7: error: implicit declaration of function 'blk_rq_sectors' [-Werror=implicit-function-declaration] nr = blk_rq_sectors(req); ^~~~~~~~~~~~~~ drivers/mmc/core/block.c:1184:2: error: implicit declaration of function 'blk_end_request' [-Werror=implicit-function-declaration] blk_end_request(req, err, blk_rq_bytes(req)); ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c:1184:28: error: implicit declaration of function 'blk_rq_bytes' [-Werror=implicit-function-declaration] blk_end_request(req, err, blk_rq_bytes(req)); ^~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_issue_flush': drivers/mmc/core/block.c:1266:2: error: implicit declaration of function 'blk_end_request_all' [-Werror=implicit-function-declaration] blk_end_request_all(req, ret); ^~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_rw_rq_prep': drivers/mmc/core/block.c:1423:37: error: 'REQ_FUA' undeclared (first use in this function) bool do_rel_wr = (req->cmd_flags & REQ_FUA) && ^~~~~~~ drivers/mmc/core/block.c:1504:21: error: 'REQ_META' undeclared (first use in this function) (req->cmd_flags & REQ_META) && ^~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_issue_rw_rq': drivers/mmc/core/block.c:1736:20: error: 'RQF_QUIET' undeclared (first use in this function) req->rq_flags |= RQF_QUIET; ^~~~~~~~~ drivers/mmc/core/block.c:1739:5: error: implicit declaration of function 'blk_rq_cur_bytes' [-Werror=implicit-function-declaration] blk_rq_cur_bytes(req)); ^~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_issue_rq': drivers/mmc/core/block.c:1777:28: error: 'REQ_OP_DISCARD' undeclared (first use in this function) if (req && req_op(req) == REQ_OP_DISCARD) { ^~~~~~~~~~~~~~ drivers/mmc/core/block.c:1782:35: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function) } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) { ^~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:1787:35: error: 'REQ_OP_FLUSH' undeclared (first use in this function) } else if (req && req_op(req) == REQ_OP_FLUSH) { ^~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_alloc_req': drivers/mmc/core/block.c:1856:13: error: implicit declaration of function 'alloc_disk' [-Werror=implicit-function-declaration] md->disk = alloc_disk(perdev_minors); ^~~~~~~~~~ drivers/mmc/core/block.c:1856:11: warning: assignment makes pointer from integer without a cast [-Wint-conversion] md->disk = alloc_disk(perdev_minors); ^ drivers/mmc/core/block.c:1872:20: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function) md->disk->major = MMC_BLOCK_MAJOR; ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c:1879:20: error: 'GENHD_FL_EXT_DEVT' undeclared (first use in this function) md->disk->flags = GENHD_FL_EXT_DEVT; ^~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:1881:22: error: 'GENHD_FL_NO_PART_SCAN' undeclared (first use in this function) md->disk->flags |= GENHD_FL_NO_PART_SCAN; ^~~~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:1899:3: error: implicit declaration of function 'blk_queue_logical_block_size' [-Werror=implicit-function-declaration] blk_queue_logical_block_size(md->queue.queue, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:1904:2: error: implicit declaration of function 'set_capacity' [-Werror=implicit-function-declaration] set_capacity(md->disk, size); ^~~~~~~~~~~~ drivers/mmc/core/block.c:1919:3: error: implicit declaration of function 'blk_queue_write_cache' [-Werror=implicit-function-declaration] blk_queue_write_cache(md->queue.queue, true, true); ^~~~~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_alloc_part': drivers/mmc/core/block.c:1969:36: error: implicit declaration of function 'disk_to_dev' [-Werror=implicit-function-declaration] part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, ^~~~~~~~~~~ drivers/mmc/core/block.c:1969:36: warning: passing argument 2 of 'mmc_blk_alloc_req' makes pointer from integer without a cast [-Wint-conversion] drivers/mmc/core/block.c:1814:29: note: expected 'struct device *' but argument is of type 'int' static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, ^~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_remove_req': drivers/mmc/core/block.c:2025:25: error: 'GENHD_FL_UP' undeclared (first use in this function) if (md->disk->flags & GENHD_FL_UP) { ^~~~~~~~~~~ drivers/mmc/core/block.c:2026:23: warning: passing argument 1 of 'device_remove_file' makes pointer from integer without a cast [-Wint-conversion] device_remove_file(disk_to_dev(md->disk), &md->force_ro); ^~~~~~~~~~~ In file included from include/linux/pm_runtime.h:12:0, from drivers/mmc/core/block.c:37: include/linux/device.h:602:13: note: expected 'struct device *' but argument is of type 'int' extern void device_remove_file(struct device *dev, ^~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2029:24: warning: passing argument 1 of 'device_remove_file' makes pointer from integer without a cast [-Wint-conversion] device_remove_file(disk_to_dev(md->disk), ^~~~~~~~~~~ In file included from include/linux/pm_runtime.h:12:0, from drivers/mmc/core/block.c:37: include/linux/device.h:602:13: note: expected 'struct device *' but argument is of type 'int' extern void device_remove_file(struct device *dev, ^~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2032:4: error: implicit declaration of function 'del_gendisk' [-Werror=implicit-function-declaration] del_gendisk(md->disk); ^~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_add_disk': drivers/mmc/core/block.c:2056:2: error: implicit declaration of function 'device_add_disk' [-Werror=implicit-function-declaration] device_add_disk(md->parent, md->disk); ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2062:27: warning: passing argument 1 of 'device_create_file' makes pointer from integer without a cast [-Wint-conversion] ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); ^~~~~~~~~~~ In file included from include/linux/pm_runtime.h:12:0, from drivers/mmc/core/block.c:37: include/linux/device.h:600:12: note: expected 'struct device *' but argument is of type 'int' extern int device_create_file(struct device *device, ^~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2081:28: warning: passing argument 1 of 'device_create_file' makes pointer from integer without a cast [-Wint-conversion] ret = device_create_file(disk_to_dev(md->disk), ^~~~~~~~~~~ In file included from include/linux/pm_runtime.h:12:0, from drivers/mmc/core/block.c:37: include/linux/device.h:600:12: note: expected 'struct device *' but argument is of type 'int' extern int device_create_file(struct device *device, ^~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2089:21: warning: passing argument 1 of 'device_remove_file' makes pointer from integer without a cast [-Wint-conversion] device_remove_file(disk_to_dev(md->disk), &md->force_ro); ^~~~~~~~~~~ In file included from include/linux/pm_runtime.h:12:0, from drivers/mmc/core/block.c:37: include/linux/device.h:602:13: note: expected 'struct device *' but argument is of type 'int' extern void device_remove_file(struct device *dev, ^~~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_init': drivers/mmc/core/block.c:2310:8: error: implicit declaration of function 'register_blkdev' [-Werror=implicit-function-declaration] res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2310:24: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function) res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c:2320:2: error: implicit declaration of function 'unregister_blkdev' [-Werror=implicit-function-declaration] unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); ^~~~~~~~~~~~~~~~~ drivers/mmc/core/block.c: In function 'mmc_blk_exit': drivers/mmc/core/block.c:2328:20: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function) unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); ^~~~~~~~~~~~~~~ drivers/mmc/core/block.c: At top level: >> drivers/mmc/core/block.c:717:45: error: storage size of 'mmc_bdops' isn't known static const struct block_device_operations mmc_bdops = { ^~~~~~~~~ In file included from drivers/mmc/core/block.c:48:0: drivers/mmc/core/queue.h: In function 'mmc_req_is_special': drivers/mmc/core/queue.h:10:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ cc1: some warnings being treated as errors .. vim +137 drivers/mmc/core/block.c ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 121 }; ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 122 a621aaed drivers/mmc/mmc_block.c Arjan van de Ven 2006-01-12 123 static DEFINE_MUTEX(open_lock); ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 124 5e71b7a6 drivers/mmc/card/block.c Olof Johansson 2010-09-17 125 module_param(perdev_minors, int, 0444); 5e71b7a6 drivers/mmc/card/block.c Olof Johansson 2010-09-17 126 MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); 5e71b7a6 drivers/mmc/card/block.c Olof Johansson 2010-09-17 127 8d1e977d drivers/mmc/card/block.c Loic Pallardy 2012-08-06 128 static inline int mmc_blk_part_switch(struct mmc_card *card, 8d1e977d drivers/mmc/card/block.c Loic Pallardy 2012-08-06 129 struct mmc_blk_data *md); 8d1e977d drivers/mmc/card/block.c Loic Pallardy 2012-08-06 130 static int get_card_status(struct mmc_card *card, u32 *status, int retries); 8d1e977d drivers/mmc/card/block.c Loic Pallardy 2012-08-06 131 ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 132 static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 133 { ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 134 struct mmc_blk_data *md; ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 135 a621aaed drivers/mmc/mmc_block.c Arjan van de Ven 2006-01-12 136 mutex_lock(&open_lock); ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 @137 md = disk->private_data; ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 138 if (md && md->usage == 0) ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 139 md = NULL; ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 140 if (md) ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 141 md->usage++; a621aaed drivers/mmc/mmc_block.c Arjan van de Ven 2006-01-12 142 mutex_unlock(&open_lock); ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 143 ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 144 return md; ^1da177e drivers/mmc/mmc_block.c Linus Torvalds 2005-04-16 145 } :::::: The code at line 137 was first introduced by commit :::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 :::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org> :::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index cdfa8520a4b1..2920bc4351ed 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -23,19 +23,8 @@ config PWRSEQ_SIMPLE This driver can also be built as a module. If so, the module will be called pwrseq_simple. -config MMC_BLOCK - tristate "MMC block device driver" - depends on BLOCK - default y - help - Say Y here to enable the MMC block device driver support. - This provides a block device driver, which you can use to - mount the filesystem. Almost everyone wishing MMC support - should say Y or M here. - config MMC_BLOCK_MINORS int "Number of minors per block device" - depends on MMC_BLOCK range 4 256 default 8 help @@ -53,7 +42,6 @@ config MMC_BLOCK_MINORS config MMC_BLOCK_BOUNCE bool "Use bounce buffer for simple hosts" - depends on MMC_BLOCK default y help SD/MMC is a high latency protocol where it is crucial to diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index b2a257dc644f..42f0d781d911 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -7,12 +7,11 @@ mmc_core-y := core.o bus.o host.o \ mmc.o mmc_ops.o sd.o sd_ops.o \ sdio.o sdio_ops.o sdio_bus.o \ sdio_cis.o sdio_io.o sdio_irq.o \ - quirks.o slot-gpio.o + quirks.o slot-gpio.o \ + block.o queue.o mmc_core-$(CONFIG_OF) += pwrseq.o obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o -obj-$(CONFIG_MMC_BLOCK) += mmc_block.o -mmc_block-objs := block.o queue.o obj-$(CONFIG_MMC_TEST) += mmc_test.o obj-$(CONFIG_SDIO_UART) += sdio_uart.o
I do not know at what point people have wanted to have a system with MMC/SD support without the block layer. We are anyway now so tightly integrated with the block layer that this is onlt teoretical and it makes no sense to have the block layer interface as optional. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/mmc/core/Kconfig | 12 ------------ drivers/mmc/core/Makefile | 5 ++--- 2 files changed, 2 insertions(+), 15 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html