Re: [Patch] Cleanup struct gendisk registration, 2.3.40-pre1

From: Alexander Viro (aviro@redhat.com)
Date: Sat Jan 15 2000 - 01:59:47 EST


On Fri, 14 Jan 2000, Andre Hedrick wrote:

> On Sat, 15 Jan 2000, Guest section DW wrote:
>
> > On Thu, Jan 13, 2000 at 09:06:59PM -0500, Alexander Viro wrote:
> > >
> > > OK, could somebody explain where does IDE call ide_geninit() if built as
> > > module? And if it (apparently) doesn't, do we need it in built-in case?
> > > Andre, could you comment on that?
>
> It should be moved from ide.c to ide-probe.c, for modules I think.
>
[snip]
>
> There is no reason to export, if we move it to "ide-probe.c" where it is
> called. I will test this move and it has to be harmless.

Hmm... you initialize drivers _after_ probing the interfaces. Check what
it will do to the logics in ide_geninit(). Said that, reordering the stuff
in ide_init() might be a better way. Comments?

[snip]

> Where are all the callbacks to "dev->init(dev)" located for block?

They must die. They can't be called for modules, so you have to do the
thing in module_init() anyway. Better move it to foo_init() and be done
with that.

Could you look at the following patch? (heck, it's almost on the
boundary... oh, well) It's against -pre4 and it should (in theory) fix
the problems with modules. Linus, your comments? I'ld rather do
drop_partitions() one as incremental to that...
                                                        Cheers,
                                                                Al

diff -urN linux-2.3.40-pre4/drivers/acorn/block/mfmhd.c linux-bird.bdev/drivers/acorn/block/mfmhd.c
--- linux-2.3.40-pre4/drivers/acorn/block/mfmhd.c Sat Jan 15 01:05:15 2000
+++ linux-bird.bdev/drivers/acorn/block/mfmhd.c Sat Jan 15 01:25:22 2000
@@ -1018,8 +1018,7 @@
 
 
 /*
- * Tell the user about the drive if we decided it exists. Also,
- * set the size of the drive.
+ * Tell the user about the drive if we decided it exists.
  */
 static void mfm_geometry (int drive)
 {
@@ -1028,8 +1027,6 @@
                         mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 4096,
                         mfm_info[drive].cylinders, mfm_info[drive].heads, mfm_info[drive].sectors,
                         mfm_info[drive].lowcurrent, mfm_info[drive].precomp);
- mfm[drive << 6].start_sect = 0;
- mfm[drive << 6].nr_sects = mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 2;
 }
 
 #ifdef CONFIG_BLK_DEV_MFM_AUTODETECT
@@ -1283,6 +1280,7 @@
  * Set the CHS from the ADFS boot block if it is present. This is not ideal
  * since if there are any non-ADFS partitions on the disk, this won't work!
  * Hence, I want to get rid of this...
+ * Please, do. It does seriously sucking things.
  */
 void xd_set_geometry(kdev_t dev, unsigned char secsptrack, unsigned char heads,
                      unsigned long discsize, unsigned int secsize)
@@ -1308,18 +1306,17 @@
                 if (raw_cmd.dev == drive)
                         mfm_specify ();
                 mfm_geometry (drive);
+ mfm[drive << 6].start_sect = 0;
+ mfm[drive << 6].nr_sects = mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 2;
         }
 }
 
-static void mfm_geninit (struct gendisk *gdev);
-
 static struct gendisk mfm_gendisk = {
         MAJOR_NR, /* Major number */
         "mfm", /* Major name */
         6, /* Bits to shift to get real from partition */
         1 << 6, /* Number of partitions per real */
         MFM_MAXDRIVES, /* maximum number of real */
- mfm_geninit, /* init function */
         mfm, /* hd struct */
         mfm_sizes, /* block sizes */
         0, /* number */
@@ -1327,17 +1324,23 @@
         NULL /* next */
 };
 
-static void mfm_geninit (struct gendisk *gdev)
+static void mfm_geninit (void)
 {
         int i;
 
- mfm_drives = mfm_initdrives();
+ for (i = 0; i < (MFM_MAXDRIVES << 6); i++) {
+ /* Can't increase this - if you do all hell breaks loose */
+ mfm_blocksizes[i] = 1024;
+ mfm_sectsizes[i] = 512;
+ }
+ blksize_size[MAJOR_NR] = mfm_blocksizes;
+ hardsect_size[MAJOR_NR] = mfm_sectsizes;
 
- printk("mfm: detected %d hard drive%s\n", mfm_drives, mfm_drives == 1 ? "" : "s");
- gdev->nr_real = mfm_drives;
+ mfm_drives = mfm_initdrives();
 
- for (i = 0; i < mfm_drives; i++)
- mfm_geometry (i);
+ printk("mfm: detected %d hard drive%s\n", mfm_drives,
+ mfm_drives == 1 ? "" : "s");
+ mfm_gendisk.nr_real = mfm_drives;
 
         if (request_irq(mfm_irq, mfm_interrupt_handler, SA_INTERRUPT, "MFM harddisk", NULL))
                 printk("mfm: unable to get IRQ%d\n", mfm_irq);
@@ -1345,12 +1348,11 @@
         if (mfm_irqenable)
                 outw(0x80, mfm_irqenable); /* Required to enable IRQs from MFM podule */
 
- for (i = 0; i < (MFM_MAXDRIVES << 6); i++) {
- mfm_blocksizes[i] = 1024; /* Can't increase this - if you do all hell breaks loose */
- mfm_sectsizes[i] = 512;
+ for (i = 0; i < mfm_drives; i++) {
+ mfm_geometry (i);
+ grok_partitions(&mfm_gendisk, i, 1<<6, mfm_info[i].cylinders *
+ mfm_info[i].heads * mfm_info[i].sectors / 2);
         }
- blksize_size[MAJOR_NR] = mfm_blocksizes;
- hardsect_size[MAJOR_NR] = mfm_sectsizes;
 }
 
 static struct block_device_operations mfm_fops =
@@ -1457,6 +1459,7 @@
         Busy = 0;
         lastspecifieddrive = -1;
 
+ mfm_geninit();
         return 0;
 }
 
@@ -1495,10 +1498,10 @@
                 mfm_gendisk.part[minor].nr_sects = 0;
         }
 
- mfm_gendisk.part[start].nr_sects = mfm_info[target].heads *
- mfm_info[target].cylinders * mfm_info[target].sectors / 2;
+ /* Divide by 2, since sectors are 2 times smaller than usual ;-) */
 
