mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-12 08:09:56 +00:00
[PATCH] convert IDE device drivers to driver-model
* add ide_bus_match() and export ide_bus_type * split ide_remove_driver_from_hwgroup() out of ide_unregister() * move device cleanup from ide_unregister() to drive_release_dev() * convert ide_driver_t->name to driver->name * convert ide_driver_t->{attach,cleanup} to driver->{probe,remove} * remove ide_driver_t->busy as ide_bus_type->subsys.rwsem protects against concurrent ->{probe,remove} calls * make ide_{un}register_driver() void as it cannot fail now * use driver_{un}register() directly, remove ide_{un}register_driver() * use device_register() instead of ata_attach(), remove ata_attach() * add proc_print_driver() and ide_drivers_show(), remove ide_drivers_op * fix ide_replace_subdriver() and move it to ide-proc.c * remove ide_driver_t->drives, ide_drives and drives_lock * remove ide_driver_t->drivers, drivers and drivers_lock * remove ide_drive_t->driver and DRIVER() macro Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
This commit is contained in:
parent
bef9c55884
commit
8604affde9
@ -3255,16 +3255,12 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
|
|||||||
return capacity * sectors_per_frame;
|
return capacity * sectors_per_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static int ide_cd_remove(struct device *dev)
|
||||||
int ide_cdrom_cleanup(ide_drive_t *drive)
|
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
struct cdrom_info *info = drive->driver_data;
|
struct cdrom_info *info = drive->driver_data;
|
||||||
|
|
||||||
if (ide_unregister_subdriver(drive)) {
|
ide_unregister_subdriver(drive, info->driver);
|
||||||
printk(KERN_ERR "%s: %s: failed to ide_unregister_subdriver\n",
|
|
||||||
__FUNCTION__, drive->name);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
del_gendisk(info->disk);
|
del_gendisk(info->disk);
|
||||||
|
|
||||||
@ -3297,7 +3293,7 @@ static void ide_cd_release(struct kref *kref)
|
|||||||
kfree(info);
|
kfree(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ide_cdrom_attach (ide_drive_t *drive);
|
static int ide_cd_probe(struct device *);
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
static int proc_idecd_read_capacity
|
static int proc_idecd_read_capacity
|
||||||
@ -3320,19 +3316,20 @@ static ide_proc_entry_t idecd_proc[] = {
|
|||||||
|
|
||||||
static ide_driver_t ide_cdrom_driver = {
|
static ide_driver_t ide_cdrom_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "ide-cdrom",
|
.gen_driver = {
|
||||||
|
.name = "ide-cdrom",
|
||||||
|
.bus = &ide_bus_type,
|
||||||
|
.probe = ide_cd_probe,
|
||||||
|
.remove = ide_cd_remove,
|
||||||
|
},
|
||||||
.version = IDECD_VERSION,
|
.version = IDECD_VERSION,
|
||||||
.media = ide_cdrom,
|
.media = ide_cdrom,
|
||||||
.busy = 0,
|
|
||||||
.supports_dsc_overlap = 1,
|
.supports_dsc_overlap = 1,
|
||||||
.cleanup = ide_cdrom_cleanup,
|
|
||||||
.do_request = ide_do_rw_cdrom,
|
.do_request = ide_do_rw_cdrom,
|
||||||
.end_request = ide_end_request,
|
.end_request = ide_end_request,
|
||||||
.error = __ide_error,
|
.error = __ide_error,
|
||||||
.abort = __ide_abort,
|
.abort = __ide_abort,
|
||||||
.proc = idecd_proc,
|
.proc = idecd_proc,
|
||||||
.attach = ide_cdrom_attach,
|
|
||||||
.drives = LIST_HEAD_INIT(ide_cdrom_driver.drives),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idecd_open(struct inode * inode, struct file * file)
|
static int idecd_open(struct inode * inode, struct file * file)
|
||||||
@ -3418,8 +3415,9 @@ static char *ignore = NULL;
|
|||||||
module_param(ignore, charp, 0400);
|
module_param(ignore, charp, 0400);
|
||||||
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
|
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
|
||||||
|
|
||||||
static int ide_cdrom_attach (ide_drive_t *drive)
|
static int ide_cd_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
struct cdrom_info *info;
|
struct cdrom_info *info;
|
||||||
struct gendisk *g;
|
struct gendisk *g;
|
||||||
struct request_sense sense;
|
struct request_sense sense;
|
||||||
@ -3453,11 +3451,8 @@ static int ide_cdrom_attach (ide_drive_t *drive)
|
|||||||
|
|
||||||
ide_init_disk(g, drive);
|
ide_init_disk(g, drive);
|
||||||
|
|
||||||
if (ide_register_subdriver(drive, &ide_cdrom_driver)) {
|
ide_register_subdriver(drive, &ide_cdrom_driver);
|
||||||
printk(KERN_ERR "%s: Failed to register the driver with ide.c\n",
|
|
||||||
drive->name);
|
|
||||||
goto out_put_disk;
|
|
||||||
}
|
|
||||||
memset(info, 0, sizeof (struct cdrom_info));
|
memset(info, 0, sizeof (struct cdrom_info));
|
||||||
|
|
||||||
kref_init(&info->kref);
|
kref_init(&info->kref);
|
||||||
@ -3470,7 +3465,6 @@ static int ide_cdrom_attach (ide_drive_t *drive)
|
|||||||
|
|
||||||
drive->driver_data = info;
|
drive->driver_data = info;
|
||||||
|
|
||||||
DRIVER(drive)->busy++;
|
|
||||||
g->minors = 1;
|
g->minors = 1;
|
||||||
snprintf(g->devfs_name, sizeof(g->devfs_name),
|
snprintf(g->devfs_name, sizeof(g->devfs_name),
|
||||||
"%s/cd", drive->devfs_name);
|
"%s/cd", drive->devfs_name);
|
||||||
@ -3478,8 +3472,7 @@ static int ide_cdrom_attach (ide_drive_t *drive)
|
|||||||
g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
|
g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
|
||||||
if (ide_cdrom_setup(drive)) {
|
if (ide_cdrom_setup(drive)) {
|
||||||
struct cdrom_device_info *devinfo = &info->devinfo;
|
struct cdrom_device_info *devinfo = &info->devinfo;
|
||||||
DRIVER(drive)->busy--;
|
ide_unregister_subdriver(drive, &ide_cdrom_driver);
|
||||||
ide_unregister_subdriver(drive);
|
|
||||||
if (info->buffer != NULL)
|
if (info->buffer != NULL)
|
||||||
kfree(info->buffer);
|
kfree(info->buffer);
|
||||||
if (info->toc != NULL)
|
if (info->toc != NULL)
|
||||||
@ -3492,7 +3485,6 @@ static int ide_cdrom_attach (ide_drive_t *drive)
|
|||||||
drive->driver_data = NULL;
|
drive->driver_data = NULL;
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
DRIVER(drive)->busy--;
|
|
||||||
|
|
||||||
cdrom_read_toc(drive, &sense);
|
cdrom_read_toc(drive, &sense);
|
||||||
g->fops = &idecd_ops;
|
g->fops = &idecd_ops;
|
||||||
@ -3500,23 +3492,20 @@ static int ide_cdrom_attach (ide_drive_t *drive)
|
|||||||
add_disk(g);
|
add_disk(g);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_put_disk:
|
|
||||||
put_disk(g);
|
|
||||||
out_free_cd:
|
out_free_cd:
|
||||||
kfree(info);
|
kfree(info);
|
||||||
failed:
|
failed:
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit ide_cdrom_exit(void)
|
static void __exit ide_cdrom_exit(void)
|
||||||
{
|
{
|
||||||
ide_unregister_driver(&ide_cdrom_driver);
|
driver_unregister(&ide_cdrom_driver.gen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ide_cdrom_init(void)
|
static int ide_cdrom_init(void)
|
||||||
{
|
{
|
||||||
ide_register_driver(&ide_cdrom_driver);
|
return driver_register(&ide_cdrom_driver.gen_driver);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(ide_cdrom_init);
|
module_init(ide_cdrom_init);
|
||||||
|
@ -1024,14 +1024,16 @@ static void ide_cacheflush_p(ide_drive_t *drive)
|
|||||||
printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
|
printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idedisk_cleanup (ide_drive_t *drive)
|
static int ide_disk_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
struct ide_disk_obj *idkp = drive->driver_data;
|
struct ide_disk_obj *idkp = drive->driver_data;
|
||||||
struct gendisk *g = idkp->disk;
|
struct gendisk *g = idkp->disk;
|
||||||
|
|
||||||
ide_cacheflush_p(drive);
|
ide_cacheflush_p(drive);
|
||||||
if (ide_unregister_subdriver(drive))
|
|
||||||
return 1;
|
ide_unregister_subdriver(drive, idkp->driver);
|
||||||
|
|
||||||
del_gendisk(g);
|
del_gendisk(g);
|
||||||
|
|
||||||
ide_disk_put(idkp);
|
ide_disk_put(idkp);
|
||||||
@ -1052,7 +1054,7 @@ static void ide_disk_release(struct kref *kref)
|
|||||||
kfree(idkp);
|
kfree(idkp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idedisk_attach(ide_drive_t *drive);
|
static int ide_disk_probe(struct device *dev);
|
||||||
|
|
||||||
static void ide_device_shutdown(struct device *dev)
|
static void ide_device_shutdown(struct device *dev)
|
||||||
{
|
{
|
||||||
@ -1082,27 +1084,23 @@ static void ide_device_shutdown(struct device *dev)
|
|||||||
dev->bus->suspend(dev, PMSG_SUSPEND);
|
dev->bus->suspend(dev, PMSG_SUSPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* IDE subdriver functions, registered with ide.c
|
|
||||||
*/
|
|
||||||
static ide_driver_t idedisk_driver = {
|
static ide_driver_t idedisk_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.gen_driver = {
|
.gen_driver = {
|
||||||
|
.name = "ide-disk",
|
||||||
|
.bus = &ide_bus_type,
|
||||||
|
.probe = ide_disk_probe,
|
||||||
|
.remove = ide_disk_remove,
|
||||||
.shutdown = ide_device_shutdown,
|
.shutdown = ide_device_shutdown,
|
||||||
},
|
},
|
||||||
.name = "ide-disk",
|
|
||||||
.version = IDEDISK_VERSION,
|
.version = IDEDISK_VERSION,
|
||||||
.media = ide_disk,
|
.media = ide_disk,
|
||||||
.busy = 0,
|
|
||||||
.supports_dsc_overlap = 0,
|
.supports_dsc_overlap = 0,
|
||||||
.cleanup = idedisk_cleanup,
|
|
||||||
.do_request = ide_do_rw_disk,
|
.do_request = ide_do_rw_disk,
|
||||||
.end_request = ide_end_request,
|
.end_request = ide_end_request,
|
||||||
.error = __ide_error,
|
.error = __ide_error,
|
||||||
.abort = __ide_abort,
|
.abort = __ide_abort,
|
||||||
.proc = idedisk_proc,
|
.proc = idedisk_proc,
|
||||||
.attach = idedisk_attach,
|
|
||||||
.drives = LIST_HEAD_INIT(idedisk_driver.drives),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idedisk_open(struct inode *inode, struct file *filp)
|
static int idedisk_open(struct inode *inode, struct file *filp)
|
||||||
@ -1199,8 +1197,9 @@ static struct block_device_operations idedisk_ops = {
|
|||||||
|
|
||||||
MODULE_DESCRIPTION("ATA DISK Driver");
|
MODULE_DESCRIPTION("ATA DISK Driver");
|
||||||
|
|
||||||
static int idedisk_attach(ide_drive_t *drive)
|
static int ide_disk_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
struct ide_disk_obj *idkp;
|
struct ide_disk_obj *idkp;
|
||||||
struct gendisk *g;
|
struct gendisk *g;
|
||||||
|
|
||||||
@ -1222,10 +1221,7 @@ static int idedisk_attach(ide_drive_t *drive)
|
|||||||
|
|
||||||
ide_init_disk(g, drive);
|
ide_init_disk(g, drive);
|
||||||
|
|
||||||
if (ide_register_subdriver(drive, &idedisk_driver)) {
|
ide_register_subdriver(drive, &idedisk_driver);
|
||||||
printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
|
|
||||||
goto out_put_disk;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(idkp, 0, sizeof(*idkp));
|
memset(idkp, 0, sizeof(*idkp));
|
||||||
|
|
||||||
@ -1239,7 +1235,6 @@ static int idedisk_attach(ide_drive_t *drive)
|
|||||||
|
|
||||||
drive->driver_data = idkp;
|
drive->driver_data = idkp;
|
||||||
|
|
||||||
DRIVER(drive)->busy++;
|
|
||||||
idedisk_setup(drive);
|
idedisk_setup(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",
|
||||||
@ -1247,7 +1242,7 @@ static int idedisk_attach(ide_drive_t *drive)
|
|||||||
drive->attach = 0;
|
drive->attach = 0;
|
||||||
} else
|
} else
|
||||||
drive->attach = 1;
|
drive->attach = 1;
|
||||||
DRIVER(drive)->busy--;
|
|
||||||
g->minors = 1 << PARTN_BITS;
|
g->minors = 1 << PARTN_BITS;
|
||||||
strcpy(g->devfs_name, drive->devfs_name);
|
strcpy(g->devfs_name, drive->devfs_name);
|
||||||
g->driverfs_dev = &drive->gendev;
|
g->driverfs_dev = &drive->gendev;
|
||||||
@ -1257,22 +1252,20 @@ static int idedisk_attach(ide_drive_t *drive)
|
|||||||
add_disk(g);
|
add_disk(g);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_put_disk:
|
|
||||||
put_disk(g);
|
|
||||||
out_free_idkp:
|
out_free_idkp:
|
||||||
kfree(idkp);
|
kfree(idkp);
|
||||||
failed:
|
failed:
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit idedisk_exit (void)
|
static void __exit idedisk_exit (void)
|
||||||
{
|
{
|
||||||
ide_unregister_driver(&idedisk_driver);
|
driver_unregister(&idedisk_driver.gen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idedisk_init (void)
|
static int idedisk_init (void)
|
||||||
{
|
{
|
||||||
return ide_register_driver(&idedisk_driver);
|
return driver_register(&idedisk_driver.gen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(idedisk_init);
|
module_init(idedisk_init);
|
||||||
|
@ -1865,13 +1865,13 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
|
|||||||
idefloppy_add_settings(drive);
|
idefloppy_add_settings(drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idefloppy_cleanup (ide_drive_t *drive)
|
static int ide_floppy_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
idefloppy_floppy_t *floppy = drive->driver_data;
|
idefloppy_floppy_t *floppy = drive->driver_data;
|
||||||
struct gendisk *g = floppy->disk;
|
struct gendisk *g = floppy->disk;
|
||||||
|
|
||||||
if (ide_unregister_subdriver(drive))
|
ide_unregister_subdriver(drive, floppy->driver);
|
||||||
return 1;
|
|
||||||
|
|
||||||
del_gendisk(g);
|
del_gendisk(g);
|
||||||
|
|
||||||
@ -1916,26 +1916,24 @@ static ide_proc_entry_t idefloppy_proc[] = {
|
|||||||
|
|
||||||
#endif /* CONFIG_PROC_FS */
|
#endif /* CONFIG_PROC_FS */
|
||||||
|
|
||||||
static int idefloppy_attach(ide_drive_t *drive);
|
static int ide_floppy_probe(struct device *);
|
||||||
|
|
||||||
/*
|
|
||||||
* IDE subdriver functions, registered with ide.c
|
|
||||||
*/
|
|
||||||
static ide_driver_t idefloppy_driver = {
|
static ide_driver_t idefloppy_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "ide-floppy",
|
.gen_driver = {
|
||||||
|
.name = "ide-floppy",
|
||||||
|
.bus = &ide_bus_type,
|
||||||
|
.probe = ide_floppy_probe,
|
||||||
|
.remove = ide_floppy_remove,
|
||||||
|
},
|
||||||
.version = IDEFLOPPY_VERSION,
|
.version = IDEFLOPPY_VERSION,
|
||||||
.media = ide_floppy,
|
.media = ide_floppy,
|
||||||
.busy = 0,
|
|
||||||
.supports_dsc_overlap = 0,
|
.supports_dsc_overlap = 0,
|
||||||
.cleanup = idefloppy_cleanup,
|
|
||||||
.do_request = idefloppy_do_request,
|
.do_request = idefloppy_do_request,
|
||||||
.end_request = idefloppy_do_end_request,
|
.end_request = idefloppy_do_end_request,
|
||||||
.error = __ide_error,
|
.error = __ide_error,
|
||||||
.abort = __ide_abort,
|
.abort = __ide_abort,
|
||||||
.proc = idefloppy_proc,
|
.proc = idefloppy_proc,
|
||||||
.attach = idefloppy_attach,
|
|
||||||
.drives = LIST_HEAD_INIT(idefloppy_driver.drives),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idefloppy_open(struct inode *inode, struct file *filp)
|
static int idefloppy_open(struct inode *inode, struct file *filp)
|
||||||
@ -2122,8 +2120,9 @@ static struct block_device_operations idefloppy_ops = {
|
|||||||
.revalidate_disk= idefloppy_revalidate_disk
|
.revalidate_disk= idefloppy_revalidate_disk
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idefloppy_attach (ide_drive_t *drive)
|
static int ide_floppy_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
idefloppy_floppy_t *floppy;
|
idefloppy_floppy_t *floppy;
|
||||||
struct gendisk *g;
|
struct gendisk *g;
|
||||||
|
|
||||||
@ -2152,10 +2151,7 @@ static int idefloppy_attach (ide_drive_t *drive)
|
|||||||
|
|
||||||
ide_init_disk(g, drive);
|
ide_init_disk(g, drive);
|
||||||
|
|
||||||
if (ide_register_subdriver(drive, &idefloppy_driver)) {
|
ide_register_subdriver(drive, &idefloppy_driver);
|
||||||
printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name);
|
|
||||||
goto out_put_disk;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(floppy, 0, sizeof(*floppy));
|
memset(floppy, 0, sizeof(*floppy));
|
||||||
|
|
||||||
@ -2169,9 +2165,8 @@ static int idefloppy_attach (ide_drive_t *drive)
|
|||||||
|
|
||||||
drive->driver_data = floppy;
|
drive->driver_data = floppy;
|
||||||
|
|
||||||
DRIVER(drive)->busy++;
|
|
||||||
idefloppy_setup (drive, floppy);
|
idefloppy_setup (drive, floppy);
|
||||||
DRIVER(drive)->busy--;
|
|
||||||
g->minors = 1 << PARTN_BITS;
|
g->minors = 1 << PARTN_BITS;
|
||||||
g->driverfs_dev = &drive->gendev;
|
g->driverfs_dev = &drive->gendev;
|
||||||
strcpy(g->devfs_name, drive->devfs_name);
|
strcpy(g->devfs_name, drive->devfs_name);
|
||||||
@ -2181,19 +2176,17 @@ static int idefloppy_attach (ide_drive_t *drive)
|
|||||||
add_disk(g);
|
add_disk(g);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_put_disk:
|
|
||||||
put_disk(g);
|
|
||||||
out_free_floppy:
|
out_free_floppy:
|
||||||
kfree(floppy);
|
kfree(floppy);
|
||||||
failed:
|
failed:
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
|
MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
|
||||||
|
|
||||||
static void __exit idefloppy_exit (void)
|
static void __exit idefloppy_exit (void)
|
||||||
{
|
{
|
||||||
ide_unregister_driver(&idefloppy_driver);
|
driver_unregister(&idefloppy_driver.gen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2202,8 +2195,7 @@ static void __exit idefloppy_exit (void)
|
|||||||
static int idefloppy_init (void)
|
static int idefloppy_init (void)
|
||||||
{
|
{
|
||||||
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
|
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
|
||||||
ide_register_driver(&idefloppy_driver);
|
return driver_register(&idefloppy_driver.gen_driver);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(idefloppy_init);
|
module_init(idefloppy_init);
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/ide.h>
|
#include <linux/ide.h>
|
||||||
|
#include <linux/devfs_fs_kernel.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/kmod.h>
|
#include <linux/kmod.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
@ -918,7 +919,7 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
|
|||||||
want them on default or a new "empty" class
|
want them on default or a new "empty" class
|
||||||
for hotplug reprobing ? */
|
for hotplug reprobing ? */
|
||||||
if (drive->present) {
|
if (drive->present) {
|
||||||
ata_attach(drive);
|
device_register(&drive->gendev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1279,10 +1280,51 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
|
|||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ide_init_disk);
|
EXPORT_SYMBOL_GPL(ide_init_disk);
|
||||||
|
|
||||||
|
static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
|
||||||
|
{
|
||||||
|
ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
|
||||||
|
|
||||||
|
if (drive == drive->next) {
|
||||||
|
/* special case: last drive from hwgroup. */
|
||||||
|
BUG_ON(hwgroup->drive != drive);
|
||||||
|
hwgroup->drive = NULL;
|
||||||
|
} else {
|
||||||
|
ide_drive_t *walk;
|
||||||
|
|
||||||
|
walk = hwgroup->drive;
|
||||||
|
while (walk->next != drive)
|
||||||
|
walk = walk->next;
|
||||||
|
walk->next = drive->next;
|
||||||
|
if (hwgroup->drive == drive) {
|
||||||
|
hwgroup->drive = drive->next;
|
||||||
|
hwgroup->hwif = hwgroup->drive->hwif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BUG_ON(hwgroup->drive == drive);
|
||||||
|
}
|
||||||
|
|
||||||
static void drive_release_dev (struct device *dev)
|
static void drive_release_dev (struct device *dev)
|
||||||
{
|
{
|
||||||
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
|
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
|
||||||
|
|
||||||
|
spin_lock_irq(&ide_lock);
|
||||||
|
if (drive->devfs_name[0] != '\0') {
|
||||||
|
devfs_remove(drive->devfs_name);
|
||||||
|
drive->devfs_name[0] = '\0';
|
||||||
|
}
|
||||||
|
ide_remove_drive_from_hwgroup(drive);
|
||||||
|
if (drive->id != NULL) {
|
||||||
|
kfree(drive->id);
|
||||||
|
drive->id = NULL;
|
||||||
|
}
|
||||||
|
drive->present = 0;
|
||||||
|
/* Messed up locking ... */
|
||||||
|
spin_unlock_irq(&ide_lock);
|
||||||
|
blk_cleanup_queue(drive->queue);
|
||||||
|
spin_lock_irq(&ide_lock);
|
||||||
|
drive->queue = NULL;
|
||||||
|
spin_unlock_irq(&ide_lock);
|
||||||
|
|
||||||
up(&drive->gendev_rel_sem);
|
up(&drive->gendev_rel_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1306,7 +1348,6 @@ static void init_gendisk (ide_hwif_t *hwif)
|
|||||||
drive->gendev.driver_data = drive;
|
drive->gendev.driver_data = drive;
|
||||||
drive->gendev.release = drive_release_dev;
|
drive->gendev.release = drive_release_dev;
|
||||||
if (drive->present) {
|
if (drive->present) {
|
||||||
device_register(&drive->gendev);
|
|
||||||
sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d",
|
sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d",
|
||||||
(hwif->channel && hwif->mate) ?
|
(hwif->channel && hwif->mate) ?
|
||||||
hwif->mate->index : hwif->index,
|
hwif->mate->index : hwif->index,
|
||||||
@ -1412,7 +1453,7 @@ int ideprobe_init (void)
|
|||||||
hwif->chipset = ide_generic;
|
hwif->chipset = ide_generic;
|
||||||
for (unit = 0; unit < MAX_DRIVES; ++unit)
|
for (unit = 0; unit < MAX_DRIVES; ++unit)
|
||||||
if (hwif->drives[unit].present)
|
if (hwif->drives[unit].present)
|
||||||
ata_attach(&hwif->drives[unit]);
|
device_register(&hwif->drives[unit].gendev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -307,17 +307,41 @@ static int proc_ide_read_driver
|
|||||||
(char *page, char **start, off_t off, int count, int *eof, void *data)
|
(char *page, char **start, off_t off, int count, int *eof, void *data)
|
||||||
{
|
{
|
||||||
ide_drive_t *drive = (ide_drive_t *) data;
|
ide_drive_t *drive = (ide_drive_t *) data;
|
||||||
ide_driver_t *driver = drive->driver;
|
struct device *dev = &drive->gendev;
|
||||||
|
ide_driver_t *ide_drv;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (driver) {
|
down_read(&dev->bus->subsys.rwsem);
|
||||||
|
if (dev->driver) {
|
||||||
|
ide_drv = container_of(dev->driver, ide_driver_t, gen_driver);
|
||||||
len = sprintf(page, "%s version %s\n",
|
len = sprintf(page, "%s version %s\n",
|
||||||
driver->name, driver->version);
|
dev->driver->name, ide_drv->version);
|
||||||
} else
|
} else
|
||||||
len = sprintf(page, "ide-default version 0.9.newide\n");
|
len = sprintf(page, "ide-default version 0.9.newide\n");
|
||||||
|
up_read(&dev->bus->subsys.rwsem);
|
||||||
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
|
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
|
||||||
|
{
|
||||||
|
struct device *dev = &drive->gendev;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
down_write(&dev->bus->subsys.rwsem);
|
||||||
|
device_release_driver(dev);
|
||||||
|
/* FIXME: device can still be in use by previous driver */
|
||||||
|
strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
|
||||||
|
device_attach(dev);
|
||||||
|
drive->driver_req[0] = 0;
|
||||||
|
if (dev->driver == NULL)
|
||||||
|
device_attach(dev);
|
||||||
|
if (dev->driver && !strcmp(dev->driver->name, driver))
|
||||||
|
ret = 0;
|
||||||
|
up_write(&dev->bus->subsys.rwsem);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int proc_ide_write_driver
|
static int proc_ide_write_driver
|
||||||
(struct file *file, const char __user *buffer, unsigned long count, void *data)
|
(struct file *file, const char __user *buffer, unsigned long count, void *data)
|
||||||
{
|
{
|
||||||
@ -488,16 +512,32 @@ void destroy_proc_ide_interface(ide_hwif_t *hwif)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct seq_operations ide_drivers_op;
|
static int proc_print_driver(struct device_driver *drv, void *data)
|
||||||
|
{
|
||||||
|
ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver);
|
||||||
|
struct seq_file *s = data;
|
||||||
|
|
||||||
|
seq_printf(s, "%s version %s\n", drv->name, ide_drv->version);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ide_drivers_show(struct seq_file *s, void *p)
|
||||||
|
{
|
||||||
|
bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ide_drivers_open(struct inode *inode, struct file *file)
|
static int ide_drivers_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
return seq_open(file, &ide_drivers_op);
|
return single_open(file, &ide_drivers_show, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file_operations ide_drivers_operations = {
|
static struct file_operations ide_drivers_operations = {
|
||||||
.open = ide_drivers_open,
|
.open = ide_drivers_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
.release = seq_release,
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
void proc_ide_create(void)
|
void proc_ide_create(void)
|
||||||
|
@ -4681,21 +4681,12 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
|
|||||||
idetape_add_settings(drive);
|
idetape_add_settings(drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idetape_cleanup (ide_drive_t *drive)
|
static int ide_tape_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
idetape_tape_t *tape = drive->driver_data;
|
idetape_tape_t *tape = drive->driver_data;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ide_lock, flags);
|
ide_unregister_subdriver(drive, tape->driver);
|
||||||
if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage ||
|
|
||||||
tape->first_stage != NULL || tape->merge_stage_size) {
|
|
||||||
spin_unlock_irqrestore(&ide_lock, flags);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ide_lock, flags);
|
|
||||||
DRIVER(drive)->busy = 0;
|
|
||||||
(void) ide_unregister_subdriver(drive);
|
|
||||||
|
|
||||||
ide_unregister_region(tape->disk);
|
ide_unregister_region(tape->disk);
|
||||||
|
|
||||||
@ -4710,6 +4701,8 @@ static void ide_tape_release(struct kref *kref)
|
|||||||
ide_drive_t *drive = tape->drive;
|
ide_drive_t *drive = tape->drive;
|
||||||
struct gendisk *g = tape->disk;
|
struct gendisk *g = tape->disk;
|
||||||
|
|
||||||
|
BUG_ON(tape->first_stage != NULL || tape->merge_stage_size);
|
||||||
|
|
||||||
drive->dsc_overlap = 0;
|
drive->dsc_overlap = 0;
|
||||||
drive->driver_data = NULL;
|
drive->driver_data = NULL;
|
||||||
devfs_remove("%s/mt", drive->devfs_name);
|
devfs_remove("%s/mt", drive->devfs_name);
|
||||||
@ -4747,26 +4740,24 @@ static ide_proc_entry_t idetape_proc[] = {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int idetape_attach(ide_drive_t *drive);
|
static int ide_tape_probe(struct device *);
|
||||||
|
|
||||||
/*
|
|
||||||
* IDE subdriver functions, registered with ide.c
|
|
||||||
*/
|
|
||||||
static ide_driver_t idetape_driver = {
|
static ide_driver_t idetape_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "ide-tape",
|
.gen_driver = {
|
||||||
|
.name = "ide-tape",
|
||||||
|
.bus = &ide_bus_type,
|
||||||
|
.probe = ide_tape_probe,
|
||||||
|
.remove = ide_tape_remove,
|
||||||
|
},
|
||||||
.version = IDETAPE_VERSION,
|
.version = IDETAPE_VERSION,
|
||||||
.media = ide_tape,
|
.media = ide_tape,
|
||||||
.busy = 1,
|
|
||||||
.supports_dsc_overlap = 1,
|
.supports_dsc_overlap = 1,
|
||||||
.cleanup = idetape_cleanup,
|
|
||||||
.do_request = idetape_do_request,
|
.do_request = idetape_do_request,
|
||||||
.end_request = idetape_end_request,
|
.end_request = idetape_end_request,
|
||||||
.error = __ide_error,
|
.error = __ide_error,
|
||||||
.abort = __ide_abort,
|
.abort = __ide_abort,
|
||||||
.proc = idetape_proc,
|
.proc = idetape_proc,
|
||||||
.attach = idetape_attach,
|
|
||||||
.drives = LIST_HEAD_INIT(idetape_driver.drives),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4829,8 +4820,9 @@ static struct block_device_operations idetape_block_ops = {
|
|||||||
.ioctl = idetape_ioctl,
|
.ioctl = idetape_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idetape_attach (ide_drive_t *drive)
|
static int ide_tape_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
idetape_tape_t *tape;
|
idetape_tape_t *tape;
|
||||||
struct gendisk *g;
|
struct gendisk *g;
|
||||||
int minor;
|
int minor;
|
||||||
@ -4865,10 +4857,7 @@ static int idetape_attach (ide_drive_t *drive)
|
|||||||
|
|
||||||
ide_init_disk(g, drive);
|
ide_init_disk(g, drive);
|
||||||
|
|
||||||
if (ide_register_subdriver(drive, &idetape_driver)) {
|
ide_register_subdriver(drive, &idetape_driver);
|
||||||
printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name);
|
|
||||||
goto out_put_disk;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(tape, 0, sizeof(*tape));
|
memset(tape, 0, sizeof(*tape));
|
||||||
|
|
||||||
@ -4902,12 +4891,11 @@ static int idetape_attach (ide_drive_t *drive)
|
|||||||
ide_register_region(g);
|
ide_register_region(g);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
out_put_disk:
|
|
||||||
put_disk(g);
|
|
||||||
out_free_tape:
|
out_free_tape:
|
||||||
kfree(tape);
|
kfree(tape);
|
||||||
failed:
|
failed:
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
|
MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
|
||||||
@ -4915,7 +4903,7 @@ MODULE_LICENSE("GPL");
|
|||||||
|
|
||||||
static void __exit idetape_exit (void)
|
static void __exit idetape_exit (void)
|
||||||
{
|
{
|
||||||
ide_unregister_driver(&idetape_driver);
|
driver_unregister(&idetape_driver.gen_driver);
|
||||||
unregister_chrdev(IDETAPE_MAJOR, "ht");
|
unregister_chrdev(IDETAPE_MAJOR, "ht");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4928,8 +4916,7 @@ static int idetape_init (void)
|
|||||||
printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
|
printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
ide_register_driver(&idetape_driver);
|
return driver_register(&idetape_driver.gen_driver);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(idetape_init);
|
module_init(idetape_init);
|
||||||
|
@ -196,8 +196,6 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
|
|||||||
|
|
||||||
EXPORT_SYMBOL(ide_hwifs);
|
EXPORT_SYMBOL(ide_hwifs);
|
||||||
|
|
||||||
static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not even *think* about calling this!
|
* Do not even *think* about calling this!
|
||||||
*/
|
*/
|
||||||
@ -358,54 +356,6 @@ static int ide_system_bus_speed(void)
|
|||||||
return system_bus_speed;
|
return system_bus_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* drives_lock protects the list of drives, drivers_lock the
|
|
||||||
* list of drivers. Currently nobody takes both at once.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(drives_lock);
|
|
||||||
static DEFINE_SPINLOCK(drivers_lock);
|
|
||||||
static LIST_HEAD(drivers);
|
|
||||||
|
|
||||||
/* Iterator for the driver list. */
|
|
||||||
|
|
||||||
static void *m_start(struct seq_file *m, loff_t *pos)
|
|
||||||
{
|
|
||||||
struct list_head *p;
|
|
||||||
loff_t l = *pos;
|
|
||||||
spin_lock(&drivers_lock);
|
|
||||||
list_for_each(p, &drivers)
|
|
||||||
if (!l--)
|
|
||||||
return list_entry(p, ide_driver_t, drivers);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *m_next(struct seq_file *m, void *v, loff_t *pos)
|
|
||||||
{
|
|
||||||
struct list_head *p = ((ide_driver_t *)v)->drivers.next;
|
|
||||||
(*pos)++;
|
|
||||||
return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m_stop(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
spin_unlock(&drivers_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int show_driver(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
ide_driver_t *driver = v;
|
|
||||||
seq_printf(m, "%s version %s\n", driver->name, driver->version);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct seq_operations ide_drivers_op = {
|
|
||||||
.start = m_start,
|
|
||||||
.next = m_next,
|
|
||||||
.stop = m_stop,
|
|
||||||
.show = show_driver
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
struct proc_dir_entry *proc_ide_root;
|
struct proc_dir_entry *proc_ide_root;
|
||||||
#endif
|
#endif
|
||||||
@ -630,7 +580,7 @@ void ide_unregister(unsigned int index)
|
|||||||
ide_hwif_t *hwif, *g;
|
ide_hwif_t *hwif, *g;
|
||||||
static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */
|
static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */
|
||||||
ide_hwgroup_t *hwgroup;
|
ide_hwgroup_t *hwgroup;
|
||||||
int irq_count = 0, unit, i;
|
int irq_count = 0, unit;
|
||||||
|
|
||||||
BUG_ON(index >= MAX_HWIFS);
|
BUG_ON(index >= MAX_HWIFS);
|
||||||
|
|
||||||
@ -643,23 +593,22 @@ void ide_unregister(unsigned int index)
|
|||||||
goto abort;
|
goto abort;
|
||||||
for (unit = 0; unit < MAX_DRIVES; ++unit) {
|
for (unit = 0; unit < MAX_DRIVES; ++unit) {
|
||||||
drive = &hwif->drives[unit];
|
drive = &hwif->drives[unit];
|
||||||
if (!drive->present)
|
if (!drive->present) {
|
||||||
|
if (drive->devfs_name[0] != '\0') {
|
||||||
|
devfs_remove(drive->devfs_name);
|
||||||
|
drive->devfs_name[0] = '\0';
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
if (drive->usage || DRIVER(drive)->busy)
|
}
|
||||||
goto abort;
|
spin_unlock_irq(&ide_lock);
|
||||||
drive->dead = 1;
|
device_unregister(&drive->gendev);
|
||||||
|
down(&drive->gendev_rel_sem);
|
||||||
|
spin_lock_irq(&ide_lock);
|
||||||
}
|
}
|
||||||
hwif->present = 0;
|
hwif->present = 0;
|
||||||
|
|
||||||
spin_unlock_irq(&ide_lock);
|
spin_unlock_irq(&ide_lock);
|
||||||
|
|
||||||
for (unit = 0; unit < MAX_DRIVES; ++unit) {
|
|
||||||
drive = &hwif->drives[unit];
|
|
||||||
if (!drive->present)
|
|
||||||
continue;
|
|
||||||
DRIVER(drive)->cleanup(drive);
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy_proc_ide_interface(hwif);
|
destroy_proc_ide_interface(hwif);
|
||||||
|
|
||||||
hwgroup = hwif->hwgroup;
|
hwgroup = hwif->hwgroup;
|
||||||
@ -687,44 +636,6 @@ void ide_unregister(unsigned int index)
|
|||||||
* Remove us from the hwgroup, and free
|
* Remove us from the hwgroup, and free
|
||||||
* the hwgroup if we were the only member
|
* the hwgroup if we were the only member
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < MAX_DRIVES; ++i) {
|
|
||||||
drive = &hwif->drives[i];
|
|
||||||
if (drive->devfs_name[0] != '\0') {
|
|
||||||
devfs_remove(drive->devfs_name);
|
|
||||||
drive->devfs_name[0] = '\0';
|
|
||||||
}
|
|
||||||
if (!drive->present)
|
|
||||||
continue;
|
|
||||||
if (drive == drive->next) {
|
|
||||||
/* special case: last drive from hwgroup. */
|
|
||||||
BUG_ON(hwgroup->drive != drive);
|
|
||||||
hwgroup->drive = NULL;
|
|
||||||
} else {
|
|
||||||
ide_drive_t *walk;
|
|
||||||
|
|
||||||
walk = hwgroup->drive;
|
|
||||||
while (walk->next != drive)
|
|
||||||
walk = walk->next;
|
|
||||||
walk->next = drive->next;
|
|
||||||
if (hwgroup->drive == drive) {
|
|
||||||
hwgroup->drive = drive->next;
|
|
||||||
hwgroup->hwif = HWIF(hwgroup->drive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BUG_ON(hwgroup->drive == drive);
|
|
||||||
if (drive->id != NULL) {
|
|
||||||
kfree(drive->id);
|
|
||||||
drive->id = NULL;
|
|
||||||
}
|
|
||||||
drive->present = 0;
|
|
||||||
/* Messed up locking ... */
|
|
||||||
spin_unlock_irq(&ide_lock);
|
|
||||||
blk_cleanup_queue(drive->queue);
|
|
||||||
device_unregister(&drive->gendev);
|
|
||||||
down(&drive->gendev_rel_sem);
|
|
||||||
spin_lock_irq(&ide_lock);
|
|
||||||
drive->queue = NULL;
|
|
||||||
}
|
|
||||||
if (hwif->next == hwif) {
|
if (hwif->next == hwif) {
|
||||||
BUG_ON(hwgroup->hwif != hwif);
|
BUG_ON(hwgroup->hwif != hwif);
|
||||||
kfree(hwgroup);
|
kfree(hwgroup);
|
||||||
@ -1304,73 +1215,6 @@ int system_bus_clock (void)
|
|||||||
|
|
||||||
EXPORT_SYMBOL(system_bus_clock);
|
EXPORT_SYMBOL(system_bus_clock);
|
||||||
|
|
||||||
/*
|
|
||||||
* Locking is badly broken here - since way back. That sucker is
|
|
||||||
* root-only, but that's not an excuse... The real question is what
|
|
||||||
* exclusion rules do we want here.
|
|
||||||
*/
|
|
||||||
int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
|
|
||||||
{
|
|
||||||
if (!drive->present || drive->usage || drive->dead)
|
|
||||||
goto abort;
|
|
||||||
if (DRIVER(drive)->cleanup(drive))
|
|
||||||
goto abort;
|
|
||||||
strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
|
|
||||||
if (ata_attach(drive)) {
|
|
||||||
spin_lock(&drives_lock);
|
|
||||||
list_del_init(&drive->list);
|
|
||||||
spin_unlock(&drives_lock);
|
|
||||||
drive->driver_req[0] = 0;
|
|
||||||
ata_attach(drive);
|
|
||||||
} else {
|
|
||||||
drive->driver_req[0] = 0;
|
|
||||||
}
|
|
||||||
if (drive->driver && !strcmp(drive->driver->name, driver))
|
|
||||||
return 0;
|
|
||||||
abort:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ata_attach - attach an ATA/ATAPI device
|
|
||||||
* @drive: drive to attach
|
|
||||||
*
|
|
||||||
* Takes a drive that is as yet not assigned to any midlayer IDE
|
|
||||||
* driver (or is assigned to the default driver) and figures out
|
|
||||||
* which driver would like to own it. If nobody claims the drive
|
|
||||||
* then it is automatically attached to the default driver used for
|
|
||||||
* unclaimed objects.
|
|
||||||
*
|
|
||||||
* A return of zero indicates attachment to a driver, of one
|
|
||||||
* attachment to the default driver.
|
|
||||||
*
|
|
||||||
* Takes drivers_lock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ata_attach(ide_drive_t *drive)
|
|
||||||
{
|
|
||||||
struct list_head *p;
|
|
||||||
spin_lock(&drivers_lock);
|
|
||||||
list_for_each(p, &drivers) {
|
|
||||||
ide_driver_t *driver = list_entry(p, ide_driver_t, drivers);
|
|
||||||
if (!try_module_get(driver->owner))
|
|
||||||
continue;
|
|
||||||
spin_unlock(&drivers_lock);
|
|
||||||
if (driver->attach(drive) == 0) {
|
|
||||||
module_put(driver->owner);
|
|
||||||
drive->gendev.driver = &driver->gen_driver;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
spin_lock(&drivers_lock);
|
|
||||||
module_put(driver->owner);
|
|
||||||
}
|
|
||||||
drive->gendev.driver = NULL;
|
|
||||||
spin_unlock(&drivers_lock);
|
|
||||||
if (ide_register_subdriver(drive, NULL))
|
|
||||||
panic("ide: default attach failed");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int generic_ide_suspend(struct device *dev, pm_message_t state)
|
static int generic_ide_suspend(struct device *dev, pm_message_t state)
|
||||||
{
|
{
|
||||||
ide_drive_t *drive = dev->driver_data;
|
ide_drive_t *drive = dev->driver_data;
|
||||||
@ -2013,27 +1857,11 @@ static void __init probe_for_hwifs (void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
|
void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ide_lock, flags);
|
|
||||||
if (!drive->present || drive->driver != NULL ||
|
|
||||||
drive->usage || drive->dead) {
|
|
||||||
spin_unlock_irqrestore(&ide_lock, flags);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
drive->driver = driver;
|
|
||||||
spin_unlock_irqrestore(&ide_lock, flags);
|
|
||||||
spin_lock(&drives_lock);
|
|
||||||
list_add_tail(&drive->list, driver ? &driver->drives : &ide_drives);
|
|
||||||
spin_unlock(&drives_lock);
|
|
||||||
// printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name);
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
if (driver)
|
ide_add_proc_entries(drive->proc, driver->proc, drive);
|
||||||
ide_add_proc_entries(drive->proc, driver->proc, drive);
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(ide_register_subdriver);
|
EXPORT_SYMBOL(ide_register_subdriver);
|
||||||
@ -2041,136 +1869,51 @@ EXPORT_SYMBOL(ide_register_subdriver);
|
|||||||
/**
|
/**
|
||||||
* ide_unregister_subdriver - disconnect drive from driver
|
* ide_unregister_subdriver - disconnect drive from driver
|
||||||
* @drive: drive to unplug
|
* @drive: drive to unplug
|
||||||
|
* @driver: driver
|
||||||
*
|
*
|
||||||
* Disconnect a drive from the driver it was attached to and then
|
* Disconnect a drive from the driver it was attached to and then
|
||||||
* clean up the various proc files and other objects attached to it.
|
* clean up the various proc files and other objects attached to it.
|
||||||
*
|
*
|
||||||
* Takes ide_setting_sem, ide_lock and drives_lock.
|
* Takes ide_setting_sem and ide_lock.
|
||||||
* Caller must hold none of the locks.
|
* Caller must hold none of the locks.
|
||||||
*
|
|
||||||
* No locking versus subdriver unload because we are moving to the
|
|
||||||
* default driver anyway. Wants double checking.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ide_unregister_subdriver (ide_drive_t *drive)
|
void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
down(&ide_setting_sem);
|
down(&ide_setting_sem);
|
||||||
spin_lock_irqsave(&ide_lock, flags);
|
spin_lock_irqsave(&ide_lock, flags);
|
||||||
if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
|
|
||||||
spin_unlock_irqrestore(&ide_lock, flags);
|
|
||||||
up(&ide_setting_sem);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc);
|
ide_remove_proc_entries(drive->proc, driver->proc);
|
||||||
#endif
|
#endif
|
||||||
auto_remove_settings(drive);
|
auto_remove_settings(drive);
|
||||||
drive->driver = NULL;
|
|
||||||
spin_unlock_irqrestore(&ide_lock, flags);
|
spin_unlock_irqrestore(&ide_lock, flags);
|
||||||
up(&ide_setting_sem);
|
up(&ide_setting_sem);
|
||||||
spin_lock(&drives_lock);
|
|
||||||
list_del_init(&drive->list);
|
|
||||||
spin_unlock(&drives_lock);
|
|
||||||
/* drive will be added to &ide_drives in ata_attach() */
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(ide_unregister_subdriver);
|
EXPORT_SYMBOL(ide_unregister_subdriver);
|
||||||
|
|
||||||
static int ide_drive_remove(struct device * dev)
|
|
||||||
{
|
|
||||||
ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
|
|
||||||
DRIVER(drive)->cleanup(drive);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ide_register_driver - register IDE device driver
|
|
||||||
* @driver: the IDE device driver
|
|
||||||
*
|
|
||||||
* Register a new device driver and then scan the devices
|
|
||||||
* on the IDE bus in case any should be attached to the
|
|
||||||
* driver we have just registered. If so attach them.
|
|
||||||
*
|
|
||||||
* Takes drivers_lock and drives_lock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ide_register_driver(ide_driver_t *driver)
|
|
||||||
{
|
|
||||||
struct list_head list;
|
|
||||||
struct list_head *list_loop;
|
|
||||||
struct list_head *tmp_storage;
|
|
||||||
|
|
||||||
spin_lock(&drivers_lock);
|
|
||||||
list_add(&driver->drivers, &drivers);
|
|
||||||
spin_unlock(&drivers_lock);
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&list);
|
|
||||||
spin_lock(&drives_lock);
|
|
||||||
list_splice_init(&ide_drives, &list);
|
|
||||||
spin_unlock(&drives_lock);
|
|
||||||
|
|
||||||
list_for_each_safe(list_loop, tmp_storage, &list) {
|
|
||||||
ide_drive_t *drive = container_of(list_loop, ide_drive_t, list);
|
|
||||||
list_del_init(&drive->list);
|
|
||||||
if (drive->present)
|
|
||||||
ata_attach(drive);
|
|
||||||
}
|
|
||||||
driver->gen_driver.name = (char *) driver->name;
|
|
||||||
driver->gen_driver.bus = &ide_bus_type;
|
|
||||||
driver->gen_driver.remove = ide_drive_remove;
|
|
||||||
return driver_register(&driver->gen_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ide_register_driver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ide_unregister_driver - unregister IDE device driver
|
|
||||||
* @driver: the IDE device driver
|
|
||||||
*
|
|
||||||
* Called when a driver module is being unloaded. We reattach any
|
|
||||||
* devices to whatever driver claims them next (typically the default
|
|
||||||
* driver).
|
|
||||||
*
|
|
||||||
* Takes drivers_lock and called functions will take ide_setting_sem.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ide_unregister_driver(ide_driver_t *driver)
|
|
||||||
{
|
|
||||||
ide_drive_t *drive;
|
|
||||||
|
|
||||||
spin_lock(&drivers_lock);
|
|
||||||
list_del(&driver->drivers);
|
|
||||||
spin_unlock(&drivers_lock);
|
|
||||||
|
|
||||||
driver_unregister(&driver->gen_driver);
|
|
||||||
|
|
||||||
while(!list_empty(&driver->drives)) {
|
|
||||||
drive = list_entry(driver->drives.next, ide_drive_t, list);
|
|
||||||
if (driver->cleanup(drive)) {
|
|
||||||
printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name);
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
ata_attach(drive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ide_unregister_driver);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probe module
|
* Probe module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EXPORT_SYMBOL(ide_lock);
|
EXPORT_SYMBOL(ide_lock);
|
||||||
|
|
||||||
|
static int ide_bus_match(struct device *dev, struct device_driver *drv)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct bus_type ide_bus_type = {
|
struct bus_type ide_bus_type = {
|
||||||
.name = "ide",
|
.name = "ide",
|
||||||
|
.match = ide_bus_match,
|
||||||
.suspend = generic_ide_suspend,
|
.suspend = generic_ide_suspend,
|
||||||
.resume = generic_ide_resume,
|
.resume = generic_ide_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EXPORT_SYMBOL_GPL(ide_bus_type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is gets invoked once during initialization, to set *everything* up
|
* This is gets invoked once during initialization, to set *everything* up
|
||||||
*/
|
*/
|
||||||
|
@ -713,7 +713,6 @@ static void idescsi_add_settings(ide_drive_t *drive)
|
|||||||
*/
|
*/
|
||||||
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
|
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
|
||||||
{
|
{
|
||||||
DRIVER(drive)->busy++;
|
|
||||||
if (drive->id && (drive->id->config & 0x0060) == 0x20)
|
if (drive->id && (drive->id->config & 0x0060) == 0x20)
|
||||||
set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
|
set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
|
||||||
set_bit(IDESCSI_TRANSFORM, &scsi->transform);
|
set_bit(IDESCSI_TRANSFORM, &scsi->transform);
|
||||||
@ -722,17 +721,16 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
|
|||||||
set_bit(IDESCSI_LOG_CMD, &scsi->log);
|
set_bit(IDESCSI_LOG_CMD, &scsi->log);
|
||||||
#endif /* IDESCSI_DEBUG_LOG */
|
#endif /* IDESCSI_DEBUG_LOG */
|
||||||
idescsi_add_settings(drive);
|
idescsi_add_settings(drive);
|
||||||
DRIVER(drive)->busy--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idescsi_cleanup (ide_drive_t *drive)
|
static int ide_scsi_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
struct Scsi_Host *scsihost = drive->driver_data;
|
struct Scsi_Host *scsihost = drive->driver_data;
|
||||||
struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
|
struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
|
||||||
struct gendisk *g = scsi->disk;
|
struct gendisk *g = scsi->disk;
|
||||||
|
|
||||||
if (ide_unregister_subdriver(drive))
|
ide_unregister_subdriver(drive, scsi->driver);
|
||||||
return 1;
|
|
||||||
|
|
||||||
ide_unregister_region(g);
|
ide_unregister_region(g);
|
||||||
|
|
||||||
@ -746,7 +744,7 @@ static int idescsi_cleanup (ide_drive_t *drive)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idescsi_attach(ide_drive_t *drive);
|
static int ide_scsi_probe(struct device *);
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
static ide_proc_entry_t idescsi_proc[] = {
|
static ide_proc_entry_t idescsi_proc[] = {
|
||||||
@ -757,24 +755,22 @@ static ide_proc_entry_t idescsi_proc[] = {
|
|||||||
# define idescsi_proc NULL
|
# define idescsi_proc NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* IDE subdriver functions, registered with ide.c
|
|
||||||
*/
|
|
||||||
static ide_driver_t idescsi_driver = {
|
static ide_driver_t idescsi_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "ide-scsi",
|
.gen_driver = {
|
||||||
|
.name = "ide-scsi",
|
||||||
|
.bus = &ide_bus_type,
|
||||||
|
.probe = ide_scsi_probe,
|
||||||
|
.remove = ide_scsi_remove,
|
||||||
|
},
|
||||||
.version = IDESCSI_VERSION,
|
.version = IDESCSI_VERSION,
|
||||||
.media = ide_scsi,
|
.media = ide_scsi,
|
||||||
.busy = 0,
|
|
||||||
.supports_dsc_overlap = 0,
|
.supports_dsc_overlap = 0,
|
||||||
.proc = idescsi_proc,
|
.proc = idescsi_proc,
|
||||||
.attach = idescsi_attach,
|
|
||||||
.cleanup = idescsi_cleanup,
|
|
||||||
.do_request = idescsi_do_request,
|
.do_request = idescsi_do_request,
|
||||||
.end_request = idescsi_end_request,
|
.end_request = idescsi_end_request,
|
||||||
.error = idescsi_atapi_error,
|
.error = idescsi_atapi_error,
|
||||||
.abort = idescsi_atapi_abort,
|
.abort = idescsi_atapi_abort,
|
||||||
.drives = LIST_HEAD_INIT(idescsi_driver.drives),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idescsi_ide_open(struct inode *inode, struct file *filp)
|
static int idescsi_ide_open(struct inode *inode, struct file *filp)
|
||||||
@ -821,8 +817,6 @@ static struct block_device_operations idescsi_ops = {
|
|||||||
.ioctl = idescsi_ide_ioctl,
|
.ioctl = idescsi_ide_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idescsi_attach(ide_drive_t *drive);
|
|
||||||
|
|
||||||
static int idescsi_slave_configure(struct scsi_device * sdp)
|
static int idescsi_slave_configure(struct scsi_device * sdp)
|
||||||
{
|
{
|
||||||
/* Configure detected device */
|
/* Configure detected device */
|
||||||
@ -1095,8 +1089,9 @@ static struct scsi_host_template idescsi_template = {
|
|||||||
.proc_name = "ide-scsi",
|
.proc_name = "ide-scsi",
|
||||||
};
|
};
|
||||||
|
|
||||||
static int idescsi_attach(ide_drive_t *drive)
|
static int ide_scsi_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
|
ide_drive_t *drive = to_ide_device(dev);
|
||||||
idescsi_scsi_t *idescsi;
|
idescsi_scsi_t *idescsi;
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
struct gendisk *g;
|
struct gendisk *g;
|
||||||
@ -1112,7 +1107,7 @@ static int idescsi_attach(ide_drive_t *drive)
|
|||||||
!drive->present ||
|
!drive->present ||
|
||||||
drive->media == ide_disk ||
|
drive->media == ide_disk ||
|
||||||
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
|
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
|
||||||
return 1;
|
return -ENODEV;
|
||||||
|
|
||||||
g = alloc_disk(1 << PARTN_BITS);
|
g = alloc_disk(1 << PARTN_BITS);
|
||||||
if (!g)
|
if (!g)
|
||||||
@ -1138,20 +1133,19 @@ static int idescsi_attach(ide_drive_t *drive)
|
|||||||
idescsi->host = host;
|
idescsi->host = host;
|
||||||
idescsi->disk = g;
|
idescsi->disk = g;
|
||||||
g->private_data = &idescsi->driver;
|
g->private_data = &idescsi->driver;
|
||||||
err = ide_register_subdriver(drive, &idescsi_driver);
|
ide_register_subdriver(drive, &idescsi_driver);
|
||||||
|
err = 0;
|
||||||
|
idescsi_setup(drive, idescsi);
|
||||||
|
g->fops = &idescsi_ops;
|
||||||
|
ide_register_region(g);
|
||||||
|
err = scsi_add_host(host, &drive->gendev);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
idescsi_setup (drive, idescsi);
|
scsi_scan_host(host);
|
||||||
g->fops = &idescsi_ops;
|
return 0;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
/* fall through on error */
|
||||||
|
ide_unregister_region(g);
|
||||||
|
ide_unregister_subdriver(drive, &idescsi_driver);
|
||||||
|
|
||||||
put_disk(g);
|
put_disk(g);
|
||||||
out_host_put:
|
out_host_put:
|
||||||
@ -1161,12 +1155,12 @@ out_host_put:
|
|||||||
|
|
||||||
static int __init init_idescsi_module(void)
|
static int __init init_idescsi_module(void)
|
||||||
{
|
{
|
||||||
return ide_register_driver(&idescsi_driver);
|
return driver_register(&idescsi_driver.gen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit exit_idescsi_module(void)
|
static void __exit exit_idescsi_module(void)
|
||||||
{
|
{
|
||||||
ide_unregister_driver(&idescsi_driver);
|
driver_unregister(&idescsi_driver.gen_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init_idescsi_module);
|
module_init(init_idescsi_module);
|
||||||
|
@ -664,7 +664,6 @@ typedef struct ide_drive_s {
|
|||||||
|
|
||||||
struct request *rq; /* current request */
|
struct request *rq; /* current request */
|
||||||
struct ide_drive_s *next; /* circular list of hwgroup drives */
|
struct ide_drive_s *next; /* circular list of hwgroup drives */
|
||||||
struct ide_driver_s *driver;/* (ide_driver_t *) */
|
|
||||||
void *driver_data; /* extra driver data */
|
void *driver_data; /* extra driver data */
|
||||||
struct hd_driveid *id; /* drive model identification info */
|
struct hd_driveid *id; /* drive model identification info */
|
||||||
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
|
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
|
||||||
@ -758,6 +757,8 @@ typedef struct ide_drive_s {
|
|||||||
struct semaphore gendev_rel_sem; /* to deal with device release() */
|
struct semaphore gendev_rel_sem; /* to deal with device release() */
|
||||||
} ide_drive_t;
|
} ide_drive_t;
|
||||||
|
|
||||||
|
#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
|
||||||
|
|
||||||
#define IDE_CHIPSET_PCI_MASK \
|
#define IDE_CHIPSET_PCI_MASK \
|
||||||
((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
|
((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
|
||||||
#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
|
#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
|
||||||
@ -1086,28 +1087,20 @@ enum {
|
|||||||
*/
|
*/
|
||||||
typedef struct ide_driver_s {
|
typedef struct ide_driver_s {
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
const char *name;
|
|
||||||
const char *version;
|
const char *version;
|
||||||
u8 media;
|
u8 media;
|
||||||
unsigned busy : 1;
|
|
||||||
unsigned supports_dsc_overlap : 1;
|
unsigned supports_dsc_overlap : 1;
|
||||||
int (*cleanup)(ide_drive_t *);
|
|
||||||
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
|
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
|
||||||
int (*end_request)(ide_drive_t *, int, int);
|
int (*end_request)(ide_drive_t *, int, int);
|
||||||
ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8);
|
ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8);
|
||||||
ide_startstop_t (*abort)(ide_drive_t *, struct request *rq);
|
ide_startstop_t (*abort)(ide_drive_t *, struct request *rq);
|
||||||
int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
|
int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
|
||||||
ide_proc_entry_t *proc;
|
ide_proc_entry_t *proc;
|
||||||
int (*attach)(ide_drive_t *);
|
|
||||||
void (*ata_prebuilder)(ide_drive_t *);
|
void (*ata_prebuilder)(ide_drive_t *);
|
||||||
void (*atapi_prebuilder)(ide_drive_t *);
|
void (*atapi_prebuilder)(ide_drive_t *);
|
||||||
struct device_driver gen_driver;
|
struct device_driver gen_driver;
|
||||||
struct list_head drives;
|
|
||||||
struct list_head drivers;
|
|
||||||
} ide_driver_t;
|
} ide_driver_t;
|
||||||
|
|
||||||
#define DRIVER(drive) ((drive)->driver)
|
|
||||||
|
|
||||||
int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
|
int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1328,8 +1321,6 @@ extern void ide_init_subdrivers(void);
|
|||||||
|
|
||||||
void ide_init_disk(struct gendisk *, ide_drive_t *);
|
void ide_init_disk(struct gendisk *, ide_drive_t *);
|
||||||
|
|
||||||
extern int ata_attach(ide_drive_t *);
|
|
||||||
|
|
||||||
extern int ideprobe_init(void);
|
extern int ideprobe_init(void);
|
||||||
|
|
||||||
extern void ide_scan_pcibus(int scan_direction) __init;
|
extern void ide_scan_pcibus(int scan_direction) __init;
|
||||||
@ -1342,11 +1333,8 @@ extern void default_hwif_iops(ide_hwif_t *);
|
|||||||
extern void default_hwif_mmiops(ide_hwif_t *);
|
extern void default_hwif_mmiops(ide_hwif_t *);
|
||||||
extern void default_hwif_transport(ide_hwif_t *);
|
extern void default_hwif_transport(ide_hwif_t *);
|
||||||
|
|
||||||
int ide_register_driver(ide_driver_t *driver);
|
void ide_register_subdriver(ide_drive_t *, ide_driver_t *);
|
||||||
void ide_unregister_driver(ide_driver_t *driver);
|
void ide_unregister_subdriver(ide_drive_t *, ide_driver_t *);
|
||||||
int ide_register_subdriver(ide_drive_t *, ide_driver_t *);
|
|
||||||
int ide_unregister_subdriver (ide_drive_t *drive);
|
|
||||||
int ide_replace_subdriver(ide_drive_t *drive, const char *driver);
|
|
||||||
|
|
||||||
#define ON_BOARD 1
|
#define ON_BOARD 1
|
||||||
#define NEVER_BOARD 0
|
#define NEVER_BOARD 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user