diff options
Diffstat (limited to 'drivers/block/md.c')
-rw-r--r-- | drivers/block/md.c | 165 |
1 files changed, 81 insertions, 84 deletions
diff --git a/drivers/block/md.c b/drivers/block/md.c index 4dedb8671..b525ef2e9 100644 --- a/drivers/block/md.c +++ b/drivers/block/md.c @@ -761,7 +761,7 @@ int md_make_request (int minor, int rw, struct buffer_head * bh) } } -static void do_md_request (void) +static void do_md_request (request_queue_t * q) { printk ("Got md request, not good..."); return; @@ -1176,98 +1176,85 @@ void mdsyncd (void *data) #ifdef CONFIG_MD_BOOT struct { - int set; - int ints[100]; - char str[100]; + unsigned long set; + int pers[MAX_MD_DEV]; + kdev_t devices[MAX_MD_DEV][MAX_REAL]; } md_setup_args __initdata = { - 0,{0},{0} + 0,{0},{{0}} }; -/* called from init/main.c */ -void __init md_setup(char *str,int *ints) -{ - int i; - for(i=0;i<=ints[0];i++) { - md_setup_args.ints[i] = ints[i]; - strcpy(md_setup_args.str, str); -/* printk ("md: ints[%d]=%d.\n", i, ints[i]);*/ - } - md_setup_args.set=1; - return; -} - -void __init do_md_setup(char *str,int *ints) +/* + * Parse the command-line parameters given our kernel, but do not + * actually try to invoke the MD device now; that is handled by + * md_setup_drive after the low-level disk drivers have initialised. + * + * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which + * assigns the task of parsing integer arguments to the + * invoked program now). Added ability to initialise all + * the MD devices (by specifying multiple "md=" lines) + * instead of just one. -- KTK + */ +int __init md_setup(char *str) { - int minor, pers, factor, fault; - kdev_t dev; - int i=1; - - if(ints[0] < 4) { - printk ("md: Too few Arguments (%d).\n", ints[0]); - return; - } - - minor=ints[i++]; - - if (minor >= MAX_MD_DEV) { + int minor, level, factor, fault, i; + kdev_t device; + char *devnames, *pername; + + if(get_option(&str, &minor) != 2 || /* MD Number */ + get_option(&str, &level) != 2 || /* RAID Personality */ + get_option(&str, &factor) != 2 || /* Chunk Size */ + get_option(&str, &fault) != 2) { + printk("md: Too few arguments supplied to md=.\n"); + return 0; + } else if (minor >= MAX_MD_DEV) { printk ("md: Minor device number too high.\n"); - return; + return 0; + } else if (md_setup_args.set & (1 << minor)) { + printk ("md: Warning - md=%d,... has been specified twice;\n" + " will discard the first definition.\n", minor); } - - pers = 0; - - switch(ints[i++]) { /* Raidlevel */ - case -1: + switch(level) { #ifdef CONFIG_MD_LINEAR - pers = LINEAR; - printk ("md: Setting up md%d as linear device.\n",minor); -#else - printk ("md: Linear mode not configured." - "Recompile the kernel with linear mode enabled!\n"); -#endif + case -1: + level = LINEAR; + pername = "linear"; break; - case 0: - pers = STRIPED; -#ifdef CONFIG_MD_STRIPED - printk ("md: Setting up md%d as a striped device.\n",minor); -#else - printk ("md: Striped mode not configured." - "Recompile the kernel with striped mode enabled!\n"); #endif +#ifdef CONFIG_MD_STRIPED + case 0: + level = STRIPED; + pername = "striped"; break; -/* not supported yet - case 1: - pers = RAID1; - printk ("md: Setting up md%d as a raid1 device.\n",minor); - break; - case 5: - pers = RAID5; - printk ("md: Setting up md%d as a raid5 device.\n",minor); - break; -*/ - default: - printk ("md: Unknown or not supported raid level %d.\n", ints[--i]); - return; +#endif + default: + printk ("md: The kernel has not been configured for raid%d" + " support!\n", level); + return 0; } - - if(pers) { - - factor=ints[i++]; /* Chunksize */ - fault =ints[i++]; /* Faultlevel */ - - pers=pers | factor | (fault << FAULT_SHIFT); - - while( str && (dev = name_to_kdev_t(str))) { - do_md_add (minor, dev); - if((str = strchr (str, ',')) != NULL) - str++; - } - - do_md_run (minor, pers); - printk ("md: Loading md%d.\n",minor); + devnames = str; + for (i = 0; str; i++) { + if ((device = name_to_kdev_t(str))) { + md_setup_args.devices[minor][i] = device; + } else { + printk ("md: Unknown device name, %s.\n", str); + return 0; + } + if ((str = strchr(str, ',')) != NULL) + str++; } - + if (!i) { + printk ("md: No devices specified for md%d?\n", minor); + return 0; + } + + printk ("md: Will configure md%d (%s) from %s, below.\n", + minor, pername, devnames); + md_setup_args.devices[minor][i] = (kdev_t) 0; + md_setup_args.pers[minor] = level | factor | (fault << FAULT_SHIFT); + md_setup_args.set |= (1 << minor); + return 0; } + #endif void linear_init (void); @@ -1287,8 +1274,7 @@ int __init md_init (void) return (-1); } - blk_dev[MD_MAJOR].request_fn=DEVICE_REQUEST; - blk_dev[MD_MAJOR].current_request=NULL; + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); read_ahead[MD_MAJOR]=INT_MAX; memset(md_dev, 0, MAX_MD_DEV * sizeof (struct md_dev)); md_gendisk.next=gendisk_head; @@ -1318,7 +1304,18 @@ int __init md_init (void) #ifdef CONFIG_MD_BOOT void __init md_setup_drive(void) { - if(md_setup_args.set) - do_md_setup(md_setup_args.str, md_setup_args.ints); + int minor, i; + kdev_t dev; + + for (minor = 0; minor < MAX_MD_DEV; minor++) { + if ((md_setup_args.set & (1 << minor)) == 0) + continue; + printk("md: Loading md%d.\n", minor); + for (i = 0; (dev = md_setup_args.devices[minor][i]); i++) + do_md_add (minor, dev); + do_md_run (minor, md_setup_args.pers[minor]); + } } + +__setup("md=", md_setup); #endif |