- resetup_one_dev(&mfm_gendisk, target);
+ 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);
@@ -1508,11 +1511,7 @@
 #ifdef MODULE
 int init_module(void)
 {
- int ret;
- ret = mfm_init();
- if (!ret)
- mfm_geninit(&mfm_gendisk);
- return ret;
+ return mfm_geninit();
 }
 
 void cleanup_module(void)
diff -urN linux-2.3.40-pre4/drivers/ap1000/ddv.c linux-bird.bdev/drivers/ap1000/ddv.c
--- linux-2.3.40-pre4/drivers/ap1000/ddv.c Tue Jan 11 00:21:04 2000
+++ linux-bird.bdev/drivers/ap1000/ddv.c Sat Jan 15 01:25:22 2000
@@ -76,7 +76,7 @@
 extern int ddv_restart_cpu(void);
 extern int ddv_mlist_available(void);
 static int ddv_revalidate(kdev_t dev, struct gendisk *gdev);
-static void ddv_geninit(struct gendisk *ignored);
+static void ddv_geninit(void);
 static void ddv_release(struct inode * inode, struct file * filp);
 static void ddv_request1(void);
 
@@ -110,11 +110,6 @@
         PARTN_BITS, /* Bits to shift to get real from partition */
         1 << PARTN_BITS, /* Number of partitions per real */
         1, /* maximum number of real */
-#ifdef MODULE
- NULL, /* called from init_module */
-#else
- ddv_geninit, /* init function */
-#endif
         partition_tables,/* hd struct */
         ddv_blk_length, /* block sizes */
         1, /* number */
@@ -122,7 +117,6 @@
         NULL /* next */
 };
 
-
 struct ddv_geometry {
         unsigned char heads;
         unsigned char sectors;
@@ -738,11 +732,9 @@
         ddv_geometry.cylinders = ddv_sect_length[0] /
                 (ddv_geometry.heads*ddv_geometry.sectors);
 
- ddv_gendisk.part[0].start_sect = 0;
- ddv_gendisk.part[0].nr_sects = ddv_sect_length[0];
-
- resetup_one_dev(&ddv_gendisk, 0);
+ grok_partitions(&ddv_gendisk, 0, 1<<PARTN_BITS, ddv_sect_length[0]);
         
+ /* FIXME. The crap below is, well, crap. Pseudo-RAID and unsafe one */
         for (i=0;i<PARDISK_BASE;i++) {
                 ddv_sect_length[i] = ddv_gendisk.part[i].nr_sects;
                 ddv_blk_length[i] = ddv_gendisk.part[i].nr_sects >> 1;
@@ -794,8 +786,7 @@
         ddv_sect_length[start] = DiskInfo->blocks;
         ddv_blk_length[start] = DiskInfo->blocks >> 1;
 
- gdev->part[start].nr_sects = ddv_sect_length[start];
- resetup_one_dev(gdev, target);
+ grok_partitions(gdev, target, 1<<PARTN_BITS, ddv_sect_length[start]);
 
         printk("sect_length[%d]=%d blk_length[%d]=%d\n",
                start,ddv_sect_length[start],
@@ -936,11 +927,13 @@
 
         kernel_thread(ddv_daemon, NULL, 0);
 
+ ddv_geninit();
+
         return(0);
 }
 
 
-static void ddv_geninit(struct gendisk *ignored)
+static void ddv_geninit(void)
 {
         int i;
         static int done = 0;
@@ -981,10 +974,8 @@
 int init_module(void)
 {
         int error = ddv_init();
- if (!error) {
- ddv_geninit(&(struct gendisk) { 0,0,0,0,0,0,0,0,0,0,0 });
+ if (!error)
                 printk(KERN_INFO "DDV: Loaded as module.\n");
- }
         return error;
 }
 
diff -urN linux-2.3.40-pre4/drivers/block/DAC960.c linux-bird.bdev/drivers/block/DAC960.c
--- linux-2.3.40-pre4/drivers/block/DAC960.c Tue Jan 11 00:21:04 2000
+++ linux-bird.bdev/drivers/block/DAC960.c Sat Jan 15 01:25:22 2000
@@ -1067,7 +1067,6 @@
   Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
   Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
   Controller->GenericDiskInfo.max_nr = DAC960_MaxLogicalDrives;
- Controller->GenericDiskInfo.init = DAC960_InitializeGenericDiskInfo;
   Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
   Controller->GenericDiskInfo.real_devices = Controller;
   Controller->GenericDiskInfo.next = NULL;
@@ -1166,6 +1165,7 @@
       Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
       add_timer(&Controller->MonitoringTimer);
       Controller->ControllerInitialized = true;
+ DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
     }
   else DAC960_FinalizeController(Controller);
 }
@@ -2439,7 +2439,6 @@
       Controller->LogicalDriveInitialState[LogicalDriveNumber] =
         DAC960_LogicalDrive_Online;
       DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
- resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
     }
   if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
     return -ENXIO;
@@ -2573,7 +2572,13 @@
           */
           set_blocksize(Device, BLOCK_SIZE);
         }
- resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
+ /*
+ * Leonard, I'll tie you, draw around you a pentagram
+ * and read this file. Aloud.
+ */
+ grok_partitions(
+ &Controller->GenericDiskInfo, LogicalDriveNumber, DAC960_MaxPartitions,
+ Controller->LogicalDriveInformation[Controller->LogicalDriveInformationIndex][LogicalDriveNumber].LogicalDriveSize);
       return 0;
     }
   return -EINVAL;
@@ -2895,8 +2900,8 @@
   for (LogicalDriveNumber = 0;
        LogicalDriveNumber < Controller->LogicalDriveCount;
        LogicalDriveNumber++)
- GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)].nr_sects =
- LogicalDriveInformation[LogicalDriveNumber].LogicalDriveSize;
+ grok_partitions(GenericDiskInfo,LogicalDriveNumber,DAC960_MaxPartitions,
+ LogicalDriveInformation[LogicalDriveNumber].LogicalDriveSize);
 }
 
 
@@ -3518,10 +3523,6 @@
       DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
       if (Controller == NULL) continue;
       DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < Controller->LogicalDriveCount;
- LogicalDriveNumber++)
- resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
     }
   return 0;
 }
diff -urN linux-2.3.40-pre4/drivers/block/acsi.c linux-bird.bdev/drivers/block/acsi.c
--- linux-2.3.40-pre4/drivers/block/acsi.c Tue Jan 11 00:21:04 2000
+++ linux-bird.bdev/drivers/block/acsi.c Sat Jan 15 01:25:22 2000
@@ -369,7 +369,7 @@
 static void acsi_prevent_removal( int target, int flag );
 static int acsi_change_blk_size( int target, int lun);
 static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
-static void acsi_geninit( struct gendisk *gd );
+static void acsi_geninit(void);
 static int revalidate_acsidisk( int dev, int maxusage );
 static int acsi_revalidate (dev_t);
 
