Commit 00684492 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] old cdroms switched to dynamic allocation

parent 80f6d6c0
......@@ -1690,13 +1690,7 @@ static int aztcd_release(struct inode *inode, struct file *file)
return 0;
}
static struct gendisk azt_disk = {
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.fops = &azt_fops,
.disk_name = "aztcd"
};
static struct gendisk *azt_disk;
/*
* Test for presence of drive and initialize it. Called at boot time.
......@@ -1844,6 +1838,7 @@ static int __init aztcd_init(void)
for (count = 0; count < AZT_TIMEOUT;
count++)
barrier(); /* Stop gcc 2.96 being smart */
/* use udelay(), damnit -- AV */
if ((st = getAztStatus()) == -1) {
printk(KERN_WARNING "aztcd: Drive Status"
......@@ -1913,21 +1908,33 @@ static int __init aztcd_init(void)
}
devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
azt_disk = alloc_disk();
if (!azt_disk)
goto err_out2;
if (register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) {
printk(KERN_WARNING "aztcd: Unable to get major %d for Aztech"
" CD-ROM\n", MAJOR_NR);
ret = -EIO;
goto err_out;
goto err_out3;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_aztcd_request, &aztSpin);
blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), 2048);
add_disk(&azt_disk);
azt_disk->major = MAJOR_NR;
azt_disk->first_minor = 0;
azt_disk->minor_shift = 0;
azt_disk->fops = &azt_fops;
sprintf(azt_disk->disk_name, "aztcd");
add_disk(azt_disk);
azt_invalidate_buffers();
aztPresent = 1;
aztCloseDoor();
return (0);
err_out:
err_out3:
put_disk(azt_disk);
err_out2:
devfs_find_and_unregister(NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK, 0);
err_out:
if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
SWITCH_IDE_MASTER;
release_region(azt_port, 8); /*IDE-interface */
......@@ -1940,7 +1947,8 @@ static int __init aztcd_init(void)
static void __exit aztcd_exit(void)
{
devfs_find_and_unregister(NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK, 0);
del_gendisk(&azt_disk);
del_gendisk(azt_disk);
put_disk(azt_disk);
if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
printk("What's that: can't unregister aztcd\n");
return;
......
......@@ -3188,14 +3188,7 @@ static struct cdrom_device_info scd_info = {
.name = "cdu31a"
};
static struct gendisk scd_gendisk = {
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.disk_name = "cdu31a",
.fops = &scd_bdops,
.flags = GENHD_FL_CD,
};
static struct gendisk *scd_gendisk;
/* The different types of disc loading mechanisms supported */
static char *load_mech[] __initdata =
......@@ -3299,7 +3292,8 @@ __setup("cdu31a=", cdu31a_setup);
int __init cdu31a_init(void)
{
struct s_sony_drive_config drive_config;
struct gendisk *disk = &scd_gendisk;
struct gendisk *disk;
int deficiency = 0;
unsigned int res_size;
char msg[255];
char buf[40];
......@@ -3360,115 +3354,119 @@ int __init cdu31a_init(void)
}
}
if (drive_found) {
int deficiency = 0;
if (!drive_found)
goto errout3;
if (!request_region(cdu31a_port, 4, "cdu31a"))
goto errout3;
if (!request_region(cdu31a_port, 4, "cdu31a"))
goto errout3;
if (register_blkdev(MAJOR_NR, "cdu31a", &scd_bdops)) {
printk("Unable to get major %d for CDU-31a\n",
MAJOR_NR);
goto errout2;
}
if (register_blkdev(MAJOR_NR, "cdu31a", &scd_bdops)) {
printk("Unable to get major %d for CDU-31a\n",
MAJOR_NR);
goto errout2;
}
if (SONY_HWC_DOUBLE_SPEED(drive_config)) {
is_double_speed = 1;
}
disk = alloc_disk();
if (!disk)
goto errout1;
disk->major = MAJOR_NR;
disk->first_minor = 0;
disk->minor_shift = 0;
sprintf(disk->disk_name, "cdu31a");
disk->fops = &scd_bdops;
disk->flags = GENHD_FL_CD;
tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
cdu31a_irq = 0;
if (SONY_HWC_DOUBLE_SPEED(drive_config))
is_double_speed = 1;
set_drive_params(sony_speed);
tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
cdu31a_irq = 0;
cdu31a_irq = tmp_irq;
set_drive_params(sony_speed);
if (cdu31a_irq > 0) {
if (request_irq
(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
"cdu31a", NULL)) {
printk
("Unable to grab IRQ%d for the CDU31A driver\n",
cdu31a_irq);
cdu31a_irq = 0;
}
}
cdu31a_irq = tmp_irq;
sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
drive_config.vendor_id,
drive_config.product_id,
drive_config.product_rev_level);
sprintf(buf, " Capabilities: %s",
load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
strcat(msg, buf);
if (SONY_HWC_AUDIO_PLAYBACK(drive_config)) {
strcat(msg, ", audio");
} else
deficiency |= CDC_PLAY_AUDIO;
if (SONY_HWC_EJECT(drive_config)) {
strcat(msg, ", eject");
} else
deficiency |= CDC_OPEN_TRAY;
if (SONY_HWC_LED_SUPPORT(drive_config)) {
strcat(msg, ", LED");
}
if (SONY_HWC_ELECTRIC_VOLUME(drive_config)) {
strcat(msg, ", elec. Vol");
}
if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config)) {
strcat(msg, ", sep. Vol");
}
if (is_double_speed) {
strcat(msg, ", double speed");
} else
deficiency |= CDC_SELECT_SPEED;
if (cdu31a_irq > 0) {
sprintf(buf, ", irq %d", cdu31a_irq);
strcat(msg, buf);
if (cdu31a_irq > 0) {
if (request_irq
(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
"cdu31a", NULL)) {
printk
("Unable to grab IRQ%d for the CDU31A driver\n",
cdu31a_irq);
cdu31a_irq = 0;
}
strcat(msg, "\n");
}
is_a_cdu31a =
strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
drive_config.vendor_id,
drive_config.product_id,
drive_config.product_rev_level);
sprintf(buf, " Capabilities: %s",
load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
strcat(msg, buf);
if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
strcat(msg, ", audio");
else
deficiency |= CDC_PLAY_AUDIO;
if (SONY_HWC_EJECT(drive_config))
strcat(msg, ", eject");
else
deficiency |= CDC_OPEN_TRAY;
if (SONY_HWC_LED_SUPPORT(drive_config))
strcat(msg, ", LED");
if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
strcat(msg, ", elec. Vol");
if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
strcat(msg, ", sep. Vol");
if (is_double_speed)
strcat(msg, ", double speed");
else
deficiency |= CDC_SELECT_SPEED;
if (cdu31a_irq > 0) {
sprintf(buf, ", irq %d", cdu31a_irq);
strcat(msg, buf);
}
strcat(msg, "\n");
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR),
do_cdu31a_request,
&cdu31a_lock);
is_a_cdu31a =
strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
init_timer(&cdu31a_abort_timer);
cdu31a_abort_timer.function = handle_abort_timeout;
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR),
do_cdu31a_request,
&cdu31a_lock);
scd_info.dev = mk_kdev(MAJOR_NR, 0);
scd_info.mask = deficiency;
if (register_cdrom(&scd_info))
goto errout0;
add_disk(disk);
}
init_timer(&cdu31a_abort_timer);
cdu31a_abort_timer.function = handle_abort_timeout;
scd_info.dev = mk_kdev(MAJOR_NR, 0);
scd_info.mask = deficiency;
scd_gendisk = disk;
if (register_cdrom(&scd_info))
goto errout0;
add_disk(disk);
disk_changed = 1;
return (0);
if (drive_found) {
return (0);
} else {
goto errout3;
}
errout0:
errout0:
printk("Unable to register CDU-31a with Uniform cdrom driver\n");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
put_disk(disk);
errout1:
if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
printk("Can't unregister block device for cdu31a\n");
}
errout2:
errout2:
release_region(cdu31a_port, 4);
errout3:
errout3:
return -EIO;
}
void __exit cdu31a_exit(void)
{
del_gendisk(&scd_gendisk);
del_gendisk(scd_gendisk);
put_disk(scd_gendisk);
if (unregister_cdrom(&scd_info)) {
printk
("Can't unregister cdu31a from Uniform cdrom driver\n");
......
......@@ -1357,14 +1357,7 @@ static struct cdrom_device_info cm206_info = {
.name = "cm206",
};
static struct gendisk cm206_gendisk = {
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.disk_name = "cm206",
.fops = &cm206_bdops,
.flags = GENHD_FL_CD,
};
static struct gendisk *cm206_gendisk;
/* This function probes for the adapter card. It returns the base
address if it has found the adapter card. One can specify a base
......@@ -1419,7 +1412,7 @@ int __init cm206_init(void)
{
uch e = 0;
long int size = sizeof(struct cm206_struct);
struct gendisk *disk = &cm206_gendisk;
struct gendisk *disk;
printk(KERN_INFO "cm206 cdrom driver " REVISION);
cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
......@@ -1477,6 +1470,16 @@ int __init cm206_init(void)
printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR);
goto out_blkdev;
}
disk = alloc_disk();
if (!disk)
goto out_disk;
disk->major = MAJOR_NR;
disk->first_minor = 0;
disk->minor_shift = 0;
sprintf(disk->disk_name, "cm206");
disk->fops = &cm206_bdops;
disk->flags = GENHD_FL_CD;
cm206_gendisk = disk;
cm206_info.dev = mk_kdev(MAJOR_NR, 0);
if (register_cdrom(&cm206_info) != 0) {
printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
......@@ -1498,6 +1501,8 @@ int __init cm206_init(void)
return 0;
out_cdrom:
put_disk(disk);
out_disk:
unregister_blkdev(MAJOR_NR, "cm206");
out_blkdev:
free_irq(cm206_irq, NULL);
......@@ -1536,7 +1541,8 @@ int __cm206_init(void)
void __exit cm206_exit(void)
{
del_gendisk(&cm206_gendisk);
del_gendisk(cm206_gendisk);
put_disk(cm206_gendisk);
if (unregister_cdrom(&cm206_info)) {
printk("Can't unregister cdrom cm206\n");
return;
......
......@@ -898,20 +898,15 @@ static void update_state(void)
}
#endif
static struct gendisk gscd_disk = {
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.fops = &gscd_fops,
.disk_name = "gscd"
};
static struct gendisk *gscd_disk;
static void __exit gscd_exit(void)
{
CLEAR_TIMER;
devfs_find_and_unregister(NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0);
del_gendisk(&gscd_disk);
del_gendisk(gscd_disk);
put_disk(gscd_disk);
if ((unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
printk("What's that: can't unregister GoldStar-module\n");
return;
......@@ -977,11 +972,20 @@ static int __init gscd_init(void)
i++;
}
gscd_disk = alloc_disk();
if (!gscd_disk)
goto err_out1;
gscd_disk->major = MAJOR_NR;
gscd_disk->first_minor = 0;
gscd_disk->minor_shift = 0;
gscd_disk->fops = &gscd_fops;
sprintf(gscd_disk->disk_name, "gscd");
if (register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) {
printk(KERN_WARNING "GSCD: Unable to get major %d for GoldStar "
"CD-ROM\n", MAJOR_NR);
ret = -EIO;
goto err_out1;
goto err_out2;
}
devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
......@@ -991,10 +995,13 @@ static int __init gscd_init(void)
disk_state = 0;
gscdPresent = 1;
add_disk(&gscd_disk);
add_disk(gscd_disk);
printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
return 0;
err_out2:
put_disk(gscd_disk);
err_out1:
release_region(gscd_port, GSCD_IO_EXTENT);
return ret;
......
......@@ -221,14 +221,7 @@ static struct cdrom_device_info mcd_info = {
.name = "mcd",
};
static struct gendisk mcd_gendisk = {
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.disk_name = "mcd",
.fops = &mcd_bdops,
.flags = GENHD_FL_CD,
};
static struct gendisk *mcd_gendisk;
#ifndef MODULE
static int __init mcd_setup(char *str)
......@@ -1038,18 +1031,23 @@ static void mcd_release(struct cdrom_device_info *cdi)
int __init mcd_init(void)
{
struct gendisk *disk = &mcd_gendisk;
struct gendisk *disk = alloc_disk();
int count;
unsigned char result[3];
char msg[80];
if (!disk) {
printk(KERN_INFO "mcd: can't allocated disk.\n");
return -ENOMEM;
}
if (mcd_port <= 0 || mcd_irq <= 0) {
printk(KERN_INFO "mcd: not probing.\n");
put_disk(disk);
return -EIO;
}
if (register_blkdev(MAJOR_NR, "mcd", &mcd_bdops) != 0) {
printk(KERN_ERR "mcd: Unable to get major %d for Mitsumi CD-ROM\n", MAJOR_NR);
put_disk(disk);
return -EIO;
}
if (!request_region(mcd_port, 4, "mcd")) {
......@@ -1124,6 +1122,13 @@ int __init mcd_init(void)
mcd_invalidate_buffers();
mcdPresent = 1;
disk->major = MAJOR_NR;
disk->first_minor = 0;
disk->minor_shift = 0;
sprintf(disk->disk_name, "mcd");
disk->fops = &mcd_bdops;
disk->flags = GENHD_FL_CD;
mcd_gendisk = disk;
mcd_info.dev = mk_kdev(MAJOR_NR, 0);
if (register_cdrom(&mcd_info) != 0) {
......@@ -1141,6 +1146,7 @@ int __init mcd_init(void)
out_region:
unregister_blkdev(MAJOR_NR, "mcd");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
put_disk(disk);
return -EIO;
}
......@@ -1506,7 +1512,8 @@ static int GetToc(void)
void __exit mcd_exit(void)
{
del_gendisk(&mcd_gendisk);
del_gendisk(mcd_gendisk);
put_disk(mcd_gendisk);
if (unregister_cdrom(&mcd_info)) {
printk(KERN_WARNING "Can't unregister cdrom mcd\n");
return;
......
......@@ -206,7 +206,7 @@ struct s_drive_stuff {
int status; /* last operation's error / status */
int readerrs; /* # of blocks read w/o error */
struct cdrom_device_info info;
struct gendisk disk;
struct gendisk *disk;
};
......@@ -1021,11 +1021,12 @@ void __exit mcdx_exit(void)
struct s_drive_stuff *stuffp = mcdx_stuffp[i];
if (!stuffp)
continue;
del_gendisk(&stuffp->disk);
del_gendisk(stuffp->disk);
if (unregister_cdrom(&stuffp->info)) {
printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
return;
continue;
}
put_disk(stuffp->disk);
release_region((unsigned long) stuffp->wreg_data,
MCDX_IO_SIZE);
free_irq(stuffp->irq, NULL);
......@@ -1075,6 +1076,13 @@ int __init mcdx_init_drive(int drive)
return 1;
}
disk = alloc_disk();
if (!disk) {
xwarn("init() malloc failed\n");
kfree(stuffp);
return 1;
}
xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
sizeof(*stuffp), stuffp);
......@@ -1106,6 +1114,7 @@ int __init mcdx_init_drive(int drive)
stuffp->wreg_data + MCDX_IO_SIZE - 1);
xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
kfree(stuffp);
put_disk(disk);
xtrace(INIT, "init() continue at next drive\n");
return 0; /* next drive */
}
......@@ -1124,6 +1133,7 @@ int __init mcdx_init_drive(int drive)
MCDX, stuffp->wreg_data, stuffp->irq);
xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
kfree(stuffp);
put_disk(disk);
xtrace(INIT, "init() continue at next drive\n");
return 0;
}
......@@ -1154,6 +1164,7 @@ int __init mcdx_init_drive(int drive)
xwarn("%s=0x%3p,%d: Init failed. No Mitsumi CD-ROM?.\n",
MCDX, stuffp->wreg_data, stuffp->irq);
kfree(stuffp);
put_disk(disk);
return 0; /* next drive */
}
......@@ -1164,6 +1175,7 @@ int __init mcdx_init_drive(int drive)
xwarn("%s=0x%3p,%d: Init failed. Can't get major %d.\n",
MCDX, stuffp->wreg_data, stuffp->irq, MAJOR_NR);
kfree(stuffp);
put_disk(disk);
return 1;
}
......@@ -1180,6 +1192,7 @@ int __init mcdx_init_drive(int drive)
stuffp->irq = 0;
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
kfree(stuffp);
put_disk(disk);
return 0;
}
......@@ -1206,13 +1219,13 @@ int __init mcdx_init_drive(int drive)
stuffp->info.handle = stuffp;
sprintf(stuffp->info.name, "mcdx%d", drive);
stuffp->info.dev = mk_kdev(MAJOR_NR, drive);
disk = &stuffp->disk;
disk->major = MAJOR_NR;
disk->first_minor = drive;
disk->minor_shift = 0;
strcpy(disk->disk_name, stuffp->info.name);
disk->fops = &mcdx_bdops;
disk->flags = GENHD_FL_CD;
stuffp->disk = disk;
sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%3p, irq %d."
" (Firmware version %c %x)\n",
......@@ -1225,6 +1238,7 @@ int __init mcdx_init_drive(int drive)
MCDX_IO_SIZE);
free_irq(stuffp->irq, NULL);
kfree(stuffp);
put_disk(disk);
if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
xwarn("cleanup() unregister_blkdev() failed\n");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
......
......@@ -1997,13 +1997,7 @@ __setup("optcd=", optcd_setup);
#endif /* MODULE */
static struct gendisk optcd_disk = {
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.fops = &opt_fops,
.disk_name = "optcd"
};
static struct gendisk *optcd_disk;
/* Test for presence of drive and initialize it. Called at boot time
or during module initialisation. */
......@@ -2016,20 +2010,33 @@ static int __init optcd_init(void)
"optcd: no Optics Storage CDROM Initialization\n");
return -EIO;
}
optcd_disk = alloc_disk();
if (!optcd_disk) {
printk(KERN_ERR "optcd: can't allocate disk\n");
return -ENOMEM;
}
optcd_disk->major = MAJOR_NR;
optcd_disk->first_minor = 0;
optcd_disk->minor_shift = 0;
optcd_disk->fops = &opt_fops;
sprintf(optcd_disk->disk_name, "optcd");
if (!request_region(optcd_port, 4, "optcd")) {
printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
optcd_port);
put_disk(optcd_disk);
return -EIO;
}
if (!reset_drive()) {
printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
release_region(optcd_port, 4);
put_disk(optcd_disk);
return -EIO;
}
if (!version_ok()) {
printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
release_region(optcd_port, 4);
put_disk(optcd_disk);
return -EIO;
}
status = exec_cmd(COMINITDOUBLE);
......@@ -2037,11 +2044,13 @@ static int __init optcd_init(void)
printk(KERN_ERR "optcd: cannot init double speed mode\n");
release_region(optcd_port, 4);
DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
put_disk(optcd_disk);
return -EIO;
}
if (register_blkdev(MAJOR_NR, "optcd", &opt_fops) != 0) {
printk(KERN_ERR "optcd: unable to get major %d\n", MAJOR_NR);
release_region(optcd_port, 4);
put_disk(optcd_disk);
return -EIO;
}
devfs_register (NULL, "optcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
......@@ -2049,7 +2058,7 @@ static int __init optcd_init(void)
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_optcd_request,
&optcd_lock);
blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), 2048);
add_disk(&optcd_disk);
add_disk(optcd_disk);
printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
return 0;
......@@ -2059,7 +2068,8 @@ static int __init optcd_init(void)
static void __exit optcd_exit(void)
{
devfs_find_and_unregister(NULL, "optcd", 0, 0, DEVFS_SPECIAL_BLK, 0);
del_gendisk(&optcd_disk);
del_gendisk(optcd_disk);
put_disk(optcd_disk);
if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) {
printk(KERN_ERR "optcd: what's that: can't unregister\n");
return;
......
......@@ -722,7 +722,7 @@ static struct sbpcd_drive {
u_char mode_xb_8;
u_char delay;
struct cdrom_device_info *sbpcd_infop;
struct gendisk disk;
struct gendisk *disk;
} D_S[NR_SBPCD];
static struct sbpcd_drive *current_drive = D_S;
......@@ -5609,6 +5609,7 @@ static int __init config_spea(void)
static devfs_handle_t devfs_handle;
/* FIXME: cleanups after failed allocations are too ugly for words */
#ifdef MODULE
int __init __sbpcd_init(void)
#else
......@@ -5830,7 +5831,7 @@ int __init sbpcd_init(void)
sbpcd_infop->dev = mk_kdev(MAJOR_NR, j);
sbpcd_infop->handle = p;
p->sbpcd_infop = sbpcd_infop;
disk = &p->disk;
disk = alloc_disk();
disk->major = MAJOR_NR;
disk->first_minor = j;
disk->minor_shift = 0;
......@@ -5839,6 +5840,7 @@ int __init sbpcd_init(void)
disk->flags = GENHD_FL_CD;
sprintf(nbuff, "c0t%d", p->drv_id);
disk->de = devfs_mk_dir(devfs_handle, nbuff, NULL);
p->disk = disk;
if (register_cdrom(sbpcd_infop))
{
printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n");
......@@ -5869,7 +5871,8 @@ void sbpcd_exit(void)
for (j=0;j<NR_SBPCD;j++)
{
if (D_S[j].drv_id==-1) continue;
del_gendisk(&D_S[j].disk);
del_gendisk(D_S[j].disk);
put_disk(D_S[j].disk);
vfree(D_S[j].sbp_buf);
if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
devfs_unregister(D_S[j].disk.de);
......
......@@ -159,8 +159,6 @@ static struct timer_list sjcd_delay_timer;
#define CLEAR_TIMER del_timer( &sjcd_delay_timer )
static int sjcd_cleanup(void);
/*
* Set up device, i.e., use command line data to set
* base address.
......@@ -1664,14 +1662,7 @@ static struct {
unsigned char major, minor;
} sjcd_version;
static struct gendisk sjcd_disk =
{
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.fops = &sjcd_fops,
.disk_name = "sjcd"
};
static struct gendisk *sjcd_disk;
/*
* Test for presence of drive and initialize it. Called at boot time.
......@@ -1698,12 +1689,22 @@ static int __init sjcd_init(void)
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_sjcd_request, &sjcd_lock);
blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), 2048);
sjcd_disk = alloc_disk();
if (!sjcd_disk) {
printk(KERN_ERR "SJCD: can't allocate disk");
goto out1;
}
sjcd_disk->major = MAJOR_NR,
sjcd_disk->first_minor = 0,
sjcd_disk->minor_shift = 0,
sjcd_disk->fops = &sjcd_fops,
sprintf(sjcd_disk->disk_name, "sjcd");
if (check_region(sjcd_base, 4)) {
printk
("SJCD: Init failed, I/O port (%X) is already in use\n",
sjcd_base);
sjcd_cleanup();
return (-EIO);
goto out2;
}
/*
......@@ -1725,8 +1726,7 @@ static int __init sjcd_init(void)
}
if (i == 0 || sjcd_command_failed) {
printk(" reset failed, no drive found.\n");
sjcd_cleanup();
return (-EIO);
goto out3;
} else
printk("\n");
......@@ -1748,8 +1748,7 @@ static int __init sjcd_init(void)
}
if (i == 0 || sjcd_command_failed) {
printk(" get version failed, no drive found.\n");
sjcd_cleanup();
return (-EIO);
goto out3;
}
if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
......@@ -1757,8 +1756,7 @@ static int __init sjcd_init(void)
(int) sjcd_version.minor);
} else {
printk(" read version failed, no drive found.\n");
sjcd_cleanup();
return (-EIO);
goto out3;
}
/*
......@@ -1781,8 +1779,7 @@ static int __init sjcd_init(void)
}
if (i == 0 || sjcd_command_failed) {
printk(" get status failed, no drive found.\n");
sjcd_cleanup();
return (-EIO);
goto out3;
} else
printk("\n");
}
......@@ -1790,33 +1787,32 @@ static int __init sjcd_init(void)
printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
devfs_register(NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
add_disk(&sjcd_disk);
add_disk(sjcd_disk);
sjcd_present++;
return (0);
}
static int sjcd_cleanup(void)
{
out3:
release_region(sjcd_base, 4);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
out2:
put_disk(sjcd_disk);
out1:
if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
printk("SJCD: cannot unregister device.\n");
else {
release_region(sjcd_base, 4);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
}
return (0);
return (-EIO);
}
static void __exit sjcd_exit(void)
{
devfs_find_and_unregister(NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK, 0);
del_gendisk(&sjcd_disk);
if (sjcd_cleanup())
printk("SJCD: module: cannot be removed.\n");
else
printk(KERN_INFO "SJCD: module: removed.\n");
del_gendisk(sjcd_disk);
put_disk(sjcd_disk);
release_region(sjcd_base, 4);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
printk("SJCD: cannot unregister device.\n");
printk(KERN_INFO "SJCD: module: removed.\n");
return (0);
}
module_init(sjcd_init);
......
......@@ -1454,14 +1454,7 @@ static struct block_device_operations cdu_fops =
.check_media_change = cdu535_check_media_change,
};
static struct gendisk cdu_disk =
{
.major = MAJOR_NR,
.first_minor = 0,
.minor_shift = 0,
.fops = &cdu_fops,
.disk_name = "cdu",
};
static struct gendisk *cdu_disk;
/*
* Initialize the driver.
......@@ -1477,6 +1470,7 @@ static int __init sony535_init(void)
int tmp_irq;
int i;
devfs_handle_t sony_devfs_handle;
int err;
/* Setting the base I/O address to 0 will disable it. */
if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0))
......@@ -1518,145 +1512,142 @@ static int __init sony535_init(void)
sony_sleep();
}
if (got_result && (check_drive_status() != TIME_OUT)) {
/* CD-ROM drive responded -- get the drive configuration */
cmd_buff[0] = SONY535_INQUIRY;
if (do_sony_cmd(cmd_buff, 1, status,
(Byte *)&drive_config, 28, 1) == 0) {
/* was able to get the configuration,
* set drive mode as rest of init
*/
if (!got_result || check_drive_status() == TIME_OUT)
goto Enodev;
/* CD-ROM drive responded -- get the drive configuration */
cmd_buff[0] = SONY535_INQUIRY;
if (do_sony_cmd(cmd_buff, 1, status, (Byte *)&drive_config, 28, 1) != 0)
goto Enodev;
/* was able to get the configuration,
* set drive mode as rest of init
*/
#if DEBUG > 0
/* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
printk(CDU535_MESSAGE_NAME
"Inquiry command returned status = 0x%x\n", status[0]);
/* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
printk(CDU535_MESSAGE_NAME
"Inquiry command returned status = 0x%x\n", status[0]);
#endif
/* now ready to use interrupts, if available */
sony535_irq_used = tmp_irq;
/* now ready to use interrupts, if available */
sony535_irq_used = tmp_irq;
/* A negative sony535_irq_used will attempt an autoirq. */
if (sony535_irq_used < 0) {
unsigned long irq_mask, delay;
/* A negative sony535_irq_used will attempt an autoirq. */
if (sony535_irq_used < 0) {
unsigned long irq_mask, delay;
irq_mask = probe_irq_on();
enable_interrupts();
outb(0, read_status_reg); /* does a reset? */
delay = jiffies + HZ/10;
while (time_before(jiffies, delay)) ;
irq_mask = probe_irq_on();
enable_interrupts();
outb(0, read_status_reg); /* does a reset? */
delay = jiffies + HZ/10;
while (time_before(jiffies, delay)) ;
sony535_irq_used = probe_irq_off(irq_mask);
disable_interrupts();
}
if (sony535_irq_used > 0) {
if (request_irq(sony535_irq_used, cdu535_interrupt,
SA_INTERRUPT, CDU535_HANDLE, NULL)) {
printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
" driver; polling instead.\n", sony535_irq_used);
sony535_irq_used = 0;
}
}
cmd_buff[0] = SONY535_SET_DRIVE_MODE;
cmd_buff[1] = 0x0; /* default audio */
if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) == 0) {
/* set the drive mode successful, we are set! */
sony_buffer_size = SONY535_BUFFER_SIZE;
sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
drive_config.vendor_id,
drive_config.product_id,
drive_config.product_rev_level);
printk(" base address %03X, ", sony535_cd_base_io);
if (tmp_irq > 0)
printk("IRQ%d, ", tmp_irq);
printk("using %d byte buffer\n", sony_buffer_size);
sony_devfs_handle = devfs_register (NULL, CDU535_HANDLE,
DEVFS_FL_DEFAULT,
MAJOR_NR, 0,
S_IFBLK | S_IRUGO | S_IWUGO,
&cdu_fops, NULL);
if (register_blkdev(MAJOR_NR, CDU535_HANDLE, &cdu_fops)) {
printk("Unable to get major %d for %s\n",
MAJOR_NR, CDU535_MESSAGE_NAME);
return -EIO;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR),
do_cdu535_request,
&sonycd535_lock);
blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), CDU535_BLOCK_SIZE);
sony_toc = (struct s535_sony_toc *)
kmalloc(sizeof *sony_toc, GFP_KERNEL);
if (sony_toc == NULL) {
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
devfs_unregister(sony_devfs_handle);
return -ENOMEM;
}
last_sony_subcode = (struct s535_sony_subcode *)
kmalloc(sizeof *last_sony_subcode, GFP_KERNEL);
if (last_sony_subcode == NULL) {
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
kfree(sony_toc);
unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
devfs_unregister(sony_devfs_handle);
return -ENOMEM;
}
sony_buffer = (Byte **)
kmalloc(4 * sony_buffer_sectors, GFP_KERNEL);
if (sony_buffer == NULL) {
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
kfree(sony_toc);
kfree(last_sony_subcode);
unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
devfs_unregister(sony_devfs_handle);
return -ENOMEM;
}
for (i = 0; i < sony_buffer_sectors; i++) {
sony_buffer[i] =
(Byte *)kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
if (sony_buffer[i] == NULL) {
while (--i>=0)
kfree(sony_buffer[i]);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
kfree(sony_buffer);
kfree(sony_toc);
kfree(last_sony_subcode);
unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
devfs_unregister(sony_devfs_handle);
return -ENOMEM;
}
}
initialized = 1;
}
sony535_irq_used = probe_irq_off(irq_mask);
disable_interrupts();
}
if (sony535_irq_used > 0) {
if (request_irq(sony535_irq_used, cdu535_interrupt,
SA_INTERRUPT, CDU535_HANDLE, NULL)) {
printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
" driver; polling instead.\n", sony535_irq_used);
sony535_irq_used = 0;
}
}
if (!initialized) {
printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
return -EIO;
cmd_buff[0] = SONY535_SET_DRIVE_MODE;
cmd_buff[1] = 0x0; /* default audio */
if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) != 0)
goto Enodev_irq;
/* set the drive mode successful, we are set! */
sony_buffer_size = SONY535_BUFFER_SIZE;
sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
drive_config.vendor_id,
drive_config.product_id,
drive_config.product_rev_level);
printk(" base address %03X, ", sony535_cd_base_io);
if (tmp_irq > 0)
printk("IRQ%d, ", tmp_irq);
printk("using %d byte buffer\n", sony_buffer_size);
sony_devfs_handle = devfs_register (NULL, CDU535_HANDLE,
DEVFS_FL_DEFAULT,
MAJOR_NR, 0,
S_IFBLK | S_IRUGO | S_IWUGO,
&cdu_fops, NULL);
if (register_blkdev(MAJOR_NR, CDU535_HANDLE, &cdu_fops)) {
printk("Unable to get major %d for %s\n",
MAJOR_NR, CDU535_MESSAGE_NAME);
err = -EIO;
goto out1;
}
if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE))
{
printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
sony535_cd_base_io);
for (i = 0; i < sony_buffer_sectors; i++)
if (sony_buffer[i])
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_cdu535_request,
&sonycd535_lock);
blk_queue_hardsect_size(BLK_DEFAULT_QUEUE(MAJOR_NR), CDU535_BLOCK_SIZE);
sony_toc = kamlloc(sizeof(struct s535_sony_toc), GFP_KERNEL);
err = -ENOMEM;
if (!sony_toc)
goto out2;
last_sony_subcode = kmalloc(sizeof(struct s535_sony_subcode), GFP_KERNEL);
if (!last_sony_subcode)
goto out3;
sony_buffer = kmalloc(sizeof(Byte *) * sony_buffer_sectors, GFP_KERNEL);
if (!sony_buffer)
goto out4;
for (i = 0; i < sony_buffer_sectors; i++) {
sony_buffer[i] = kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
if (!sony_buffer[i]) {
while (--i>=0)
kfree(sony_buffer[i]);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
kfree(sony_buffer);
kfree(sony_toc);
kfree(last_sony_subcode);
unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
devfs_unregister(sony_devfs_handle);
if (sony535_irq_used)
free_irq(sony535_irq_used, NULL);
return -EIO;
goto out5;
}
add_disk(&cdu_disk);
}
initialized = 1;
cdu_disk = alloc_disk();
if (!cdu_disk)
goto out6;
cdu_disk->major = MAJOR_NR;
cdu_disk->first_minor = 0;
cdu_disk->minor_shift = 0;
cdu_disk->fops = &cdu_fops;
sprintf(cdu_disk->disk_name, "cdu");
if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
sony535_cd_base_io);
goto out7;
}
add_disk(cdu_disk);
return 0;
out7:
put_disk(cdu_disk);
out6:
for (i = 0; i < sony_buffer_sectors; i++)
if (sony_buffer[i])
kfree(sony_buffer[i]);
out5:
kfree(sony_buffer);
out4:
kfree(last_sony_subcode);
out3:
kfree(sony_toc);
out2:
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
out1:
devfs_unregister(sony_devfs_handle);
if (sony535_irq_used)
free_irq(sony535_irq_used, NULL);
return err;
Enodev_irq:
if (sony535_irq_used)
free_irq(sony535_irq_used, NULL);
Enodev:
printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
return -EIO;
}
#ifndef MODULE
......@@ -1707,7 +1698,8 @@ static sony535_exit(void)
kfree(sony_toc);
devfs_find_and_unregister(NULL, CDU535_HANDLE, 0, 0,
DEVFS_SPECIAL_BLK, 0);
del_gendisk(&cdu_disk);
del_gendisk(cdu_disk);
put_disk(cdu_disk);
if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
else
......
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