aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@trik.(none)>2005-04-02 19:38:19 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@trik.(none)>2005-04-02 19:38:19 +0200
commit4de9793a90e10d132275915066194a6bc20895bb (patch)
tree4109b8860d417a6bc67b2cb82009ceca0a90f71f
parent2f5930e15a6456602366b04b728c8492b07830bc (diff)
downloadhistory-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.c61
-rw-r--r--drivers/ide/ide-tape.c3
-rw-r--r--drivers/scsi/ide-scsi.c4
-rw-r--r--include/linux/ide.h3
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 *));