@@ -1386,21 +1386,16 @@
 
 
 static struct gendisk acsi_gendisk = {
- MAJOR_NR, /* Major number */
- "ad", /* Major name */
- 4, /* Bits to shift to get real from partition */
- 1 << 4, /* Number of partitions per real */
- MAX_DEV, /* maximum number of real */
-#ifdef MODULE
- NULL, /* called from init_module() */
-#else
- acsi_geninit, /* init function */
-#endif
- acsi_part, /* hd struct */
- acsi_sizes, /* block sizes */
- 0, /* number */
+ MAJOR_NR, /* Major number */
+ "ad", /* Major name */
+ 4, /* Bits to shift to get real from partition */
+ 1 << 4, /* Number of partitions per real */
+ MAX_DEV, /* maximum number of real */
+ acsi_part, /* hd struct */
+ acsi_sizes, /* block sizes */
+ 0, /* number */
         (void *)acsi_info, /* internal */
- NULL /* next */
+ NULL /* next */
 };
         
 #define MAX_SCSI_DEVICE_CODE 10
@@ -1659,7 +1654,7 @@
 int SLM_devices[8];
 #endif
 
-static void acsi_geninit( struct gendisk *gd )
+static void acsi_geninit(void)
 {
         int i, target, lun;
         struct acsi_info_struct *aip;
@@ -1741,14 +1736,14 @@
                         NDevices, n_slm );
 #endif
                                          
- for( i = 0; i < NDevices; ++i ) {
- acsi_part[i<<4].start_sect = 0;
- acsi_part[i<<4].nr_sects = acsi_info[i].size;
- }
- acsi_gendisk.nr_real = NDevices;
         for( i = 0; i < (MAX_DEV << 4); i++ )
                 acsi_blocksizes[i] = 1024;
         blksize_size[MAJOR_NR] = acsi_blocksizes;
+ for( i = 0; i < NDevices; ++i )
+ grok_partitions(&acsi_gendisk, i,
+ (acsi_info[i].type==HARDDISK)?1<<4:1,
+ acsi_info[i].size);
+ acsi_gendisk.nr_real = NDevices;
 }
 
 #ifdef CONFIG_ATARI_SLM_MODULE
@@ -1778,6 +1773,7 @@
 int acsi_init( void )
 
 {
+ int err = 0;
         if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI))
                 return 0;
 
@@ -1801,10 +1797,11 @@
         gendisk_head = &acsi_gendisk;
 
 #ifdef CONFIG_ATARI_SLM
- return( slm_init() );
-#else
- return 0;
+ err = slm_init();
 #endif
+ if (!err)
+ acsi_geninit();
+ return err;
 }
 
 
@@ -1816,7 +1813,6 @@
         if ((err = acsi_init()))
                 return( err );
         printk( KERN_INFO "ACSI driver loaded as module.\n");
- acsi_geninit( &(struct gendisk){ 0,0,0,0,0,0,0,0,0,0,0 } );
         return( 0 );
 }
 
@@ -1914,9 +1910,7 @@
         ENABLE_IRQ();
         stdma_release();
         
- gdev->part[start].nr_sects = aip->size;
- if (aip->type == HARDDISK && aip->size > 0)
- resetup_one_dev(gdev, device);
+ grok_partitions(gdev, device, (aip->type==HARDDISK)?1<<4:1, aip->size);
 
         DEVICE_BUSY = 0;
         wake_up(&busy_wait);
diff -urN linux-2.3.40-pre4/drivers/block/cpqarray.c linux-bird.bdev/drivers/block/cpqarray.c
--- linux-2.3.40-pre4/drivers/block/cpqarray.c Tue Jan 11 00:21:05 2000
+++ linux-bird.bdev/drivers/block/cpqarray.c Sat Jan 15 01:25:22 2000
@@ -171,9 +171,8 @@
                              int length, int *eof, void *data) {}
 #endif
 
-static void ida_geninit(struct gendisk *g)
+static void ida_geninit(int ctlr)
 {
- int ctlr = g-ida_gendisk;
         int i,j;
         drv_info_t *drv;
 
@@ -317,13 +316,6 @@
         cpqarray_init();
         if (nr_ctlr == 0)
                 return -EIO;
-
- for(i=0; i<nr_ctlr; i++) {
- ida_geninit(&ida_gendisk[i]);
- for(j=0; j<NWD; j++)
- if (ida_sizes[(i<<CTLR_SHIFT) + (j<<NWD_SHIFT)])
- resetup_one_dev(&ida_gendisk[i], j);
- }
         return 0;
 }
 
@@ -375,7 +367,7 @@
                 do_ida_request4, do_ida_request5,
                 do_ida_request6, do_ida_request7,
         };
- int i;
+ int i,j;
 
         /* detect controllers */
         cpqarray_pci_detect();
@@ -460,22 +452,22 @@
                 hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
 
                 ida_procinit(i);
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i), request_fns[i]);
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 0);
+
+ blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
+ hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
+
+ read_ahead[MAJOR_NR+i] = READ_AHEAD;
                 ida_gendisk[i].major = MAJOR_NR + i;
                 ida_gendisk[i].major_name = "ida";
                 ida_gendisk[i].minor_shift = NWD_SHIFT;
                 ida_gendisk[i].max_p = 16;
                 ida_gendisk[i].max_nr = 16;
- ida_gendisk[i].init = ida_geninit;
                 ida_gendisk[i].part = ida + (i*256);
                 ida_gendisk[i].sizes = ida_sizes + (i*256);
                 /* ida_gendisk[i].nr_real is handled by getgeometry */
-
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i), request_fns[i]);
- blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 0);
-
- blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
- hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
- read_ahead[MAJOR_NR+i] = READ_AHEAD;
 
                 /* Get on the disk list */
                 ida_gendisk[i].next = gendisk_head;
@@ -487,6 +479,10 @@
                 hba[i]->timer.function = ida_timer;
                 add_timer(&hba[i]->timer);
 
+ ida_geninit(i);
+ for(j=0; j<NWD; j++)
+ grok_partitions(&ida_gendisk[i], j, 16,
+ hba[i]->drv[j].nr_blks);
         }
         /* done ! */
         return;
@@ -1494,7 +1490,7 @@
         getgeometry(ctlr);
         hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY);
 
- ida_geninit(&ida_gendisk[ctlr]);
+ ida_geninit(ctlr);
         for(i=0; i<NWD; i++)
                 if (ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)])
                         revalidate_logvol(dev+(i<<NWD_SHIFT), 2);
@@ -1545,8 +1541,8 @@
                 blksize_size[MAJOR_NR+ctlr][minor] = 1024;
         }
 
