From: viro@parcelfarce.linux.theplanet.co.uk check_region() fixes. --- 25-akpm/drivers/cdrom/cdu31a.c | 71 ++++++++++++++++------------------------- 1 files changed, 29 insertions(+), 42 deletions(-) diff -puN drivers/cdrom/cdu31a.c~cdu31c-check_region-fix-2 drivers/cdrom/cdu31a.c --- 25/drivers/cdrom/cdu31a.c~cdu31c-check_region-fix-2 Fri Mar 12 14:02:36 2004 +++ 25-akpm/drivers/cdrom/cdu31a.c Fri Mar 12 14:02:36 2004 @@ -3203,13 +3203,16 @@ static struct gendisk *scd_gendisk; static char *load_mech[] __initdata = { "caddy", "tray", "pop-up", "unknown" }; -static void __init +static int __init get_drive_configuration(unsigned short base_io, unsigned char res_reg[], unsigned int *res_size) { unsigned long retry_count; + if (!request_region(base_io, 4, "cdu31a")) + return 0; + /* Set the base address */ cdu31a_port = base_io; @@ -3244,7 +3247,7 @@ get_drive_configuration(unsigned short b /* If attention is never seen probably not a CDU31a present */ if (!is_attention()) { res_reg[0] = 0x20; - return; + goto out_err; } #endif @@ -3254,11 +3257,17 @@ get_drive_configuration(unsigned short b do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD, NULL, 0, (unsigned char *) res_reg, res_size); - return; + if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0) + goto out_err; + return 1; } /* Return an error */ res_reg[0] = 0x20; +out_err: + release_region(cdu31a_port, 4); + cdu31a_port = 0; + return 0; } #ifndef MODULE @@ -3307,9 +3316,6 @@ int __init cdu31a_init(void) char msg[255]; char buf[40]; int i; - int drive_found; - int tmp_irq; - /* * According to Alex Freed (freed@europa.orion.adobe.com), this is @@ -3323,52 +3329,33 @@ int __init cdu31a_init(void) outb(0xe2, 0x9a01); } - drive_found = 0; - /* Setting the base I/O address to 0xffff will disable it. */ - if (cdu31a_port == 0xffff) { - } else if (cdu31a_port != 0) { - tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */ - cdu31a_irq = 0; - - get_drive_configuration(cdu31a_port, - drive_config.exec_status, - &res_size); - if ((res_size > 2) - && ((drive_config.exec_status[0] & 0xf0) == 0x00)) { - drive_found = 1; - } + if (cdu31a_port == 0xffff) + goto errout3; + if (cdu31a_port != 0) { + /* Need IRQ 0 because we can't sleep here. */ + int tmp_irq = cdu31a_irq; + cdu31a_irq = 0; + if (!get_drive_configuration(cdu31a_port, + drive_config.exec_status, + &res_size)) + goto errout3; cdu31a_irq = tmp_irq; } else { cdu31a_irq = 0; - i = 0; - while ((cdu31a_addresses[i].base != 0) - && (!drive_found)) { - if (check_region(cdu31a_addresses[i].base, 4)) { - i++; - continue; - } - get_drive_configuration(cdu31a_addresses[i].base, - drive_config.exec_status, - &res_size); - if ((res_size > 2) - && ((drive_config.exec_status[0] & 0xf0) == - 0x00)) { - drive_found = 1; + for (i = 0; cdu31a_addresses[i].base; i++) { + if (get_drive_configuration(cdu31a_addresses[i].base, + drive_config.exec_status, + &res_size)) { cdu31a_irq = cdu31a_addresses[i].int_num; - } else { - i++; + break; } } + if (!cdu31a_port) + goto errout3; } - if (!drive_found) - goto errout3; - - if (!request_region(cdu31a_port, 4, "cdu31a")) - goto errout3; - if (register_blkdev(MAJOR_NR, "cdu31a")) goto errout2; _