Commit 6ccb8d02 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] gendisk for cm206

cm206 switched to use of gendisk, failure path in module_init cleaned up
parent cce4287b
...@@ -772,11 +772,11 @@ void get_disc_status(void) ...@@ -772,11 +772,11 @@ void get_disc_status(void)
struct block_device_operations cm206_bdops = struct block_device_operations cm206_bdops =
{ {
owner: THIS_MODULE, .owner = THIS_MODULE,
open: cdrom_open, .open = cdrom_open,
release: cdrom_release, .release = cdrom_release,
ioctl: cdrom_ioctl, .ioctl = cdrom_ioctl,
check_media_change: cdrom_media_changed, .check_media_change = cdrom_media_changed,
}; };
/* The new open. The real opening strategy is defined in cdrom.c. */ /* The new open. The real opening strategy is defined in cdrom.c. */
...@@ -1330,57 +1330,40 @@ int cm206_select_speed(struct cdrom_device_info *cdi, int speed) ...@@ -1330,57 +1330,40 @@ int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
} }
static struct cdrom_device_ops cm206_dops = { static struct cdrom_device_ops cm206_dops = {
open:cm206_open, .open = cm206_open,
release:cm206_release, .release = cm206_release,
drive_status:cm206_drive_status, .drive_status = cm206_drive_status,
media_changed:cm206_media_changed, .media_changed = cm206_media_changed,
tray_move:cm206_tray_move, .tray_move = cm206_tray_move,
lock_door:cm206_lock_door, .lock_door = cm206_lock_door,
select_speed:cm206_select_speed, .select_speed = cm206_select_speed,
get_last_session:cm206_get_last_session, .get_last_session = cm206_get_last_session,
get_mcn:cm206_get_upc, .get_mcn = cm206_get_upc,
reset:cm206_reset, .reset = cm206_reset,
audio_ioctl:cm206_audio_ioctl, .audio_ioctl = cm206_audio_ioctl,
dev_ioctl:cm206_ioctl, .dev_ioctl = cm206_ioctl,
capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED | CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
CDC_IOCTLS | CDC_DRIVE_STATUS, CDC_IOCTLS | CDC_DRIVE_STATUS,
n_minors:1, .n_minors = 1,
}; };
static struct cdrom_device_info cm206_info = { static struct cdrom_device_info cm206_info = {
ops:&cm206_dops, .ops = &cm206_dops,
speed:2, .speed = 2,
capacity:1, .capacity = 1,
name:"cm206", .name = "cm206",
}; };
/* This routine gets called during initialization if things go wrong, static struct gendisk cm206_gendisk = {
* can be used in cleanup_module as well. */ .major = MAJOR_NR,
static void cleanup(int level) .first_minor = 0,
{ .minor_shift = 0,
switch (level) { .major_name = "cm206",
case 4: .fops = &cm206_bdops,
if (unregister_cdrom(&cm206_info)) { };
printk("Can't unregister cdrom cm206\n");
return;
}
if (unregister_blkdev(MAJOR_NR, "cm206")) {
printk("Can't unregister major cm206\n");
return;
}
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
case 3:
free_irq(cm206_irq, NULL);
case 2:
case 1:
kfree(cd);
release_region(cm206_base, 16);
default:;
}
}
/* This function probes for the adapter card. It returns the base /* This function probes for the adapter card. It returns the base
address if it has found the adapter card. One can specify a base address if it has found the adapter card. One can specify a base
...@@ -1435,6 +1418,7 @@ int __init cm206_init(void) ...@@ -1435,6 +1418,7 @@ int __init cm206_init(void)
{ {
uch e = 0; uch e = 0;
long int size = sizeof(struct cm206_struct); long int size = sizeof(struct cm206_struct);
struct gendisk *disk = &cm206_gendisk;
printk(KERN_INFO "cm206 cdrom driver " REVISION); printk(KERN_INFO "cm206 cdrom driver " REVISION);
cm206_base = probe_base_port(auto_probe ? 0 : cm206_base); cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
...@@ -1454,7 +1438,7 @@ int __init cm206_init(void) ...@@ -1454,7 +1438,7 @@ int __init cm206_init(void)
cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq); cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
if (cm206_irq <= 0) { if (cm206_irq <= 0) {
printk("can't find IRQ!\n"); printk("can't find IRQ!\n");
cleanup(1); goto out_probe;
return -EIO; return -EIO;
} else } else
printk(" IRQ %d found\n", cm206_irq); printk(" IRQ %d found\n", cm206_irq);
...@@ -1472,8 +1456,7 @@ int __init cm206_init(void) ...@@ -1472,8 +1456,7 @@ int __init cm206_init(void)
if (send_receive_polled(c_drive_configuration) != if (send_receive_polled(c_drive_configuration) !=
c_drive_configuration) { c_drive_configuration) {
printk(KERN_INFO " drive not there\n"); printk(KERN_INFO " drive not there\n");
cleanup(1); goto out_probe;
return -EIO;
} }
e = send_receive_polled(c_gimme); e = send_receive_polled(c_gimme);
printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code); printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
...@@ -1486,24 +1469,25 @@ int __init cm206_init(void) ...@@ -1486,24 +1469,25 @@ int __init cm206_init(void)
printk(", motorized tray"); printk(", motorized tray");
if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) { if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
printk("\nUnable to reserve IRQ---aborted\n"); printk("\nUnable to reserve IRQ---aborted\n");
cleanup(2); goto out_probe;
return -EIO;
} }
printk(".\n"); printk(".\n");
if (register_blkdev(MAJOR_NR, "cm206", &cm206_bdops) != 0) { if (register_blkdev(MAJOR_NR, "cm206", &cm206_bdops) != 0) {
printk(KERN_INFO "Cannot register for major %d!\n", printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR);
MAJOR_NR); goto out_blkdev;
cleanup(3);
return -EIO;
} }
cm206_info.dev = mk_kdev(MAJOR_NR, 0); cm206_info.dev = mk_kdev(MAJOR_NR, 0);
if (register_cdrom(&cm206_info) != 0) { if (register_cdrom(&cm206_info) != 0) {
printk(KERN_INFO "Cannot register for cdrom %d!\n", printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
MAJOR_NR); goto out_cdrom;
cleanup(3);
return -EIO;
} }
devfs_plain_cdrom(&cm206_info, &cm206_bdops); devfs_plain_cdrom(&cm206_info, disk->fops);
add_gendisk(disk);
register_disk(disk,
mk_kdev(disk->major,disk->first_minor),
1<<disk->minor_shift,
disk->fops,
0);
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_cm206_request, blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_cm206_request,
&cm206_lock); &cm206_lock);
blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), 2048); blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), 2048);
...@@ -1517,6 +1501,15 @@ int __init cm206_init(void) ...@@ -1517,6 +1501,15 @@ int __init cm206_init(void)
" %ld bytes kernel memory used.\n", cd->max_sectors * 2, " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
size); size);
return 0; return 0;
out_cdrom:
unregister_blkdev(MAJOR_NR, "cm206");
out_blkdev:
free_irq(cm206_irq, NULL);
out_probe:
kfree(cd);
release_region(cm206_base, 16);
return -EIO;
} }
#ifdef MODULE #ifdef MODULE
...@@ -1548,7 +1541,19 @@ int __cm206_init(void) ...@@ -1548,7 +1541,19 @@ int __cm206_init(void)
void __exit cm206_exit(void) void __exit cm206_exit(void)
{ {
cleanup(4); del_gendisk(&cm206_gendisk);
if (unregister_cdrom(&cm206_info)) {
printk("Can't unregister cdrom cm206\n");
return;
}
if (unregister_blkdev(MAJOR_NR, "cm206")) {
printk("Can't unregister major cm206\n");
return;
}
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
free_irq(cm206_irq, NULL);
kfree(cd);
release_region(cm206_base, 16);
printk(KERN_INFO "cm206 removed\n"); printk(KERN_INFO "cm206 removed\n");
} }
......
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