- gdev->part[start].nr_sects = hba[ctlr]->drv[target].nr_blks;
- resetup_one_dev(gdev, target);
+ /* 16 minors per disk... */
+ grok_partitions(gdev, target, 16, hba[ctlr]->drv[target].nr_blks);
         hba[ctlr]->drv[target].usage_count--;
         return 0;
 }
diff -urN linux-2.3.40-pre4/drivers/block/hd.c linux-bird.bdev/drivers/block/hd.c
--- linux-2.3.40-pre4/drivers/block/hd.c Tue Jan 11 00:21:05 2000
+++ linux-bird.bdev/drivers/block/hd.c Sat Jan 15 01:25:22 2000
@@ -662,15 +662,12 @@
         return 0;
 }
 
-static void hd_geninit(struct gendisk *);
-
 static struct gendisk hd_gendisk = {
         MAJOR_NR, /* Major number */
         "hd", /* Major name */
         6, /* Bits to shift to get real from partition */
         1 << 6, /* Number of partitions per real */
         MAX_HD, /* maximum number of real */
- hd_geninit, /* init function */
         hd, /* hd struct */
         hd_sizes, /* block sizes */
         0, /* number */
@@ -699,10 +696,17 @@
  * We enable interrupts in some of the routines after making sure it's
  * safe.
  */
-static void hd_geninit(struct gendisk *ignored)
+static void hd_geninit(void)
 {
         int drive;
 
+ for(drive=0; drive < (MAX_HD << 6); drive++) {
+ hd_blocksizes[drive] = 1024;
+ hd_hardsectsizes[drive] = 512;
+ }
+ blksize_size[MAJOR_NR] = hd_blocksizes;
+ hardsect_size[MAJOR_NR] = hd_hardsectsizes;
+
 #ifdef __i386__
         if (!NR_HD) {
                 extern struct drive_info drive_info;
@@ -765,29 +769,27 @@
 #endif
 
         for (drive=0 ; drive < NR_HD ; drive++) {
- hd[drive<<6].nr_sects = hd_info[drive].head *
- hd_info[drive].sect * hd_info[drive].cyl;
                 printk ("hd%c: %ldMB, CHS=%d/%d/%d\n", drive+'a',
                         hd[drive<<6].nr_sects / 2048, hd_info[drive].cyl,
                         hd_info[drive].head, hd_info[drive].sect);
         }
- if (NR_HD) {
- if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) {
- printk("hd: unable to get IRQ%d for the hard disk driver\n",HD_IRQ);
- NR_HD = 0;
- } else {
- request_region(HD_DATA, 8, "hd");
- request_region(HD_CMD, 1, "hd(cmd)");
- }
+ if (!NR_HD)
+ return;
+
+ if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) {
+ printk("hd: unable to get IRQ%d for the hard disk driver\n",
+ HD_IRQ);
+ NR_HD = 0;
+ return;
         }
+ request_region(HD_DATA, 8, "hd");
+ request_region(HD_CMD, 1, "hd(cmd)");
+
         hd_gendisk.nr_real = NR_HD;
 
- for(drive=0; drive < (MAX_HD << 6); drive++) {
- hd_blocksizes[drive] = 1024;
- hd_hardsectsizes[drive] = 512;
- }
- blksize_size[MAJOR_NR] = hd_blocksizes;
- hardsect_size[MAJOR_NR] = hd_hardsectsizes;
+ for(drive=0; drive < NR_HD; drive++)
+ grok_partitions(&hd_gendisk, drive, 1<<6, hd_info[drive].head *
+ hd_info[drive].sect * hd_info[drive].cyl);
 }
 
 static struct block_device_operations hd_fops = {
@@ -807,6 +809,7 @@
         hd_gendisk.next = gendisk_head;
         gendisk_head = &hd_gendisk;
         timer_table[HD_TIMER].fn = hd_times_out;
+ hd_geninit();
         return 0;
 }
 
@@ -867,8 +870,7 @@
         MAYBE_REINIT;
 #endif
 
- gdev->part[start].nr_sects = CAPACITY;
- resetup_one_dev(gdev, target);
+ grok_partitions(gdev, target, 1<<6, CAPACITY);
 
         DEVICE_BUSY = 0;
         wake_up(&busy_wait);
diff -urN linux-2.3.40-pre4/drivers/block/ide-probe.c linux-bird.bdev/drivers/block/ide-probe.c
--- linux-2.3.40-pre4/drivers/block/ide-probe.c Wed Dec 22 00:56:42 1999
+++ linux-bird.bdev/drivers/block/ide-probe.c Sat Jan 15 01:25:22 2000
@@ -689,7 +689,6 @@
         gd->max_p = 1<<PARTN_BITS; /* 1 + max partitions / drive */
         gd->max_nr = units; /* max num real drives */
         gd->nr_real = units; /* current num real drives */
- gd->init = &ide_geninit; /* initialization function */
         gd->real_devices= hwif; /* ptr to internal data */
         gd->next = NULL; /* linked list of major devs */
 
diff -urN linux-2.3.40-pre4/drivers/block/ide.c linux-bird.bdev/drivers/block/ide.c
--- linux-2.3.40-pre4/drivers/block/ide.c Sat Jan 15 01:05:16 2000
+++ linux-bird.bdev/drivers/block/ide.c Sat Jan 15 01:28:57 2000
@@ -548,24 +548,23 @@
 }
 
 /*
- * ide_geninit() is called exactly *once* for each major, from genhd.c,
- * at the beginning of the initial partition check for the drives.
+ * ide_geninit() is called exactly *once* for each interface.
  */
-void ide_geninit (struct gendisk *gd)
+void ide_geninit (struct ide_hwif_t *hwif)
 {
         unsigned int unit;
- ide_hwif_t *hwif = gd->real_devices;
+ struct gendisk *gd = hwif->gd;
 
         for (unit = 0; unit < gd->nr_real; ++unit) {
                 ide_drive_t *drive = &hwif->drives[unit];
 
- drive->part[0].nr_sects = current_capacity(drive);
- if (!drive->present || (drive->media != ide_disk && drive->media != ide_floppy) ||
+ grok_partitions(gd,unit,
 #ifdef CONFIG_BLK_DEV_ISAPNP
- (drive->forced_geom && drive->noprobe) ||
+ (drive->forced_geom && drive->noprobe) ||
 #endif /* CONFIG_BLK_DEV_ISAPNP */
- drive->driver == NULL || !drive->part[0].nr_sects)
- drive->part[0].start_sect = -1; /* skip partition check */
+ (drive->media != ide_disk &&
+ drive->media != ide_floppy) ? 1 : 1<<PARTN_BITS,
+ current_capacity(drive));
         }
 }
 
