Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Viro <viro@math.psu.edu>2002-07-31 23:33:24 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-07-31 23:33:24 -0700
commit3f41fa2f9a08aff674b55458ec39c578f57de8a8 (patch)
tree20626607a58daf923c66e66c42c4fc37043784a5
parentd7536161a456543c86286e4f4f2928eef4297fdb (diff)
[PATCH] split "gendisk" to be per-disk, part 2
we are starting to split gendisks - now we can do that. Done for ide, sd, pd, hd and mfm It's in transit - what we are aiming at is getting ->nr_real to 1 for all gendisks. Once that will be done we will be able to simplify a lot stuff and remove ad-hackery. First thing that will happen after that is death of ->nr_real, obviouslye. Then we (a) will merge ->major and ->first_minor into ->dev (b) strip one level of indirection from ->driverfs_dev_arr, ->de_arr and ->flags - they turn into single-element arrays and we will simply pull the (only) element into struct gendisk. Kills a lot of ad-hackery in splitup code (fewer things to allocate). (c) replace ->major_name with ->disk_name; kills most of the crap in disk_name(9) - it only has to care about adding partition number to the name.
-rw-r--r--drivers/acorn/block/mfmhd.c23
-rw-r--r--drivers/block/genhd.c4
-rw-r--r--drivers/block/paride/pd.c46
-rw-r--r--drivers/ide/hd.c23
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-floppy.c4
-rw-r--r--drivers/ide/main.c9
-rw-r--r--drivers/ide/probe.c56
-rw-r--r--drivers/scsi/sd.c139
-rw-r--r--include/linux/ide.h2
10 files changed, 146 insertions, 164 deletions
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index b2a1c64a1467..d29f53874d08 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -1253,11 +1253,20 @@ void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack,
}
}
-static struct gendisk mfm_gendisk = {
+static struct gendisk mfm_gendisk[2] = {
+{
major: MAJOR_NR,
+ first_minor: 0,
major_name: "mfm",
minor_shift: 6,
part: mfm,
+},
+{
+ major: MAJOR_NR,
+ first_minor: 64,
+ major_name: "mfm",
+ minor_shift: 6,
+ part: mfm + 64,
};
static struct block_device_operations mfm_fops =
@@ -1275,8 +1284,6 @@ static void mfm_geninit (void)
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);
@@ -1284,8 +1291,10 @@ static void mfm_geninit (void)
outw(0x80, mfm_irqenable); /* Required to enable IRQs from MFM podule */
for (i = 0; i < mfm_drives; i++) {
+ mfm_gendisk[i].nr_real = 1;
+ add_gendisk(mfm_gendisk + i);
mfm_geometry (i);
- register_disk(&mfm_gendisk, mk_kdev(MAJOR_NR,i<<6), 1<<6,
+ register_disk(mfm_gendisk + i, mk_kdev(MAJOR_NR,i<<6), 1<<6,
&mfm_fops,
mfm_info[i].cylinders * mfm_info[i].heads *
mfm_info[i].sectors / 2);
@@ -1380,8 +1389,6 @@ int mfm_init (void)
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_mfm_request);
- add_gendisk(&mfm_gendisk);
-
Busy = 0;
lastspecifieddrive = -1;
@@ -1419,11 +1426,13 @@ int init_module(void)
void cleanup_module(void)
{
+ int i;
if (ecs && mfm_irqenable)
outw (0, mfm_irqenable); /* Required to enable IRQs from MFM podule */
free_irq(mfm_irq, NULL);
unregister_blkdev(MAJOR_NR, "mfm");
- del_gendisk(&mfm_gendisk);
+ for (i = 0; i < mfm_drives; i++)
+ del_gendisk(mfm_gendisk + i);
if (ecs)
ecard_release(ecs);
if (mfm_addr)
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 0917d42da972..bf9ceb8fe403 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -55,8 +55,8 @@ add_gendisk(struct gendisk *gp)
{
if (sgp == gp)
{
-// printk(KERN_ERR "add_gendisk: device major %d is buggy and added a live gendisk!\n",
-// sgp->major)
+ printk(KERN_ERR "add_gendisk: device major %d is buggy and added a live gendisk!\n",
+ sgp->major)
goto out;
}
}
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 2daf420f0ebe..746da3ccd3a9 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -291,6 +291,7 @@ struct pd_unit {
int alt_geom;
int present;
char name[PD_NAMELEN]; /* pda, pdb, etc ... */
+ struct gendisk gd;
};
struct pd_unit pd[PD_UNITS];
@@ -330,8 +331,8 @@ static struct gendisk pd_gendisk = {
major: PD_MAJOR,
major_name: PD_NAME,
minor_shift: PD_BITS,
- part: pd_hd,
fops: &pd_fops,
+ nr_real: 1,
};
static struct block_device_operations pd_fops = {
@@ -680,8 +681,8 @@ static int pd_probe_drive( int unit )
}
static int pd_detect( void )
-
-{ int k, unit;
+{
+ int k, unit;
k = 0;
if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
@@ -703,18 +704,19 @@ static int pd_detect( void )
k = unit+1;
} else pi_release(PI);
}
- for (unit=0;unit<PD_UNITS;unit++)
- register_disk(&pd_gendisk,mk_kdev(MAJOR_NR,unit<<PD_BITS),
- PD_PARTNS,&pd_fops,
- PD.present?PD.capacity:0);
-
-/* We lie about the number of drives found, as the generic partition
- scanner assumes that the drives are numbered sequentially from 0.
- This can result in some bogus error messages if non-sequential
- drive numbers are used.
-*/
+ for (unit=0;unit<PD_UNITS;unit++) {
+ if (PD.present) {
+ PD.gd = pd_gendisk;
+ PD.gd.first_minor = unit << PD_BITS;
+ PD.gd.part = pd_hd + (unit << PD_BITS);
+ add_gendisk(&PD.gd);
+ register_disk(&PD.gd,mk_kdev(MAJOR_NR,unit<<PD_BITS),
+ PD_PARTNS,&pd_fops,
+ PD.capacity);
+ }
+ }
if (k)
- return k;
+ return 1;
printk("%s: no valid drive found\n",name);
return 0;
}
@@ -935,8 +937,6 @@ static void do_pd_write_done( void )
static int __init pd_init(void)
{
request_queue_t * q;
- int unit;
-
if (disable) return -1;
if (register_blkdev(MAJOR_NR,name,&pd_fops)) {
printk("%s: unable to get major number %d\n",
@@ -949,18 +949,11 @@ static int __init pd_init(void)
pd_gendisk.major = major;
pd_gendisk.major_name = name;
- add_gendisk(&pd_gendisk);
-
printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
name,name,PD_VERSION,major,cluster,nice);
pd_init_units();
- pd_gendisk.nr_real = pd_detect();
- if (!pd_gendisk.nr_real) {
+ if (!pd_detect()) {
unregister_blkdev(MAJOR_NR, name);
- del_gendisk(&pd_gendisk);
- for (unit=0; unit<PD_UNITS; unit++)
- if (PD.present)
- pi_release(PI);
return -1;
}
return 0;
@@ -970,10 +963,11 @@ static void __exit pd_exit(void)
{
int unit;
unregister_blkdev(MAJOR_NR, name);
- del_gendisk(&pd_gendisk);
for (unit=0; unit<PD_UNITS; unit++)
- if (PD.present)
+ if (PD.present) {
+ del_gendisk(&PD.gd);
pi_release(PI);
+ }
}
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c
index 07c83415f587..91403c27419f 100644
--- a/drivers/ide/hd.c
+++ b/drivers/ide/hd.c
@@ -708,12 +708,22 @@ static int hd_open(struct inode * inode, struct file * filp)
extern struct block_device_operations hd_fops;
-static struct gendisk hd_gendisk = {
+static struct gendisk hd_gendisk[2] = {
+{
.major = MAJOR_NR,
+ .first_minor = 0,
.major_name = "hd",
.minor_shift = 6,
.part = hd,
.fops = &hd_fops,
+},{
+ .major = MAJOR_NR,
+ .first_minor = 64,
+ .major_name = "hd",
+ .minor_shift = 6,
+ .part = hd + 64,
+ .fops = &hd_fops,
+}
};
static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -845,12 +855,14 @@ static void __init hd_geninit(void)
return;
}
- hd_gendisk.nr_real = NR_HD;
-
- for(drive=0; drive < NR_HD; drive++)
- register_disk(&hd_gendisk, mk_kdev(MAJOR_NR,drive<<6), 1<<6,
+ for(drive=0; drive < NR_HD; drive++) {
+ hd_gendisk[i].nr_real = 1;
+ add_gendisk(hd_gendisk + drive);
+ register_disk(hd_gendisk + drive,
+ mk_kdev(MAJOR_NR,drive<<6), 1<<6,
&hd_fops, hd_info[drive].head * hd_info[drive].sect *
hd_info[drive].cyl);
+ }
}
int __init hd_init(void)
@@ -861,7 +873,6 @@ int __init hd_init(void)
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_hd_request, &hd_lock);
blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 255);
- add_gendisk(&hd_gendisk);
init_timer(&device_timer);
device_timer.function = hd_times_out;
hd_geninit();
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 739f634fa69c..58499ebbfa4e 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1064,9 +1064,9 @@ static void idedisk_setup(struct ata_device *drive)
if (drive != &ch->drives[i])
continue;
drvid = i;
- ch->gd->de_arr[i] = drive->de;
+ ch->gd[i]->de_arr[0] = drive->de;
if (drive->removable)
- ch->gd->flags[i] |= GENHD_FL_REMOVABLE;
+ ch->gd[i]->flags[0] |= GENHD_FL_REMOVABLE;
break;
}
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 4651a5319935..56d076b902ff 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1712,9 +1712,9 @@ static void idefloppy_setup(struct ata_device *drive, idefloppy_floppy_t *floppy
struct ata_channel *hwif = drive->channel;
if (drive != &hwif->drives[i]) continue;
- hwif->gd->de_arr[i] = drive->de;
+ hwif->gd[i]->de_arr[0] = drive->de;
if (drive->removable)
- hwif->gd->flags[i] |= GENHD_FL_REMOVABLE;
+ hwif->gd[i]->flags[0] |= GENHD_FL_REMOVABLE;
break;
}
}
diff --git a/drivers/ide/main.c b/drivers/ide/main.c
index 38541845345e..e37abbb65c91 100644
--- a/drivers/ide/main.c
+++ b/drivers/ide/main.c
@@ -488,16 +488,19 @@ void ide_unregister(struct ata_channel *ch)
blk_dev[ch->major].data = NULL;
blk_dev[ch->major].queue = NULL;
blk_clear(ch->major);
- gd = ch->gd;
+ gd = ch->gd[0];
if (gd) {
- del_gendisk(gd);
+ int i;
+ for (i = 0; i < MAX_DRIVES; i++)
+ del_gendisk(gd + i);
kfree(gd->part);
if (gd->de_arr)
kfree (gd->de_arr);
if (gd->flags)
kfree (gd->flags);
kfree(gd);
- ch->gd = NULL;
+ for (i = 0; i < MAX_DRIVES; i++)
+ ch->gd[i] = NULL;
}
/*
diff --git a/drivers/ide/probe.c b/drivers/ide/probe.c
index 08113bc0e4e5..701317fbdd30 100644
--- a/drivers/ide/probe.c
+++ b/drivers/ide/probe.c
@@ -1043,6 +1043,9 @@ static request_queue_t *ata_get_queue(kdev_t dev)
static void channel_init(struct ata_channel *ch)
{
struct gendisk *gd;
+ struct hd_struct *part;
+ devfs_handle_t *de_arr;
+ char *flags;
unsigned int unit;
extern devfs_handle_t ide_devfs_handle;
@@ -1103,39 +1106,42 @@ static void channel_init(struct ata_channel *ch)
/* Initialize partition and global device data.
*/
- gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
+ gd = kmalloc (MAX_DRIVES * sizeof(struct gendisk), GFP_KERNEL);
if (!gd)
goto err_kmalloc_gd;
- memset(gd, 0, sizeof(struct gendisk));
+ memset(gd, 0, MAX_DRIVES * sizeof(struct gendisk));
- gd->part = kmalloc(ATA_MINORS * sizeof(struct hd_struct), GFP_KERNEL);
- if (!gd->part)
+ part = kmalloc(ATA_MINORS * sizeof(struct hd_struct), GFP_KERNEL);
+ if (!part)
goto err_kmalloc_gd_part;
- memset(gd->part, 0, ATA_MINORS * sizeof(struct hd_struct));
+ memset(part, 0, ATA_MINORS * sizeof(struct hd_struct));
- gd->de_arr = kmalloc (sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
- if (!gd->de_arr)
+ de_arr = kmalloc (sizeof(devfs_handle_t) * MAX_DRIVES, GFP_KERNEL);
+ if (!de_arr)
goto err_kmalloc_gd_de_arr;
- memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
+ memset(de_arr, 0, sizeof(devfs_handle_t) * MAX_DRIVES);
- gd->flags = kmalloc (sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
- if (!gd->flags)
+ flags = kmalloc (sizeof(char) * MAX_DRIVES, GFP_KERNEL);
+ if (!flags)
goto err_kmalloc_gd_flags;
- memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
+ memset(flags, 0, sizeof(char) * MAX_DRIVES);
- for (unit = 0; unit < MAX_DRIVES; ++unit)
- ch->drives[unit].part = &gd->part[unit << PARTN_BITS];
-
- gd->major = ch->major; /* our major device number */
- gd->major_name = IDE_MAJOR_NAME; /* treated special in genhd.c */
- gd->minor_shift = PARTN_BITS; /* num bits for partitions */
- gd->nr_real = MAX_DRIVES; /* current num real drives */
- gd->next = NULL; /* linked list of major devs */
- gd->fops = ide_fops; /* file operations */
-
- ch->gd = gd;
- add_gendisk(gd);
+ for (unit = 0; unit < MAX_DRIVES; ++unit) {
+ gd[unit].part = part + (unit << PARTN_BITS);
+ gd[unit].de_arr = de_arr + unit;
+ gd[unit].flags = flags + unit;
+ ch->drives[unit].part = gd[unit].part;
+ gd[unit].major = ch->major;
+ gd[unit].first_minor = unit << PARTN_BITS;
+ /* treated special in genhd.c */
+ gd[unit].major_name = IDE_MAJOR_NAME;
+ gd[unit].minor_shift = PARTN_BITS;
+ gd[unit].nr_real = 1;
+ gd[unit].fops = ide_fops;
+ ch->gd[unit] = gd + unit;
+ add_gendisk(gd + unit);
+ }
for (unit = 0; unit < MAX_DRIVES; ++unit) {
char name[80];
@@ -1156,9 +1162,9 @@ static void channel_init(struct ata_channel *ch)
return;
err_kmalloc_gd_flags:
- kfree(gd->de_arr);
+ kfree(de_arr);
err_kmalloc_gd_de_arr:
- kfree(gd->part);
+ kfree(part);
err_kmalloc_gd_part:
kfree(gd);
err_kmalloc_gd:
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 67addc14739c..911deaf7e380 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -90,8 +90,6 @@ struct hd_struct *sd;
static Scsi_Disk ** sd_dsk_arr;
static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED;
-static int *sd_max_sectors;
-
static int check_scsidisk_media_change(kdev_t);
static int fop_revalidate_scsidisk(kdev_t);
@@ -605,22 +603,7 @@ static struct block_device_operations sd_fops =
revalidate: fop_revalidate_scsidisk
};
-/*
- * If we need more than one SCSI disk major (i.e. more than
- * 16 SCSI disks), we'll have to vmalloc() more gendisks later.
- */
-
-static struct gendisk sd_gendisk =
-{
- major: SCSI_DISK0_MAJOR,
- major_name: "sd",
- minor_shift: 4,
- fops: &sd_fops,
-};
-
-static struct gendisk *sd_gendisks = &sd_gendisk;
-
-#define SD_GENDISK(i) sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR]
+static struct gendisk **sd_disks;
/**
* sd_rw_intr - bottom half handler: called when the lower level
@@ -1224,62 +1207,23 @@ static int sd_init()
sd_dsk_arr[k] = sdkp;
}
}
+ init_mem_lth(sd_disks, sd_template.dev_max);
+ if (sd_disks)
+ zero_mem_lth(sd_disks, sd_template.dev_max);
init_mem_lth(sd, maxparts);
- init_mem_lth(sd_gendisks, N_USED_SD_MAJORS);
- init_mem_lth(sd_max_sectors, sd_template.dev_max << 4);
- if (!sd_dsk_arr || !sd || !sd_gendisks)
+ if (!sd_dsk_arr || !sd || !sd_disks)
goto cleanup_mem;
zero_mem_lth(sd, maxparts);
-
- for (k = 0; k < maxparts; k++) {
- /*
- * Allow lowlevel device drivers to generate 512k large scsi
- * commands if they know what they're doing and they ask for it
- * explicitly via the SHpnt->max_sectors API.
- */
- sd_max_sectors[k] = MAX_PHYS_SEGMENTS*8;
- }
-
- for (k = 0; k < N_USED_SD_MAJORS; k++) {
- int N = SCSI_DISKS_PER_MAJOR;
-
- sd_gendisks[k] = sd_gendisk;
-
- init_mem_lth(sd_gendisks[k].de_arr, N);
- init_mem_lth(sd_gendisks[k].flags, N);
- init_mem_lth(sd_gendisks[k].driverfs_dev_arr, N);
-
- if (!sd_gendisks[k].de_arr || !sd_gendisks[k].flags ||
- !sd_gendisks[k].driverfs_dev_arr)
- goto cleanup_gendisks;
-
- zero_mem_lth(sd_gendisks[k].de_arr, N);
- zero_mem_lth(sd_gendisks[k].flags, N);
- zero_mem_lth(sd_gendisks[k].driverfs_dev_arr, N);
-
- sd_gendisks[k].major = SD_MAJOR(k);
- sd_gendisks[k].major_name = "sd";
- sd_gendisks[k].minor_shift = 4;
- sd_gendisks[k].part = sd + k * (N << 4);
- sd_gendisks[k].nr_real = 0;
- }
return 0;
#undef init_mem_lth
#undef zero_mem_lth
-cleanup_gendisks:
- /* vfree can handle NULL, so no test is required here */
- for (k = 0; k < N_USED_SD_MAJORS; k++) {
- vfree(sd_gendisks[k].de_arr);
- vfree(sd_gendisks[k].flags);
- vfree(sd_gendisks[k].driverfs_dev_arr);
- }
cleanup_mem:
- vfree(sd_gendisks);
- sd_gendisks = NULL;
+ vfree(sd_disks);
+ sd_disks = NULL;
vfree(sd);
sd = NULL;
if (sd_dsk_arr) {
@@ -1310,17 +1254,16 @@ static void sd_finish()
Scsi_Disk * sdkp;
SCSI_LOG_HLQUEUE(3, printk("sd_finish: \n"));
- for (k = 0; k < N_USED_SD_MAJORS; k++) {
+ for (k = 0; k < N_USED_SD_MAJORS; k++)
blk_dev[SD_MAJOR(k)].queue = sd_find_queue;
- add_gendisk(&(sd_gendisks[k]));
- }
for (k = 0; k < sd_template.dev_max; ++k) {
sdkp = sd_get_sdisk(k);
if (sdkp && (0 == sdkp->capacity) && sdkp->device) {
sd_init_onedisk(sdkp, k);
if (!sdkp->has_been_registered) {
- register_disk(&SD_GENDISK(k), MKDEV_SD(k),
+ add_gendisk(sd_disks[k]);
+ register_disk(sd_disks[k], MKDEV_SD(k),
1<<4, &sd_fops,
sdkp->capacity);
sdkp->has_been_registered = 1;
@@ -1366,21 +1309,36 @@ static int sd_detect(Scsi_Device * sdp)
**/
static int sd_attach(Scsi_Device * sdp)
{
- unsigned int devnum;
Scsi_Disk *sdkp;
int dsk_nr;
char diskname[6];
unsigned long iflags;
+ struct {
+ struct gendisk disk;
+ devfs_handle_t de;
+ struct device *dev;
+ char flags;
+ } *p;
+ struct gendisk *gd;
if ((NULL == sdp) ||
((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD)))
return 0;
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return 1;
+ gd = &p->disk;
+ gd->de_arr = &p->de;
+ gd->flags = &p->flags;
+ gd->driverfs_dev_arr = &p->dev;
+
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
if (sd_template.nr_dev >= sd_template.dev_max) {
sdp->attached--;
printk(KERN_ERR "sd_init: no more room for device\n");
+ kfree(p);
return 1;
}
@@ -1400,17 +1358,23 @@ static int sd_attach(Scsi_Device * sdp)
if (dsk_nr >= sd_template.dev_max) {
/* panic("scsi_devices corrupt (sd)"); overkill */
printk(KERN_ERR "sd_init: sd_dsk_arr corrupted\n");
+ kfree(p);
return 1;
}
sd_template.nr_dev++;
- SD_GENDISK(dsk_nr).nr_real++;
- devnum = dsk_nr % SCSI_DISKS_PER_MAJOR;
- SD_GENDISK(dsk_nr).de_arr[devnum] = sdp->de;
- SD_GENDISK(dsk_nr).driverfs_dev_arr[devnum] =
- &sdp->sdev_driverfs_dev;
+ gd->nr_real = 1;
+ gd->de_arr[0] = sdp->de;
+ gd->driverfs_dev_arr[0] = &sdp->sdev_driverfs_dev;
+ gd->major = SD_MAJOR(dsk_nr>>4);
+ gd->first_minor = (dsk_nr & 15)<<4;
+ gd->major_name = "sd";
+ gd->minor_shift = 4;
+ gd->part = sd + (dsk_nr << 4);
+ gd->fops = &sd_fops;
if (sdp->removable)
- SD_GENDISK(dsk_nr).flags[devnum] |= GENHD_FL_REMOVABLE;
+ gd->flags[0] |= GENHD_FL_REMOVABLE;
+ sd_disks[dsk_nr] = gd;
sd_dskname(dsk_nr, diskname);
printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
"id %d, lun %d\n", sdp->removable ? "removable " : "",
@@ -1480,8 +1444,6 @@ static void sd_detach(Scsi_Device * sdp)
Scsi_Disk *sdkp = NULL;
kdev_t dev;
int dsk_nr;
- int max_p;
- int start;
unsigned long iflags;
SCSI_LOG_HLQUEUE(3, printk("sd_detach: <%d,%d,%d,%d>\n",
@@ -1491,7 +1453,6 @@ static void sd_detach(Scsi_Device * sdp)
for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) {
sdkp = sd_dsk_arr[dsk_nr];
if (sdkp->device == sdp) {
- sdkp->has_been_registered = 0;
sdkp->device = NULL;
sdkp->capacity = 0;
/* sdkp->detaching = 1; */
@@ -1502,19 +1463,20 @@ static void sd_detach(Scsi_Device * sdp)
if (dsk_nr >= sd_template.dev_max)
return;
- max_p = 1 << sd_gendisk.minor_shift;
- start = dsk_nr << sd_gendisk.minor_shift;
- dev = MKDEV_SD_PARTITION(start);
- driverfs_remove_partitions(&SD_GENDISK (dsk_nr),
- SD_MINOR_NUMBER (start));
- wipe_partitions(dev);
- devfs_register_partitions (&SD_GENDISK (dsk_nr),
- SD_MINOR_NUMBER (start), 1);
- /* unregister_disk() */
+ if (sdkp->has_been_registered) {
+ sdkp->has_been_registered = 0;
+ dev = MKDEV_SD(dsk_nr);
+ driverfs_remove_partitions(sd_disks[dsk_nr], minor(dev));
+ wipe_partitions(dev);
+ devfs_register_partitions (sd_disks[dsk_nr], minor(dev), 1);
+ /* unregister_disk() */
+ del_gendisk(sd_disks[dsk_nr]);
+ }
sdp->attached--;
sd_template.dev_noticed--;
sd_template.nr_dev--;
- SD_GENDISK(dsk_nr).nr_real--;
+ kfree(sd_disks[dsk_nr]);
+ sd_disks[dsk_nr] = NULL;
}
/**
@@ -1560,12 +1522,9 @@ static void __exit exit_sd(void)
vfree((char *) sd);
for (k = 0; k < N_USED_SD_MAJORS; k++) {
blk_dev[SD_MAJOR(k)].queue = NULL;
- del_gendisk(&(sd_gendisks[k]));
blk_clear(SD_MAJOR(k));
}
sd_template.dev_max = 0;
- if (sd_gendisks != &sd_gendisk)
- vfree(sd_gendisks);
remove_driver(&sd_template.scsi_driverfs_driver);
}
diff --git a/include/linux/ide.h b/include/linux/ide.h
index f65e5649c0e0..6de4ad25531c 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -894,7 +894,7 @@ struct ata_channel {
struct pci_dev *pci_dev; /* for pci chipsets */
#endif
struct ata_device drives[MAX_DRIVES]; /* drive info */
- struct gendisk *gd; /* gendisk structure */
+ struct gendisk *gd[MAX_DRIVES]; /* gendisk structure */
/*
* Routines to tune PIO and DMA mode for drives.