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)
static
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;
cdrom_read_toc(drive, &sense);
g->minor_shift = 0;
grok_partitions(mk_kdev(g->major, drive->select.b.unit), current_capacity(drive));
}
static
......@@ -3031,6 +3025,9 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
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))
return 1;
......@@ -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);
kfree(info);
drive->driver_data = NULL;
del_gendisk(g);
return 0;
}
......@@ -3094,6 +3092,10 @@ MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
static int ide_cdrom_reinit (ide_drive_t *drive)
{
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))
goto failed;
......@@ -3126,12 +3128,29 @@ static int ide_cdrom_reinit (ide_drive_t *drive)
drive->driver_data = info;
DRIVER(drive)->busy++;
if (ide_cdrom_setup (drive)) {
struct cdrom_device_info *devinfo = &info->devinfo;
DRIVER(drive)->busy--;
if (ide_cdrom_cleanup (drive))
printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
ide_unregister_subdriver (drive);
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;
}
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;
failed:
return 1;
......
......@@ -1629,11 +1629,17 @@ static void idedisk_setup (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 (do_idedisk_flushcache(drive))
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
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);
......@@ -1677,6 +1683,10 @@ MODULE_DESCRIPTION("ATA DISK Driver");
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 */
if (!strstr("ide-disk", drive->driver_req))
goto failed;
......@@ -1694,11 +1704,20 @@ static int idedisk_reinit(ide_drive_t *drive)
if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
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--;
goto failed;
}
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;
failed:
return 1;
......
......@@ -2122,11 +2122,15 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
static int idefloppy_cleanup (ide_drive_t *drive)
{
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))
return 1;
drive->driver_data = NULL;
kfree (floppy);
del_gendisk(g);
return 0;
}
......@@ -2187,6 +2191,9 @@ static ide_driver_t idefloppy_driver = {
static int idefloppy_reinit (ide_drive_t *drive)
{
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))
goto failed;
if (!drive->present)
......@@ -2213,6 +2220,11 @@ static int idefloppy_reinit (ide_drive_t *drive)
DRIVER(drive)->busy++;
idefloppy_setup (drive, floppy);
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;
failed:
return 1;
......
......@@ -864,7 +864,6 @@ static void init_gendisk (ide_hwif_t *hwif)
gd[unit].nr_real = 1;
gd[unit].fops = ide_fops;
hwif->gd[unit] = gd + unit;
add_gendisk(gd + unit);
}
for (unit = 0; unit < units; ++unit) {
......
......@@ -443,30 +443,6 @@ unsigned long current_capacity (ide_drive_t *drive)
}
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 */
......@@ -1775,9 +1751,7 @@ void ide_revalidate_drive (ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive);
int unit = drive - hwif->drives;
struct gendisk *g = hwif->gd[unit];
int minor = (drive->select.b.unit << g->minor_shift);
grok_partitions(mk_kdev(g->major, minor), current_capacity(drive));
g->part[0].nr_sects = current_capacity(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
* 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_hwgroup_t *hwgroup;
unsigned long flags;
int res;
if ((drive = get_info_ptr(i_rdev)) == NULL)
return -ENODEV;
hwgroup = HWGROUP(drive);
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)
if (DRIVER(drive)->revalidate)
DRIVER(drive)->revalidate(drive);
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));
}
}
}
return 0;
}
static void ide_probe_module (void)
......@@ -1846,7 +1781,6 @@ static void ide_probe_module (void)
} else {
(void) ide_probe->init();
}
revalidate_drives();
}
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)
spin_unlock(&drives_lock);
drive->driver_req[0] = 0;
ata_attach(drive);
revalidate_drives();
} else {
drive->driver_req[0] = 0;
revalidate_drives();
}
if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver))
return 0;
......@@ -2129,8 +2061,6 @@ void ide_unregister (unsigned int index)
gd = hwif->gd[0];
if (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);
......@@ -2617,10 +2547,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
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_GET_IDENTITY:
if (minor(inode->i_rdev) & PARTN_MASK)
......@@ -2722,7 +2648,8 @@ static int ide_ioctl (struct inode *inode, struct file *file,
* }
* HWIF(drive)->multiproc(drive);
*/
return ide_revalidate_disk(inode->i_rdev);
return file->f_op->ioctl(inode, file,
BLKRRPART, 0);
}
return 0;
}
......@@ -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->nice1 = 1;
}
drive->revalidate = 1;
drive->suspend_reset = 0;
#ifdef CONFIG_PROC_FS
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
......@@ -3576,7 +3502,6 @@ int ide_register_driver(ide_driver_t *driver)
list_del_init(&drive->list);
ata_attach(drive);
}
revalidate_drives();
return 0;
}
......@@ -3650,7 +3575,6 @@ EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ide_end_drive_cmd);
EXPORT_SYMBOL(ide_end_request);
EXPORT_SYMBOL(ide_revalidate_drive);
EXPORT_SYMBOL(ide_revalidate_disk);
EXPORT_SYMBOL(ide_cmd);
EXPORT_SYMBOL(ide_wait_cmd);
EXPORT_SYMBOL(ide_wait_cmd_task);
......@@ -3731,8 +3655,6 @@ static struct notifier_block ide_notifier = {
int __init ide_init (void)
{
static char banner_printed;
int i;
if (!banner_printed) {
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL);
......@@ -3746,12 +3668,6 @@ int __init ide_init (void)
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);
}
register_reboot_notifier(&ide_notifier);
return 0;
}
......
......@@ -470,7 +470,6 @@ typedef struct ide_drive_s {
unsigned no_unmask : 1; /* disallow setting unmask bit */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
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 nice0 : 1; /* flag: give obvious excess 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