@@ -1775,11 +1774,10 @@
                 drive->part[p].nr_sects = 0;
         };
 
- drive->part[0].nr_sects = current_capacity(drive);
- if ((drive->media != ide_disk && drive->media != ide_floppy) ||
- drive->driver == NULL || !drive->part[0].nr_sects)
- drive->part[0].start_sect = -1;
- resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
+ grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
+ (drive->media != ide_disk &&
+ drive->media != ide_floppy) ? 1 : 1<<PARTN_BITS,
+ current_capacity(drive));
 
         drive->busy = 0;
         wake_up(&drive->wqueue);
@@ -3399,7 +3397,6 @@
 EXPORT_SYMBOL(drive_is_flashcard);
 EXPORT_SYMBOL(ide_timer_expiry);
 EXPORT_SYMBOL(ide_intr);
-EXPORT_SYMBOL(ide_geninit);
 EXPORT_SYMBOL(ide_fops);
 EXPORT_SYMBOL(ide_get_queue);
 EXPORT_SYMBOL(do_ide0_request);
@@ -3481,6 +3478,7 @@
 int __init ide_init (void)
 {
         static char banner_printed = 0;
+ int i;
 
         if (!banner_printed) {
                 printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
@@ -3492,6 +3490,12 @@
         initializing = 1;
         ide_init_builtin_drivers();
         initializing = 0;
+
+ for (i = 0; i < MAX_HWIFS; ++i) {
+ ide_hwif_t *hwif = &ide_hwifs[i];
+ if (hwif->present)
+ ide_geninit(hwif);
+ }
 
         return 0;
 }
diff -urN linux-2.3.40-pre4/drivers/block/md.c linux-bird.bdev/drivers/block/md.c
--- linux-2.3.40-pre4/drivers/block/md.c Tue Jan 11 00:21:05 2000
+++ linux-bird.bdev/drivers/block/md.c Sat Jan 15 01:25:22 2000
@@ -77,8 +77,6 @@
 
 int md_size[MAX_MD_DEV]={0, };
 
-static void md_geninit (struct gendisk *);
-
 static struct gendisk md_gendisk=
 {
   MD_MAJOR,
@@ -86,7 +84,6 @@
   0,
   1,
   MAX_MD_DEV,
- md_geninit,
   md_hd_struct,
   md_size,
   MAX_MD_DEV,
@@ -909,22 +906,20 @@
 }
 #endif
 
-static void md_geninit (struct gendisk *gdisk)
+static void md_geninit (void)
 {
   int i;
   
+ blksize_size[MD_MAJOR] = md_blocksizes;
+ max_readahead[MD_MAJOR] = md_maxreadahead;
   for(i=0;i<MAX_MD_DEV;i++)
   {
     md_blocksizes[i] = 1024;
     md_maxreadahead[i] = MD_DEFAULT_DISK_READAHEAD;
- md_gendisk.part[i].start_sect=-1; /* avoid partition check */
- md_gendisk.part[i].nr_sects=0;
     md_dev[i].pers=NULL;
+ grok_partitions(&md_gendisk, i, 1, 0);
   }
 
- blksize_size[MD_MAJOR] = md_blocksizes;
- max_readahead[MD_MAJOR] = md_maxreadahead;
-
 #ifdef CONFIG_PROC_FS
         create_proc_read_entry("mdstat", 0, NULL, md_status_read_proc, NULL);
 #endif
@@ -1265,6 +1260,7 @@
 #ifdef CONFIG_MD_RAID5
   raid5_init ();
 #endif
+ md_geninit();
   return (0);
 }
 
diff -urN linux-2.3.40-pre4/drivers/block/paride/pd.c linux-bird.bdev/drivers/block/paride/pd.c
--- linux-2.3.40-pre4/drivers/block/paride/pd.c Tue Jan 11 00:21:05 2000
+++ linux-bird.bdev/drivers/block/paride/pd.c Sat Jan 15 01:25:22 2000
@@ -263,7 +263,7 @@
 #ifdef MODULE
 void cleanup_module( void );
 #endif
-static void pd_geninit(struct gendisk *ignored);
+static void pd_geninit(void);
 static int pd_open(struct inode *inode, struct file *file);
 static void do_pd_request(request_queue_t * q);
 static int pd_ioctl(struct inode *inode,struct file *file,
@@ -346,7 +346,6 @@
         PD_BITS, /* Bits to shift to get real from partition */
         PD_PARTNS, /* Number of partitions per real */
         PD_UNITS, /* maximum number of real */
- pd_geninit, /* init function */
         pd_hd, /* hd struct */
         pd_sizes, /* block sizes */
         0, /* number */
@@ -401,21 +400,24 @@
         pd_gendisk.major = major;
         pd_gendisk.major_name = name;
         pd_gendisk.next = gendisk_head;
- gendisk_head = &pd_gendisk;
+ gendisk_head = &pd_gendisk;
 
- for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
- blksize_size[MAJOR_NR] = pd_blocksizes;
+ for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
+ blksize_size[MAJOR_NR] = pd_blocksizes;
 
- printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
- name,name,PD_VERSION,major,cluster,nice);
+ printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
+ name,name,PD_VERSION,major,cluster,nice);
+ pd_geninit();
         
         return 0;
 }
 
-static void pd_geninit (struct gendisk *ignored)
-
-{ pd_init_units();
+static void pd_geninit (void)
+{
+ pd_init_units();
+ pd_valid = 0;
         pd_gendisk.nr_real = pd_detect();
+ pd_valid = 1;
 
 #ifdef MODULE
         if (!pd_gendisk.nr_real) cleanup_module();
@@ -502,8 +504,6 @@
 { kdev_t devp;
         int unit;
 
- struct super_block *sb;
-
         devp = inode->i_rdev;
         unit = DEVICE_NR(devp);
 
@@ -566,8 +566,8 @@
                 pd_hd[minor].nr_sects = 0;
         }
 
- pd_identify(unit);
- resetup_one_dev(&pd_gendisk,unit);
+ if (pd_identify(unit))
+ grok_partitions(&pd_gendisk,unit,1<<PD_BITS,PD.capacity);
 
         pd_valid = 1;
         wake_up(&pd_wait_open);
@@ -594,15 +594,8 @@
         err = pd_init();
         if (err) return err;
 
- pd_geninit(&pd_gendisk);
-
         if (!pd_gendisk.nr_real) return -1;
 
- pd_valid = 0;
- for (unit=0;unit<PD_UNITS;unit++)
- if (PD.present) resetup_one_dev(&pd_gendisk,unit);
- pd_valid = 1;
-
         return 0;
 }
 
@@ -815,21 +808,19 @@
 
         if (PD.capacity) pd_init_dev_parms(unit);
         if (!PD.standby) pd_standby_off(unit);
-
- pd_hd[unit<<PD_BITS].nr_sects = PD.capacity;
- pd_hd[unit<<PD_BITS].start_sect = 0;
         
         return 1;
 }
 
 static int pd_probe_drive( int unit )
