Commit b6b7580f authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] move add_gendisk()/del_gendisk() into ->reinit() and ->cleanup()

add_gendisk()/del_gendisk() moved into ->reinit() and ->cleanup() of
ide-{disk,cd,floppy} - i.e.  moments when high-levle driver claims/gives
up a drive.

register_disk() also shifted into ->reinit().

consequently, revalidate_drives() is gone (it did messy postponed
rereading of partition tables; not needed anymore).  Ditto for
ide_geninit().

regular 2.5 changes in ->revalidate() and BLKRRPART handling - same as
all other block devices.
parent 9e8a6e88
...@@ -3005,14 +3005,8 @@ int ide_cdrom_check_media_change (ide_drive_t *drive) ...@@ -3005,14 +3005,8 @@ int ide_cdrom_check_media_change (ide_drive_t *drive)
static static
void ide_cdrom_revalidate (ide_drive_t *drive) void ide_cdrom_revalidate (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
struct request_sense sense; struct request_sense sense;
cdrom_read_toc(drive, &sense); cdrom_read_toc(drive, &sense);
g->minor_shift = 0;
grok_partitions(mk_kdev(g->major, drive->select.b.unit), current_capacity(drive));
} }
static static
...@@ -3031,6 +3025,9 @@ int ide_cdrom_cleanup(ide_drive_t *drive) ...@@ -3031,6 +3025,9 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
{ {
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo; struct cdrom_device_info *devinfo = &info->devinfo;
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
if (ide_unregister_subdriver (drive)) if (ide_unregister_subdriver (drive))
return 1; return 1;
...@@ -3044,6 +3041,7 @@ int ide_cdrom_cleanup(ide_drive_t *drive) ...@@ -3044,6 +3041,7 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name); printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
kfree(info); kfree(info);
drive->driver_data = NULL; drive->driver_data = NULL;
del_gendisk(g);
return 0; return 0;
} }
...@@ -3094,6 +3092,10 @@ MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); ...@@ -3094,6 +3092,10 @@ MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
static int ide_cdrom_reinit (ide_drive_t *drive) static int ide_cdrom_reinit (ide_drive_t *drive)
{ {
struct cdrom_info *info; struct cdrom_info *info;
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
struct request_sense sense;
if (!strstr("ide-cdrom", drive->driver_req)) if (!strstr("ide-cdrom", drive->driver_req))
goto failed; goto failed;
...@@ -3126,12 +3128,29 @@ static int ide_cdrom_reinit (ide_drive_t *drive) ...@@ -3126,12 +3128,29 @@ static int ide_cdrom_reinit (ide_drive_t *drive)
drive->driver_data = info; drive->driver_data = info;
DRIVER(drive)->busy++; DRIVER(drive)->busy++;
if (ide_cdrom_setup (drive)) { if (ide_cdrom_setup (drive)) {
struct cdrom_device_info *devinfo = &info->devinfo;
DRIVER(drive)->busy--; DRIVER(drive)->busy--;
if (ide_cdrom_cleanup (drive)) ide_unregister_subdriver (drive);
printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name); if (info->buffer != NULL)
kfree(info->buffer);
if (info->toc != NULL)
kfree(info->toc);
if (info->changer_info != NULL)
kfree(info->changer_info);
if (devinfo->handle == drive && unregister_cdrom (devinfo))
printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
kfree(info);
drive->driver_data = NULL;
goto failed; goto failed;
} }
DRIVER(drive)->busy--; DRIVER(drive)->busy--;
cdrom_read_toc(drive, &sense);
g->minor_shift = 0;
add_gendisk(g);
register_disk(g, mk_kdev(g->major,g->first_minor),
1<<g->minor_shift, ide_fops,
g->part[0].nr_sects);
return 0; return 0;
failed: failed:
return 1; return 1;
......
...@@ -1629,11 +1629,17 @@ static void idedisk_setup (ide_drive_t *drive) ...@@ -1629,11 +1629,17 @@ static void idedisk_setup (ide_drive_t *drive)
static int idedisk_cleanup (ide_drive_t *drive) static int idedisk_cleanup (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (do_idedisk_flushcache(drive)) if (do_idedisk_flushcache(drive))
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
drive->name); drive->name);
return ide_unregister_subdriver(drive); if (ide_unregister_subdriver(drive))
return 1;
del_gendisk(g);
return 0;
} }
static int idedisk_reinit(ide_drive_t *drive); static int idedisk_reinit(ide_drive_t *drive);
...@@ -1677,6 +1683,10 @@ MODULE_DESCRIPTION("ATA DISK Driver"); ...@@ -1677,6 +1683,10 @@ MODULE_DESCRIPTION("ATA DISK Driver");
static int idedisk_reinit(ide_drive_t *drive) static int idedisk_reinit(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
/* strstr("foo", "") is non-NULL */ /* strstr("foo", "") is non-NULL */
if (!strstr("ide-disk", drive->driver_req)) if (!strstr("ide-disk", drive->driver_req))
goto failed; goto failed;
...@@ -1694,11 +1704,20 @@ static int idedisk_reinit(ide_drive_t *drive) ...@@ -1694,11 +1704,20 @@ static int idedisk_reinit(ide_drive_t *drive)
if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
drive->name, drive->head); drive->name, drive->head);
(void) idedisk_cleanup(drive); if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (do_idedisk_flushcache(drive))
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
drive->name);
ide_unregister_subdriver(drive);
DRIVER(drive)->busy--; DRIVER(drive)->busy--;
goto failed; goto failed;
} }
DRIVER(drive)->busy--; DRIVER(drive)->busy--;
g->minor_shift = PARTN_BITS;
add_gendisk(g);
register_disk(g, mk_kdev(g->major,g->first_minor),
1<<g->minor_shift, ide_fops,
current_capacity(drive));
return 0; return 0;
failed: failed:
return 1; return 1;
......
...@@ -2122,11 +2122,15 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) ...@@ -2122,11 +2122,15 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
static int idefloppy_cleanup (ide_drive_t *drive) static int idefloppy_cleanup (ide_drive_t *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
if (ide_unregister_subdriver (drive)) if (ide_unregister_subdriver (drive))
return 1; return 1;
drive->driver_data = NULL; drive->driver_data = NULL;
kfree (floppy); kfree (floppy);
del_gendisk(g);
return 0; return 0;
} }
...@@ -2187,6 +2191,9 @@ static ide_driver_t idefloppy_driver = { ...@@ -2187,6 +2191,9 @@ static ide_driver_t idefloppy_driver = {
static int idefloppy_reinit (ide_drive_t *drive) static int idefloppy_reinit (ide_drive_t *drive)
{ {
idefloppy_floppy_t *floppy; idefloppy_floppy_t *floppy;
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
if (!strstr("ide-floppy", drive->driver_req)) if (!strstr("ide-floppy", drive->driver_req))
goto failed; goto failed;
if (!drive->present) if (!drive->present)
...@@ -2213,6 +2220,11 @@ static int idefloppy_reinit (ide_drive_t *drive) ...@@ -2213,6 +2220,11 @@ static int idefloppy_reinit (ide_drive_t *drive)
DRIVER(drive)->busy++; DRIVER(drive)->busy++;
idefloppy_setup (drive, floppy); idefloppy_setup (drive, floppy);
DRIVER(drive)->busy--; DRIVER(drive)->busy--;
g->minor_shift = PARTN_BITS;
add_gendisk(g);
register_disk(g, mk_kdev(g->major,g->first_minor),
1<<g->minor_shift, ide_fops,
g->part[0].nr_sects);
return 0; return 0;
failed: failed:
return 1; return 1;
......
...@@ -864,7 +864,6 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -864,7 +864,6 @@ static void init_gendisk (ide_hwif_t *hwif)
gd[unit].nr_real = 1; gd[unit].nr_real = 1;
gd[unit].fops = ide_fops; gd[unit].fops = ide_fops;
hwif->gd[unit] = gd + unit; hwif->gd[unit] = gd + unit;
add_gendisk(gd + unit);
} }
for (unit = 0; unit < units; ++unit) { for (unit = 0; unit < units; ++unit) {
......
...@@ -443,30 +443,6 @@ unsigned long current_capacity (ide_drive_t *drive) ...@@ -443,30 +443,6 @@ unsigned long current_capacity (ide_drive_t *drive)
} }
extern struct block_device_operations ide_fops[]; extern struct block_device_operations ide_fops[];
/*
* ide_geninit() is called exactly *once* for each interface.
*/
void ide_geninit (ide_hwif_t *hwif)
{
unsigned int unit;
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
struct gendisk *gd = hwif->gd[unit];
if (!drive->present)
continue;
if (drive->media!=ide_disk && drive->media!=ide_floppy
&& drive->media != ide_cdrom)
continue;
register_disk(gd,mk_kdev(hwif->major,unit<<PARTN_BITS),
#ifdef CONFIG_BLK_DEV_ISAPNP
(drive->forced_geom && drive->noprobe) ? 1 :
#endif /* CONFIG_BLK_DEV_ISAPNP */
1<<PARTN_BITS, ide_fops,
current_capacity(drive));
}
}
static ide_startstop_t do_reset1 (ide_drive_t *, int); /* needed below */ static ide_startstop_t do_reset1 (ide_drive_t *, int); /* needed below */
...@@ -1775,9 +1751,7 @@ void ide_revalidate_drive (ide_drive_t *drive) ...@@ -1775,9 +1751,7 @@ void ide_revalidate_drive (ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives; int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit]; struct gendisk *g = hwif->gd[unit];
int minor = (drive->select.b.unit << g->minor_shift); g->part[0].nr_sects = current_capacity(drive);
grok_partitions(mk_kdev(g->major, minor), current_capacity(drive));
} }
/* /*
...@@ -1788,53 +1762,14 @@ void ide_revalidate_drive (ide_drive_t *drive) ...@@ -1788,53 +1762,14 @@ void ide_revalidate_drive (ide_drive_t *drive)
* usage == 1 (we need an open channel to use an ioctl :-), so this * usage == 1 (we need an open channel to use an ioctl :-), so this
* is our limit. * is our limit.
*/ */
int ide_revalidate_disk (kdev_t i_rdev) static int ide_revalidate_disk (kdev_t i_rdev)
{ {
ide_drive_t *drive; ide_drive_t *drive;
ide_hwgroup_t *hwgroup;
unsigned long flags;
int res;
if ((drive = get_info_ptr(i_rdev)) == NULL) if ((drive = get_info_ptr(i_rdev)) == NULL)
return -ENODEV; return -ENODEV;
hwgroup = HWGROUP(drive); if (DRIVER(drive)->revalidate)
spin_lock_irqsave(&ide_lock, flags);
if (drive->busy || (drive->usage > 1)) {
spin_unlock_irqrestore(&ide_lock, flags);
return -EBUSY;
};
drive->busy = 1;
MOD_INC_USE_COUNT;
spin_unlock_irqrestore(&ide_lock, flags);
res = wipe_partitions(i_rdev);
if (!res && DRIVER(drive)->revalidate)
DRIVER(drive)->revalidate(drive); DRIVER(drive)->revalidate(drive);
return 0;
drive->busy = 0;
wake_up(&drive->wqueue);
MOD_DEC_USE_COUNT;
return res;
}
static void revalidate_drives (void)
{
ide_hwif_t *hwif;
ide_drive_t *drive;
int index, unit;
for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index];
for (unit = 0; unit < MAX_DRIVES; ++unit) {
drive = &ide_hwifs[index].drives[unit];
if (drive->revalidate) {
drive->revalidate = 0;
if (!initializing)
(void) ide_revalidate_disk(mk_kdev(hwif->major, unit<<PARTN_BITS));
}
}
}
} }
static void ide_probe_module (void) static void ide_probe_module (void)
...@@ -1846,7 +1781,6 @@ static void ide_probe_module (void) ...@@ -1846,7 +1781,6 @@ static void ide_probe_module (void)
} else { } else {
(void) ide_probe->init(); (void) ide_probe->init();
} }
revalidate_drives();
} }
static int ide_open (struct inode * inode, struct file * filp) static int ide_open (struct inode * inode, struct file * filp)
...@@ -1954,10 +1888,8 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver) ...@@ -1954,10 +1888,8 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
spin_unlock(&drives_lock); spin_unlock(&drives_lock);
drive->driver_req[0] = 0; drive->driver_req[0] = 0;
ata_attach(drive); ata_attach(drive);
revalidate_drives();
} else { } else {
drive->driver_req[0] = 0; drive->driver_req[0] = 0;
revalidate_drives();
} }
if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver)) if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver))
return 0; return 0;
...@@ -2129,8 +2061,6 @@ void ide_unregister (unsigned int index) ...@@ -2129,8 +2061,6 @@ void ide_unregister (unsigned int index)
gd = hwif->gd[0]; gd = hwif->gd[0];
if (gd) { if (gd) {
int i; int i;
for (i = 0; i < MAX_DRIVES; i++)
del_gendisk(gd + i);
kfree(gd->part); kfree(gd->part);
if (gd->de_arr) if (gd->de_arr)
kfree (gd->de_arr); kfree (gd->de_arr);
...@@ -2617,10 +2547,6 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2617,10 +2547,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
return 0; return 0;
} }
case BLKRRPART: /* Re-read partition tables */
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
return ide_revalidate_disk(inode->i_rdev);
case HDIO_OBSOLETE_IDENTITY: case HDIO_OBSOLETE_IDENTITY:
case HDIO_GET_IDENTITY: case HDIO_GET_IDENTITY:
if (minor(inode->i_rdev) & PARTN_MASK) if (minor(inode->i_rdev) & PARTN_MASK)
...@@ -2722,7 +2648,8 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2722,7 +2648,8 @@ static int ide_ioctl (struct inode *inode, struct file *file,
* } * }
* HWIF(drive)->multiproc(drive); * HWIF(drive)->multiproc(drive);
*/ */
return ide_revalidate_disk(inode->i_rdev); return file->f_op->ioctl(inode, file,
BLKRRPART, 0);
} }
return 0; return 0;
} }
...@@ -3523,7 +3450,6 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio ...@@ -3523,7 +3450,6 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap);
drive->nice1 = 1; drive->nice1 = 1;
} }
drive->revalidate = 1;
drive->suspend_reset = 0; drive->suspend_reset = 0;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
...@@ -3576,7 +3502,6 @@ int ide_register_driver(ide_driver_t *driver) ...@@ -3576,7 +3502,6 @@ int ide_register_driver(ide_driver_t *driver)
list_del_init(&drive->list); list_del_init(&drive->list);
ata_attach(drive); ata_attach(drive);
} }
revalidate_drives();
return 0; return 0;
} }
...@@ -3650,7 +3575,6 @@ EXPORT_SYMBOL(ide_do_drive_cmd); ...@@ -3650,7 +3575,6 @@ EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ide_end_drive_cmd); EXPORT_SYMBOL(ide_end_drive_cmd);
EXPORT_SYMBOL(ide_end_request); EXPORT_SYMBOL(ide_end_request);
EXPORT_SYMBOL(ide_revalidate_drive); EXPORT_SYMBOL(ide_revalidate_drive);
EXPORT_SYMBOL(ide_revalidate_disk);
EXPORT_SYMBOL(ide_cmd); EXPORT_SYMBOL(ide_cmd);
EXPORT_SYMBOL(ide_wait_cmd); EXPORT_SYMBOL(ide_wait_cmd);
EXPORT_SYMBOL(ide_wait_cmd_task); EXPORT_SYMBOL(ide_wait_cmd_task);
...@@ -3731,8 +3655,6 @@ static struct notifier_block ide_notifier = { ...@@ -3731,8 +3655,6 @@ static struct notifier_block ide_notifier = {
int __init ide_init (void) int __init ide_init (void)
{ {
static char banner_printed; static char banner_printed;
int i;
if (!banner_printed) { if (!banner_printed) {
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL); ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL);
...@@ -3746,12 +3668,6 @@ int __init ide_init (void) ...@@ -3746,12 +3668,6 @@ int __init ide_init (void)
ide_init_builtin_drivers(); ide_init_builtin_drivers();
initializing = 0; initializing = 0;
for (i = 0; i < MAX_HWIFS; ++i) {
ide_hwif_t *hwif = &ide_hwifs[i];
if (hwif->present)
ide_geninit(hwif);
}
register_reboot_notifier(&ide_notifier); register_reboot_notifier(&ide_notifier);
return 0; return 0;
} }
......
...@@ -470,7 +470,6 @@ typedef struct ide_drive_s { ...@@ -470,7 +470,6 @@ typedef struct ide_drive_s {
unsigned no_unmask : 1; /* disallow setting unmask bit */ unsigned no_unmask : 1; /* disallow setting unmask bit */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
unsigned nobios : 1; /* flag: do not probe bios for drive */ unsigned nobios : 1; /* flag: do not probe bios for drive */
unsigned revalidate : 1; /* request revalidation */
unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */ unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */
unsigned nice0 : 1; /* flag: give obvious excess bandwidth */ unsigned nice0 : 1; /* flag: give obvious excess bandwidth */
unsigned nice2 : 1; /* flag: give a share in our own bandwidth */ unsigned nice2 : 1; /* flag: give a share in our own bandwidth */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment