diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@trik.(none)> | 2005-04-02 19:38:19 +0200 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@trik.(none)> | 2005-04-02 19:38:19 +0200 |
commit | 4de9793a90e10d132275915066194a6bc20895bb (patch) | |
tree | 4109b8860d417a6bc67b2cb82009ceca0a90f71f | |
parent | 2f5930e15a6456602366b04b728c8492b07830bc (diff) | |
download | history-4de9793a90e10d132275915066194a6bc20895bb.tar.gz |
[ide] add ide_{un}register_region()
Add ide_{un}register_region() and fix ide-{tape,scsi}.c to register
block device number ranges. In ata_probe() only probe for modules.
Behavior is unchanged because:
* if driver is already loaded and attached to drive ata_probe()
is not called et all
* if driver is loaded by ata_probe() it will register new number range
for a drive and this range will be found by kobj_lookup()
If this is not clear please read http://lwn.net/Articles/25711/
and see drivers/base/map.c.
This patch makes it possible to move drive->disk allocation from
ide-probe.c to device drivers.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/ide-probe.c | 61 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 3 | ||||
-rw-r--r-- | drivers/scsi/ide-scsi.c | 4 | ||||
-rw-r--r-- | include/linux/ide.h | 3 |
4 files changed, 54 insertions, 17 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 2b8c8f86edbd00..4f25501bc758b8 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1214,8 +1214,6 @@ static int ata_lock(dev_t dev, void *data) return 0; } -extern ide_driver_t idedefault_driver; - static struct kobject *ata_probe(dev_t dev, int *part, void *data) { ide_hwif_t *hwif = data; @@ -1223,24 +1221,53 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) ide_drive_t *drive = &hwif->drives[unit]; if (!drive->present) return NULL; - if (drive->driver == &idedefault_driver) { - if (drive->media == ide_disk) - (void) request_module("ide-disk"); - if (drive->scsi) - (void) request_module("ide-scsi"); - if (drive->media == ide_cdrom || drive->media == ide_optical) - (void) request_module("ide-cd"); - if (drive->media == ide_tape) - (void) request_module("ide-tape"); - if (drive->media == ide_floppy) - (void) request_module("ide-floppy"); - } - if (drive->driver == &idedefault_driver) - return NULL; + + if (drive->media == ide_disk) + request_module("ide-disk"); + if (drive->scsi) + request_module("ide-scsi"); + if (drive->media == ide_cdrom || drive->media == ide_optical) + request_module("ide-cd"); + if (drive->media == ide_tape) + request_module("ide-tape"); + if (drive->media == ide_floppy) + request_module("ide-floppy"); + + return NULL; +} + +static struct kobject *exact_match(dev_t dev, int *part, void *data) +{ + struct gendisk *p = data; *part &= (1 << PARTN_BITS) - 1; - return get_disk(drive->disk); + return &p->kobj; } +static int exact_lock(dev_t dev, void *data) +{ + struct gendisk *p = data; + + if (!get_disk(p)) + return -1; + return 0; +} + +void ide_register_region(struct gendisk *disk) +{ + blk_register_region(MKDEV(disk->major, disk->first_minor), + disk->minors, NULL, exact_match, exact_lock, disk); +} + +EXPORT_SYMBOL_GPL(ide_register_region); + +void ide_unregister_region(struct gendisk *disk) +{ + blk_unregister_region(MKDEV(disk->major, disk->first_minor), + disk->minors); +} + +EXPORT_SYMBOL_GPL(ide_unregister_region); + static int alloc_disks(ide_hwif_t *hwif) { unsigned int unit; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8802679c3eff90..41513c4b27fe7f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -4687,6 +4687,8 @@ static int idetape_cleanup (ide_drive_t *drive) DRIVER(drive)->busy = 0; (void) ide_unregister_subdriver(drive); + ide_unregister_region(drive->disk); + ide_tape_put(tape); return 0; @@ -4878,6 +4880,7 @@ static int idetape_attach (ide_drive_t *drive) g->number = devfs_register_tape(drive->devfs_name); g->fops = &idetape_block_ops; g->private_data = tape; + ide_register_region(g); return 0; failed: diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 805cccd042b671..fc7e999ec46310 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -723,6 +723,8 @@ static int idescsi_cleanup (ide_drive_t *drive) if (ide_unregister_subdriver(drive)) return 1; + ide_unregister_region(g); + drive->driver_data = NULL; g->private_data = NULL; g->fops = ide_fops; @@ -1120,12 +1122,14 @@ static int idescsi_attach(ide_drive_t *drive) idescsi_setup (drive, idescsi); g->fops = &idescsi_ops; g->private_data = idescsi; + ide_register_region(g); err = scsi_add_host(host, &drive->gendev); if (!err) { scsi_scan_host(host); return 0; } /* fall through on error */ + ide_unregister_region(g); ide_unregister_subdriver(drive); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 58d91a9d533256..329dcc754d868a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1442,6 +1442,9 @@ extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); +void ide_register_region(struct gendisk *); +void ide_unregister_region(struct gendisk *); + void ide_undecoded_slave(ide_hwif_t *); int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *)); |