-
-{ if (PD.drive == -1) {
- for (PD.drive=0;PD.drive<=1;PD.drive++)
- if (pd_identify(unit)) return 1;
- return 0;
- }
- else return pd_identify(unit);
+{
+ if (PD.drive == -1) {
+ for (PD.drive=0;PD.drive<=1;PD.drive++)
+ if (pd_identify(unit))
+ return 1;
+ return 0;
+ }
+ return pd_identify(unit);
 }
 
 static int pd_detect( void )
@@ -843,6 +834,7 @@
                      PI_PD,verbose,PD.name)) {
                 if (pd_probe_drive(unit)) {
                         PD.present = 1;
+ grok_partitions(&pd_gendisk,unit,PD_PARTNS,PD.capacity);
                         k = 1;
                 } else pi_release(PI);
             }
@@ -853,6 +845,7 @@
                         PI_PD,verbose,PD.name)) {
                 if (pd_probe_drive(unit)) {
                         PD.present = 1;
+ grok_partitions(&pd_gendisk,unit,PD_PARTNS,PD.capacity);
                         k = unit+1;
                 } else pi_release(PI);
             }
@@ -862,9 +855,8 @@
    This can result in some bogus error messages if non-sequential
    drive numbers are used.
 */
-
- if (k) return k;
-
+ if (k)
+ return k;
         printk("%s: no valid drive found\n",name);
         return 0;
 }
diff -urN linux-2.3.40-pre4/drivers/block/ps2esdi.c linux-bird.bdev/drivers/block/ps2esdi.c
--- linux-2.3.40-pre4/drivers/block/ps2esdi.c Tue Jan 11 00:21:05 2000
+++ linux-bird.bdev/drivers/block/ps2esdi.c Sat Jan 15 01:25:22 2000
@@ -68,7 +68,7 @@
 
 int ps2esdi_init(void);
 
-static void ps2esdi_geninit(struct gendisk *ignored);
+static void ps2esdi_geninit(void);
 
 static void do_ps2esdi_request(request_queue_t * q);
 
@@ -161,7 +161,6 @@
         6, /* Bits to shift to get real from partition */
         1 << 6, /* Number of partitions per real disk */
         MAX_HD, /* maximum number of real disks */
- ps2esdi_geninit, /* init function */
         ps2esdi, /* hd struct */
         ps2esdi_sizes, /* block sizes */
         0, /* number */
@@ -186,8 +185,8 @@
         /* some minor housekeeping - setup the global gendisk structure */
         ps2esdi_gendisk.next = gendisk_head;
         gendisk_head = &ps2esdi_gendisk;
+ ps2esdi_geninit();
         return 0;
-
 } /* ps2esdi_init */
 
 #ifdef MODULE
@@ -291,7 +290,7 @@
 }
 
 /* ps2 esdi specific initialization - called thru the gendisk chain */
-static void __init ps2esdi_geninit(struct gendisk *ignored)
+static void __init ps2esdi_geninit(void)
 {
         /*
            The first part contains the initialization code
@@ -414,20 +413,19 @@
 
         ps2esdi_gendisk.nr_real = ps2esdi_drives;
 
- for (i = 0; i < ps2esdi_drives; i++) {
- ps2esdi[i << 6].nr_sects =
- ps2esdi_info[i].head *
- ps2esdi_info[i].sect *
- ps2esdi_info[i].cyl;
- ps2esdi_valid[i] = 1;
- }
         for (i = 0; i < (MAX_HD << 6); i++)
                 ps2esdi_blocksizes[i] = 1024;
 
         request_dma(dma_arb_level, "ed");
         request_region(io_base, 4, "ed");
         blksize_size[MAJOR_NR] = ps2esdi_blocksizes;
-} /* ps2esdi_geninit */
+
+ for (i = 0; i < ps2esdi_drives; i++) {
+ grok_partitions(&ps2esdi_gendisk,i,1<<6,ps2esdi_info[i].head *
+ ps2esdi_info[i].sect * ps2esdi_info[i].cyl);
+ ps2esdi_valid[i] = 1;
+ }
+}
 
 
 static void __init ps2esdi_get_device_cfg(void)
@@ -1189,9 +1187,8 @@
                 ps2esdi_gendisk.part[start + partition].nr_sects = 0;
         }
 
- ps2esdi_gendisk.part[start].nr_sects = ps2esdi_info[target].head *
- ps2esdi_info[target].cyl * ps2esdi_info[target].sect;
- resetup_one_dev(&ps2esdi_gendisk, target);
+ grok_partitions(&ps2esdi_gendisk, target, 1<<6,
+ ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect);
 
         ps2esdi_valid[target] = 1;
         wake_up(&ps2esdi_wait_open);
diff -urN linux-2.3.40-pre4/drivers/block/xd.c linux-bird.bdev/drivers/block/xd.c
--- linux-2.3.40-pre4/drivers/block/xd.c Tue Jan 11 00:21:05 2000
+++ linux-bird.bdev/drivers/block/xd.c Sat Jan 15 01:25:22 2000
@@ -136,11 +136,6 @@
         6, /* Bits to shift to get real from partition */
         1 << 6, /* Number of partitions per real */
         XD_MAXDRIVES, /* maximum number of real */
-#ifdef MODULE
- NULL, /* called from init_module */
-#else
- xd_geninit, /* init function */
-#endif
         xd_struct, /* hd struct */
         xd_sizes, /* block sizes */
         0, /* number */
@@ -181,6 +176,7 @@
         read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
         xd_gendisk.next = gendisk_head;
         gendisk_head = &xd_gendisk;
+ xd_geninit();
 
         return 0;
 }
@@ -210,16 +206,21 @@
 
 /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */
 /* and set up the "raw" device entries in the table */
