From e941b34947b6344f25f21e329f356412d9880e45 Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 4 Jun 2006 10:01:33 +0000 Subject: [PATCH] Fixed an error in the load routine: The driver was not removed from memory when the install routine failed. git-svn-id: svn://svn.cc65.org/cc65/trunk@3750 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- asminc/ser-kernel.inc | 11 ++++++----- libsrc/serial/ser-kernel.s | 1 + libsrc/serial/ser_load.c | 35 ++++++++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/asminc/ser-kernel.inc b/asminc/ser-kernel.inc index debae78fc..5d448775f 100644 --- a/asminc/ser-kernel.inc +++ b/asminc/ser-kernel.inc @@ -6,10 +6,10 @@ ;* * ;* * ;* * -;*(C) 2003 Ullrich von Bassewitz * -;* Römerstrasse 52 * -;* D-70794 Filderstadt * -;*EMail: uz@cc65.org * +;*(C) 2003-2006, Ullrich von Bassewitz * +;* Römerstrasse 52 * +;* D-70794 Filderstadt * +;*EMail: uz@cc65.org * ;* * ;* * ;*This software is provided 'as-is', without any expressed or implied * @@ -142,7 +142,7 @@ SER_STATUS_DSR = $40 ; NOT data set ready .global ser_irq ;------------------------------------------------------------------------------ -; ASM functions +; C callable functions .global _ser_unload .global _ser_install @@ -154,4 +154,5 @@ SER_STATUS_DSR = $40 ; NOT data set ready .global _ser_status .global _ser_ioctl + .global _ser_clear_ptr diff --git a/libsrc/serial/ser-kernel.s b/libsrc/serial/ser-kernel.s index 0bd494459..d666e9452 100644 --- a/libsrc/serial/ser-kernel.s +++ b/libsrc/serial/ser-kernel.s @@ -103,6 +103,7 @@ _ser_uninstall: lda #$60 ; RTS opcode sta ser_irq ; Disable IRQ entry point +_ser_clear_ptr: ; External entry point lda #0 sta _ser_drv sta _ser_drv+1 ; Clear the driver pointer diff --git a/libsrc/serial/ser_load.c b/libsrc/serial/ser_load.c index 2673b21de..11ca23a27 100644 --- a/libsrc/serial/ser_load.c +++ b/libsrc/serial/ser_load.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2003-2006, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -50,6 +50,9 @@ /* Pointer to serial driver, exported from ser-kernel.s */ extern void* ser_drv; +/* Function that clears the driver pointer (ser-kernel.s) */ +void ser_clear_ptr (void); + /*****************************************************************************/ @@ -58,6 +61,11 @@ extern void* ser_drv; +/* Use static local variables, since the module is not reentrant anyway */ +#pragma staticlocals (on); + + + unsigned char __fastcall__ ser_load_driver (const char* name) /* Load a serial driver and return an error code */ { @@ -77,7 +85,7 @@ unsigned char __fastcall__ ser_load_driver (const char* name) /* Load the module */ Res = mod_load (&ctrl); - + /* Close the input file */ close (ctrl.callerdata); @@ -85,8 +93,21 @@ unsigned char __fastcall__ ser_load_driver (const char* name) if (Res == MLOAD_OK) { /* Check the driver signature, install the driver */ - return ser_install (ctrl.module); - + Res = ser_install (ctrl.module); + + /* If the driver did not install correctly, remove it from + * memory again. + */ + if (Res != SER_ERR_OK) { + /* Do not call ser_uninstall here, since the driver is not + * correctly installed. + */ + mod_free (ser_drv); + ser_clear_ptr (); + } + + /* Return the error code */ + return Res; } } -- 2.39.5