summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorDave Jones <davej@suse.de>2002-05-30 20:44:01 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-05-30 20:44:01 -0700
commit4fbfba2c66fb78b3d476ba628ab21a0443e48369 (patch)
tree276cbd30610779361f541043ec41c7e8a1da80bf /drivers/block
parent5c2219ce7e848e666f6547edb4aba969f6f2f584 (diff)
[PATCH] ps2esdi resource cleanups
checks return codes, and sanitises resource allocation.
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/ps2esdi.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index aa701c81b474..18a3ac58f87d 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -69,7 +69,7 @@ static void reset_ctrl(void);
int ps2esdi_init(void);
-static void ps2esdi_geninit(void);
+static int ps2esdi_geninit(void);
static void do_ps2esdi_request(request_queue_t * q);
@@ -168,6 +168,8 @@ static struct gendisk ps2esdi_gendisk =
int __init ps2esdi_init(void)
{
+ int error = 0;
+
/* register the device - pass the name, major number and operations
vector . */
if (devfs_register_blkdev(MAJOR_NR, "ed", &ps2esdi_fops)) {
@@ -180,7 +182,16 @@ int __init ps2esdi_init(void)
/* some minor housekeeping - setup the global gendisk structure */
add_gendisk(&ps2esdi_gendisk);
- ps2esdi_geninit();
+ error = ps2esdi_geninit();
+ if (error) {
+ printk(KERN_WARNING "PS2ESDI: error initialising"
+ " device, releasing resources\n");
+ devfs_unregister_blkdev(MAJOR_NR, "ed");
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ del_gendisk(&ps2esdi_gendisk);
+ blk_clear(MAJOR_NR);
+ return error;
+ }
return 0;
} /* ps2esdi_init */
@@ -225,7 +236,7 @@ cleanup_module(void) {
}
release_region(io_base, 4);
free_dma(dma_arb_level);
- free_irq(PS2ESDI_IRQ, NULL);
+ free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
devfs_unregister_blkdev(MAJOR_NR, "ed");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
del_gendisk(&ps2esdi_gendisk);
@@ -289,7 +300,7 @@ static int ps2esdi_getinfo(char *buf, int slot, void *d)
}
/* ps2 esdi specific initialization - called thru the gendisk chain */
-static void __init ps2esdi_geninit(void)
+static int __init ps2esdi_geninit(void)
{
/*
The first part contains the initialization code
@@ -307,6 +318,7 @@ static void __init ps2esdi_geninit(void)
int slot = 0, i, reset_start, reset_end;
u_char status;
unsigned short adapterID;
+ int error = 0;
if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) {
adapterID = INTG_ESDI_ID;
@@ -321,7 +333,7 @@ static void __init ps2esdi_geninit(void)
DEVICE_NAME, slot+1);
mca_set_adapter_name(slot, "PS/2 ESDI");
} else {
- return;
+ return -ENODEV;
}
ps2esdi_slot = slot;
@@ -347,7 +359,8 @@ static void __init ps2esdi_geninit(void)
/* is it enabled ? */
if (!(status & STATUS_ENABLED)) {
printk("%s: ESDI adapter disabled\n", DEVICE_NAME);
- return;
+ error = -ENODEV;
+ goto err_out1;
}
/* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
share with the SCSI driver */
@@ -357,7 +370,8 @@ static void __init ps2esdi_geninit(void)
SA_SHIRQ, "PS/2 ESDI", &ps2esdi_gendisk)
) {
printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
- return;
+ error = -EBUSY;
+ goto err_out1;
}
if (status & STATUS_ALTERNATE)
io_base = ALT_IO_BASE;
@@ -366,8 +380,8 @@ static void __init ps2esdi_geninit(void)
if (!request_region(io_base, 4, "ed")) {
printk(KERN_WARNING"Unable to request region 0x%x\n", io_base);
- free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
- return;
+ error = -EBUSY;
+ goto err_out2;
}
/* get the dma arbitration level */
dma_arb_level = (status >> 2) & 0xf;
@@ -417,8 +431,12 @@ static void __init ps2esdi_geninit(void)
ps2esdi_gendisk.nr_real = ps2esdi_drives;
- request_dma(dma_arb_level, "ed");
-
+ if (request_dma(dma_arb_level, "ed") !=0) {
+ printk(KERN_WARNING "PS2ESDI: Can't request dma-channel %d\n"
+ ,(int) dma_arb_level);
+ error = -EBUSY;
+ goto err_out3;
+ }
blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 128);
for (i = 0; i < ps2esdi_drives; i++) {
@@ -428,6 +446,18 @@ static void __init ps2esdi_geninit(void)
ps2esdi_info[i].cyl);
ps2esdi_valid[i] = 1;
}
+ return 0;
+
+err_out3:
+ release_region(io_base, 4);
+err_out2:
+ free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
+err_out1:
+ if(ps2esdi_slot) {
+ mca_mark_as_unused(ps2esdi_slot);
+ mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
+ }
+ return error;
}
static void __init ps2esdi_get_device_cfg(void)