-static void __init xd_geninit (struct gendisk *ignored)
+static void __init xd_geninit (void)
 {
         u_char i,controller;
         unsigned int address;
 
+ for(i=0;i<(XD_MAXDRIVES << 6);i++) xd_blocksizes[i] = 1024;
+ blksize_size[MAJOR_NR] = xd_blocksizes;
+
         if (xd_detect(&controller,&address)) {
 
- printk("Detected a%s controller (type %d) at address %06x\n",xd_sigs[controller].name,controller,address);
+ printk("Detected a%s controller (type %d) at address %06x\n",
+ xd_sigs[controller].name,controller,address);
                 if (check_region(xd_iobase,4)) {
- printk("xd: Ports at 0x%x are not available\n",xd_iobase);
+ printk("xd: Ports at 0x%x are not available\n",
+ xd_iobase);
                         return;
                 }
                 request_region(xd_iobase,4,"xd");
@@ -227,9 +228,12 @@
                         xd_sigs[controller].init_controller(address);
                 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
                 
- printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
+ printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
+ xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
                 for (i = 0; i < xd_drives; i++)
- printk(" xd%c: CHS=%d/%d/%d\n",'a'+i,xd_info[i].cylinders,xd_info[i].heads,xd_info[i].sectors);
+ printk(" xd%c: CHS=%d/%d/%d\n",'a'+i,
+ xd_info[i].cylinders,xd_info[i].heads,
+ xd_info[i].sectors);
 
         }
         if (xd_drives) {
@@ -244,14 +248,13 @@
         }
 
         for (i = 0; i < xd_drives; i++) {
- xd_struct[i << 6].nr_sects = xd_info[i].heads * xd_info[i].cylinders * xd_info[i].sectors;
                 xd_valid[i] = 1;
+ grok_partitions(&xd_gendisk, i, 1<<6, xd_info[i].heads *
+ xd_info[i].cylinders * xd_info[i].sectors);
         }
 
         xd_gendisk.nr_real = xd_drives;
 
- for(i=0;i<(XD_MAXDRIVES << 6);i++) xd_blocksizes[i] = 1024;
- blksize_size[MAJOR_NR] = xd_blocksizes;
 }
 
 /* xd_open: open a device */
@@ -406,8 +409,8 @@
                 xd_gendisk.part[minor].nr_sects = 0;
         };
 
- xd_gendisk.part[start].nr_sects = xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors;
- resetup_one_dev(&xd_gendisk,target);
+ grok_partitions(&xd_gendisk, target, 1<<6,
+ xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors);
 
         xd_valid[target] = 1;
         wake_up(&xd_wait_open);
@@ -1145,27 +1148,26 @@
 int init_module(void)
 {
         int i,count = 0;
- int error = xd_init();
- if (!error)
- {
- printk(KERN_INFO "XD: Loaded as a module.\n");
- for (i = 4; i > 0; i--)
- if(((xd[i] = xd[i-1]) >= 0) && !count)
- count = i;
- if((xd[0] = count))
- xd_setup(NULL, xd);
- xd_geninit(&(struct gendisk) { 0,0,0,0,0,0,0,0,0,0,0 });
- if (!xd_drives) {
- /* no drives detected - unload module */
- unregister_blkdev(MAJOR_NR, "xd");
- xd_done();
- return (-1);
- }
- for (i = 0; i < xd_drives; i++)
- resetup_one_dev(&xd_gendisk, i);
+ int error;
+
+ for (i = 4; i > 0; i--)
+ if(((xd[i] = xd[i-1]) >= 0) && !count)
+ count = i;
+ if((xd[0] = count))
+ xd_setup(NULL, xd);
+
+ if (error = xd_init())
+ return error;
+
+ printk(KERN_INFO "XD: Loaded as a module.\n");
+ if (!xd_drives) {
+ /* no drives detected - unload module */
+ unregister_blkdev(MAJOR_NR, "xd");
+ xd_done();
+ return (-1);
         }
         
- return error;
+ return 0;
 }
 
 void cleanup_module(void)
diff -urN linux-2.3.40-pre4/drivers/block/xd.h linux-bird.bdev/drivers/block/xd.h
--- linux-2.3.40-pre4/drivers/block/xd.h Mon Dec 13 02:02:23 1999
+++ linux-bird.bdev/drivers/block/xd.h Sat Jan 15 01:25:22 2000
@@ -109,7 +109,7 @@
 #endif /* MODULE */
 static u_char xd_detect (u_char *controller, unsigned int *address);
 static u_char xd_initdrives (void (*init_drive)(u_char drive));
-static void xd_geninit (struct gendisk *);
+static void xd_geninit (void);
 
 static int xd_open (struct inode *inode,struct file *file);
 static void do_xd_request (request_queue_t * q);
diff -urN linux-2.3.40-pre4/drivers/i2o/i2o_block.c linux-bird.bdev/drivers/i2o/i2o_block.c
--- linux-2.3.40-pre4/drivers/i2o/i2o_block.c Tue Jan 11 00:21:06 2000
+++ linux-bird.bdev/drivers/i2o/i2o_block.c Sat Jan 15 01:25:22 2000
@@ -821,7 +821,6 @@
         i2ob_query_device(dev, 0x0000, 6, &status, 4);
         i2ob_sizes[unit] = (int)(size>>10);
         i2ob_hardsizes[unit] = blocksize;
- i2ob_gendisk.part[unit].nr_sects = i2ob_sizes[unit];
 
         limit=4096; /* 8 deep scatter gather */
 
@@ -869,7 +868,7 @@
         printk(".\n");
         printk("%s: Maximum sectors/read set to %d.\n",
                 d->dev_name, i2ob_max_sectors[unit]);
- resetup_one_dev(&i2ob_gendisk, unit>>4);
+ grok_partitions(&i2ob_gendisk, unit>>4, 1<<4, (long)(size>>9));
         return 0;
 }
 
@@ -1013,14 +1012,6 @@
         check_media_change: i2ob_media_change,
         revalidate: i2ob_revalidate,
 };
-
-/*
- * Partitioning
- */
-
-static void i2ob_geninit(struct gendisk *gd)
-{
-}
         
 static struct gendisk i2ob_gendisk =
 {
@@ -1029,7 +1020,6 @@
         4,
         1<<4,
         MAX_I2OB,
- i2ob_geninit,
         i2ob,
         i2ob_sizes,
         0,
diff -urN linux-2.3.40-pre4/drivers/scsi/sd.c linux-bird.bdev/drivers/scsi/sd.c
--- linux-2.3.40-pre4/drivers/scsi/sd.c Tue Jan 11 00:21:07 2000
+++ linux-bird.bdev/drivers/scsi/sd.c Sat Jan 15 01:25:22 2000
@@ -469,8 +469,6 @@
         return 0;
 }
 
