get_io_perms() is renamed to rget_io_perms() and automatically registers a function to release I/O permissions on shutdown.
Actually release I/O permissions on Solaris and iopl()-supporting operating systems like Linux.
This patch fixes quite a few programmers which forgot to release I/O permissions on shutdown, and it simplifies the shutdown and error handling code for all others.
Note: The next steps will be to do the same with PCI init and /dev/mem accesses. That should make probably 3/4 of all explicit shutdown functions empty and obsolete.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-auto_release_io_perms/hwaccess.c =================================================================== --- flashrom-auto_release_io_perms/hwaccess.c (Revision 1547) +++ flashrom-auto_release_io_perms/hwaccess.c (Arbeitskopie) @@ -44,9 +44,25 @@ int io_fd; #endif
-void get_io_perms(void) +int release_io_perms(void *p) { #if defined(__DJGPP__) || defined(__LIBPAYLOAD__) +#else +#if defined (__sun) && (defined(__i386) || defined(__amd64)) + sysi86(SI86V86, V86SC_IOPL, 0); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__DragonFly__) + close(io_fd); +#else + iopl(0); +#endif +#endif + return 0; +} + +/* Get I/O permissions with automatic permission release on shutdown. */ +void rget_io_perms(void) +{ +#if defined(__DJGPP__) || defined(__LIBPAYLOAD__) /* We have full permissions by default. */ return; #else @@ -65,17 +81,12 @@ msg_perr("single user mode.\n"); #endif exit(1); + } else { + register_shutdown(release_io_perms, NULL); } #endif }
-void release_io_perms(void) -{ -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) - close(io_fd); -#endif -} - #elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
static inline void sync_primitive(void) @@ -88,15 +99,10 @@ }
/* PCI port I/O is not yet implemented on PowerPC. */ -void get_io_perms(void) +void rget_io_perms(void) { }
-/* PCI port I/O is not yet implemented on PowerPC. */ -void release_io_perms(void) -{ -} - #elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
/* sync primitive is not needed because /dev/mem on MIPS uses uncached accesses @@ -107,29 +113,20 @@ }
/* PCI port I/O is not yet implemented on MIPS. */ -void get_io_perms(void) +void rget_io_perms(void) { }
-/* PCI port I/O is not yet implemented on MIPS. */ -void release_io_perms(void) -{ -} - #elif defined (__arm__)
static inline void sync_primitive(void) { }
-void get_io_perms(void) +void rget_io_perms(void) { }
-void release_io_perms(void) -{ -} - #else
#error Unknown architecture Index: flashrom-auto_release_io_perms/ogp_spi.c =================================================================== --- flashrom-auto_release_io_perms/ogp_spi.c (Revision 1547) +++ flashrom-auto_release_io_perms/ogp_spi.c (Arbeitskopie) @@ -98,7 +98,6 @@ { physunmap(ogp_spibar, 4096); pci_cleanup(pacc); - release_io_perms();
return 0; } @@ -128,7 +127,7 @@ return 1; }
- get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi);
Index: flashrom-auto_release_io_perms/drkaiser.c =================================================================== --- flashrom-auto_release_io_perms/drkaiser.c (Revision 1547) +++ flashrom-auto_release_io_perms/drkaiser.c (Arbeitskopie) @@ -59,7 +59,6 @@ physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE); /* Flash write is disabled automatically by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; };
@@ -67,7 +66,7 @@ { uint32_t addr;
- get_io_perms(); + rget_io_perms();
addr = pcidev_init(PCI_BASE_ADDRESS_2, drkaiser_pcidev);
Index: flashrom-auto_release_io_perms/gfxnvidia.c =================================================================== --- flashrom-auto_release_io_perms/gfxnvidia.c (Revision 1547) +++ flashrom-auto_release_io_perms/gfxnvidia.c (Arbeitskopie) @@ -83,7 +83,6 @@ * by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -91,7 +90,7 @@ { uint32_t reg32;
- get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, gfx_nvidia);
Index: flashrom-auto_release_io_perms/nicrealtek.c =================================================================== --- flashrom-auto_release_io_perms/nicrealtek.c (Revision 1547) +++ flashrom-auto_release_io_perms/nicrealtek.c (Arbeitskopie) @@ -55,13 +55,12 @@ { /* FIXME: We forgot to disable software access again. */ pci_cleanup(pacc); - release_io_perms(); return 0; }
int nicrealtek_init(void) { - get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
Index: flashrom-auto_release_io_perms/satamv.c =================================================================== --- flashrom-auto_release_io_perms/satamv.c (Revision 1547) +++ flashrom-auto_release_io_perms/satamv.c (Arbeitskopie) @@ -60,7 +60,6 @@ { physunmap(mv_bar, 0x20000); pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -85,7 +84,7 @@ uintptr_t addr; uint32_t tmp;
- get_io_perms(); + rget_io_perms();
/* BAR0 has all internal registers memory mapped. */ /* No need to check for errors, pcidev_init() will not return in case @@ -161,7 +160,6 @@
error_out: pci_cleanup(pacc); - release_io_perms(); return 1; }
Index: flashrom-auto_release_io_perms/internal.c =================================================================== --- flashrom-auto_release_io_perms/internal.c (Revision 1547) +++ flashrom-auto_release_io_perms/internal.c (Arbeitskopie) @@ -158,7 +158,6 @@
static int internal_shutdown(void *data) { - release_io_perms(); return 0; }
@@ -225,7 +224,7 @@ } free(arg);
- get_io_perms(); + rget_io_perms(); if (register_shutdown(internal_shutdown, NULL)) return 1;
Index: flashrom-auto_release_io_perms/nicintel_spi.c =================================================================== --- flashrom-auto_release_io_perms/nicintel_spi.c (Revision 1547) +++ flashrom-auto_release_io_perms/nicintel_spi.c (Arbeitskopie) @@ -158,7 +158,6 @@
physunmap(nicintel_spibar, 4096); pci_cleanup(pacc); - release_io_perms();
return 0; } @@ -167,7 +166,7 @@ { uint32_t tmp;
- get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_intel_spi);
Index: flashrom-auto_release_io_perms/nicnatsemi.c =================================================================== --- flashrom-auto_release_io_perms/nicnatsemi.c (Revision 1547) +++ flashrom-auto_release_io_perms/nicnatsemi.c (Arbeitskopie) @@ -53,13 +53,12 @@ static int nicnatsemi_shutdown(void *data) { pci_cleanup(pacc); - release_io_perms(); return 0; }
int nicnatsemi_init(void) { - get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
Index: flashrom-auto_release_io_perms/rayer_spi.c =================================================================== --- flashrom-auto_release_io_perms/rayer_spi.c (Revision 1547) +++ flashrom-auto_release_io_perms/rayer_spi.c (Arbeitskopie) @@ -167,7 +167,7 @@ rayer_miso_bit = 4; }
- get_io_perms(); + rget_io_perms();
/* Get the initial value before writing to any line. */ lpt_outbyte = INB(lpt_iobase); Index: flashrom-auto_release_io_perms/atahpt.c =================================================================== --- flashrom-auto_release_io_perms/atahpt.c (Revision 1547) +++ flashrom-auto_release_io_perms/atahpt.c (Arbeitskopie) @@ -59,7 +59,6 @@ { /* Flash access is disabled automatically by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -67,7 +66,7 @@ { uint32_t reg32;
- get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_4, ata_hpt);
Index: flashrom-auto_release_io_perms/nic3com.c =================================================================== --- flashrom-auto_release_io_perms/nic3com.c (Revision 1547) +++ flashrom-auto_release_io_perms/nic3com.c (Arbeitskopie) @@ -81,13 +81,12 @@ }
pci_cleanup(pacc); - release_io_perms(); return 0; }
int nic3com_init(void) { - get_io_perms(); + rget_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_3com);
Index: flashrom-auto_release_io_perms/satasii.c =================================================================== --- flashrom-auto_release_io_perms/satasii.c (Revision 1547) +++ flashrom-auto_release_io_perms/satasii.c (Arbeitskopie) @@ -61,7 +61,6 @@ { physunmap(sii_bar, SATASII_MEMMAP_SIZE); pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -70,7 +69,7 @@ uint32_t addr; uint16_t reg_offset;
- get_io_perms(); + rget_io_perms();
pcidev_init(PCI_BASE_ADDRESS_0, satas_sii);
Index: flashrom-auto_release_io_perms/nicintel.c =================================================================== --- flashrom-auto_release_io_perms/nicintel.c (Revision 1547) +++ flashrom-auto_release_io_perms/nicintel.c (Arbeitskopie) @@ -63,7 +63,6 @@ physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE); physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -72,9 +71,9 @@ uintptr_t addr;
/* Needed only for PCI accesses on some platforms. - * FIXME: Refactor that into get_mem_perms/get_io_perms/get_pci_perms? + * FIXME: Refactor that into get_mem_perms/rget_io_perms/get_pci_perms? */ - get_io_perms(); + rget_io_perms();
/* No need to check for errors, pcidev_init() will not return in case * of errors. @@ -117,7 +116,6 @@ physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); error_out: pci_cleanup(pacc); - release_io_perms(); return 1; }
Index: flashrom-auto_release_io_perms/programmer.h =================================================================== --- flashrom-auto_release_io_perms/programmer.h (Revision 1547) +++ flashrom-auto_release_io_perms/programmer.h (Arbeitskopie) @@ -300,8 +300,7 @@ struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device, uint16_t card_vendor, uint16_t card_device); #endif -void get_io_perms(void); -void release_io_perms(void); +void rget_io_perms(void); #if CONFIG_INTERNAL == 1 extern int is_laptop; extern int laptop_ok;