-static void sd_geninit(struct gendisk *);
-
 static struct block_device_operations sd_fops =
 {
         open: sd_open,
@@ -492,7 +490,6 @@
         4, /* Bits to shift to get real from partition */
         1 << 4, /* Number of partitions per real */
         0, /* maximum number of real */
- sd_geninit, /* init function */
         NULL, /* hd struct */
         NULL, /* block sizes */
         0, /* number */
@@ -505,13 +502,14 @@
 #define SD_GENDISK(i) sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR]
 #define LAST_SD_GENDISK sd_gendisks[N_USED_SD_MAJORS - 1]
 
-static void sd_geninit(struct gendisk *ignored)
+static void sd_geninit(void)
 {
         int i;
 
         for (i = 0; i < sd_template.dev_max; ++i)
                 if (rscsi_disks[i].device)
- sd[i << 4].nr_sects = rscsi_disks[i].capacity;
+ grok_partitions(&SD_GENDISK(i), i%SCSI_DISKS_PER_MAJOR,
+ 1<<4, rscsi_disks[i].capacity);
 }
 
 /*
@@ -1019,7 +1017,6 @@
                 sd_gendisks[i].minor_shift = 4;
                 sd_gendisks[i].max_p = 1 << 4;
                 sd_gendisks[i].max_nr = SCSI_DISKS_PER_MAJOR;
- sd_gendisks[i].init = sd_geninit;
                 sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);
                 sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);
                 sd_gendisks[i].nr_real = 0;
@@ -1031,6 +1028,7 @@
         LAST_SD_GENDISK.max_nr =
             (sd_template.dev_max - 1) % SCSI_DISKS_PER_MAJOR + 1;
         LAST_SD_GENDISK.next = NULL;
+ sd_geninit();
         return 0;
 }
 
@@ -1175,11 +1173,8 @@
         MAYBE_REINIT;
 #endif
 
- sd_gendisks->part[start].nr_sects = CAPACITY;
- if (!rscsi_disks[target].device)
- return -EBUSY;
- resetup_one_dev(&SD_GENDISK(target),
- target % SCSI_DISKS_PER_MAJOR);
+ grok_partitions(&SD_GENDISK(target), target % SCSI_DISKS_PER_MAJOR,
+ 1<<4, CAPACITY);
 
         DEVICE_BUSY = 0;
         return 0;
diff -urN linux-2.3.40-pre4/fs/partitions/check.c linux-bird.bdev/fs/partitions/check.c
--- linux-2.3.40-pre4/fs/partitions/check.c Mon Aug 30 13:24:14 1999
+++ linux-bird.bdev/fs/partitions/check.c Sat Jan 15 01:25:22 2000
@@ -234,7 +234,7 @@
 }
 #endif
 
-void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
+static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
 {
         static int first_time = 1;
         unsigned long first_sector;
@@ -272,13 +272,18 @@
  * Much of the cleanup from the old partition tables should have already been
  * done
  */
-void resetup_one_dev(struct gendisk *dev, int drive)
+
+void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size)
 {
         int i;
         int first_minor = drive << dev->minor_shift;
         int end_minor = first_minor + dev->max_p;
 
         blk_size[dev->major] = NULL;
+ dev->part[first_minor].nr_sects = size;
+ /* No Such Agen^Wdevice or no minors to use for partitions */
+ if (!size || minors == 1)
+ return;
         check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
 
          /*
@@ -292,30 +297,9 @@
         }
 }
 
-static inline void setup_dev(struct gendisk *dev)
-{
- int i, drive;
- int end_minor = dev->max_nr * dev->max_p;
-
- blk_size[dev->major] = NULL;
- for (i = 0; i < end_minor; i++) {
- dev->part[i].start_sect = 0;
- dev->part[i].nr_sects = 0;
- dev->sizes[i] = 0;
- }
- dev->init(dev);
- for (drive = 0 ; drive < dev->nr_real ; drive++)
- resetup_one_dev(dev, drive);
-}
-
 int __init partition_setup(void)
 {
- struct gendisk *p;
-
         device_init();
-
- for (p = gendisk_head ; p ; p=p->next)
- setup_dev(p);
 
 #ifdef CONFIG_BLK_DEV_RAM
 #ifdef CONFIG_BLK_DEV_INITRD
diff -urN linux-2.3.40-pre4/include/linux/blkdev.h linux-bird.bdev/include/linux/blkdev.h
--- linux-2.3.40-pre4/include/linux/blkdev.h Tue Dec 28 20:43:02 1999
+++ linux-bird.bdev/include/linux/blkdev.h Sat Jan 15 01:25:22 2000
@@ -104,7 +104,7 @@
 extern struct sec_size * blk_sec[MAX_BLKDEV];
 extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
 extern wait_queue_head_t wait_for_request;
-extern void resetup_one_dev(struct gendisk *dev, int drive);
+extern void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size);
 extern void unplug_device(void * data);
 extern void make_request(int major,int rw, struct buffer_head * bh);
 
diff -urN linux-2.3.40-pre4/include/linux/genhd.h linux-bird.bdev/include/linux/genhd.h
--- linux-2.3.40-pre4/include/linux/genhd.h Fri Dec 10 17:58:51 1999
+++ linux-bird.bdev/include/linux/genhd.h Sat Jan 15 01:25:22 2000
@@ -55,7 +55,6 @@
         int max_p; /* maximum partitions per device */
         int max_nr; /* maximum number of real devices */
 
- void (*init)(struct gendisk *); /* Initialization called before we do our thing */
         struct hd_struct *part; /* [indexed by minor] */
         int *sizes; /* [idem], device size in blocks */
         int nr_real; /* number of real devices */
diff -urN linux-2.3.40-pre4/include/linux/ide.h linux-bird.bdev/include/linux/ide.h
--- linux-2.3.40-pre4/include/linux/ide.h Sat Jan 15 01:05:20 2000
+++ linux-bird.bdev/include/linux/ide.h Sat Jan 15 01:25:22 2000
@@ -757,7 +757,6 @@
 int ide_spin_wait_hwgroup(ide_drive_t *drive, unsigned long *flags);
 void ide_timer_expiry (unsigned long data);
 void ide_intr (int irq, void *dev_id, struct pt_regs *regs);
-void ide_geninit (struct gendisk *gd);
 void do_ide0_request (request_queue_t * q);
 #if MAX_HWIFS > 1
 void do_ide1_request (request_queue_t * q);
diff -urN linux-2.3.40-pre4/kernel/ksyms.c linux-bird.bdev/kernel/ksyms.c
--- linux-2.3.40-pre4/kernel/ksyms.c Sat Jan 15 01:05:20 2000
+++ linux-bird.bdev/kernel/ksyms.c Sat Jan 15 01:25:22 2000
@@ -262,7 +262,7 @@
 EXPORT_SYMBOL(blkdev_put);
 EXPORT_SYMBOL(ioctl_by_bdev);
 EXPORT_SYMBOL(gendisk_head);
-EXPORT_SYMBOL(resetup_one_dev);
+EXPORT_SYMBOL(grok_partitions);
 EXPORT_SYMBOL(unplug_device);
 EXPORT_SYMBOL(make_request);
 EXPORT_SYMBOL(tq_disk);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Jan 15 2000 - 21:00:25 EST