Author: hailfinger Date: Sat Jul 21 19:27:08 2012 New Revision: 1551 URL: http://flashrom.org/trac/flashrom/changeset/1551
Log: Automatically release I/O permissions on shutdown.
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.
Do not call exit(1) if I/O permissions are denied and return an error instead. This part of the patch was written by Niklas Söderlund.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Signed-off-by: Niklas Söderlund niso@kth.se Acked-by: Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de
Modified: trunk/atahpt.c trunk/drkaiser.c trunk/gfxnvidia.c trunk/hwaccess.c trunk/internal.c trunk/nic3com.c trunk/nicintel.c trunk/nicintel_spi.c trunk/nicnatsemi.c trunk/nicrealtek.c trunk/ogp_spi.c trunk/programmer.h trunk/rayer_spi.c trunk/satamv.c trunk/satasii.c
Modified: trunk/atahpt.c ============================================================================== --- trunk/atahpt.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/atahpt.c Sat Jul 21 19:27:08 2012 (r1551) @@ -60,7 +60,6 @@ { /* Flash access is disabled automatically by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -68,7 +67,8 @@ { uint32_t reg32;
- get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_4, ata_hpt);
Modified: trunk/drkaiser.c ============================================================================== --- trunk/drkaiser.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/drkaiser.c Sat Jul 21 19:27:08 2012 (r1551) @@ -60,7 +60,6 @@ physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE); /* Flash write is disabled automatically by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; };
@@ -68,7 +67,8 @@ { uint32_t addr;
- get_io_perms(); + if (rget_io_perms()) + return 1;
addr = pcidev_init(PCI_BASE_ADDRESS_2, drkaiser_pcidev);
Modified: trunk/gfxnvidia.c ============================================================================== --- trunk/gfxnvidia.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/gfxnvidia.c Sat Jul 21 19:27:08 2012 (r1551) @@ -84,7 +84,6 @@ * by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -92,7 +91,8 @@ { uint32_t reg32;
- get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, gfx_nvidia);
Modified: trunk/hwaccess.c ============================================================================== --- trunk/hwaccess.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/hwaccess.c Sat Jul 21 19:27:08 2012 (r1551) @@ -45,11 +45,27 @@ 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. */ +int rget_io_perms(void) { #if defined(__DJGPP__) || defined(__LIBPAYLOAD__) /* We have full permissions by default. */ - return; + return 0; #else #if defined (__sun) && (defined(__i386) || defined(__amd64)) if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) { @@ -65,15 +81,11 @@ "and reboot, or reboot into \n"); msg_perr("single user mode.\n"); #endif - exit(1); + return 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); + return 0; #endif }
@@ -89,13 +101,9 @@ }
/* PCI port I/O is not yet implemented on PowerPC. */ -void get_io_perms(void) -{ -} - -/* PCI port I/O is not yet implemented on PowerPC. */ -void release_io_perms(void) +int rget_io_perms(void) { + return 0; }
#elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips) @@ -108,13 +116,9 @@ }
/* PCI port I/O is not yet implemented on MIPS. */ -void get_io_perms(void) -{ -} - -/* PCI port I/O is not yet implemented on MIPS. */ -void release_io_perms(void) +int rget_io_perms(void) { + return 0; }
#elif defined (__arm__) @@ -123,12 +127,9 @@ { }
-void get_io_perms(void) -{ -} - -void release_io_perms(void) +int rget_io_perms(void) { + return 0; }
#else
Modified: trunk/internal.c ============================================================================== --- trunk/internal.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/internal.c Sat Jul 21 19:27:08 2012 (r1551) @@ -159,7 +159,6 @@
static int internal_shutdown(void *data) { - release_io_perms(); return 0; }
@@ -226,7 +225,8 @@ } free(arg);
- get_io_perms(); + if (rget_io_perms()) + return 1; if (register_shutdown(internal_shutdown, NULL)) return 1;
Modified: trunk/nic3com.c ============================================================================== --- trunk/nic3com.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/nic3com.c Sat Jul 21 19:27:08 2012 (r1551) @@ -82,13 +82,13 @@ }
pci_cleanup(pacc); - release_io_perms(); return 0; }
int nic3com_init(void) { - get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_3com);
Modified: trunk/nicintel.c ============================================================================== --- trunk/nicintel.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/nicintel.c Sat Jul 21 19:27:08 2012 (r1551) @@ -64,7 +64,6 @@ physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE); physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -73,9 +72,10 @@ 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(); + if (rget_io_perms()) + return 1;
/* No need to check for errors, pcidev_init() will not return in case * of errors. @@ -118,7 +118,6 @@ physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); error_out: pci_cleanup(pacc); - release_io_perms(); return 1; }
Modified: trunk/nicintel_spi.c ============================================================================== --- trunk/nicintel_spi.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/nicintel_spi.c Sat Jul 21 19:27:08 2012 (r1551) @@ -159,7 +159,6 @@
physunmap(nicintel_spibar, 4096); pci_cleanup(pacc); - release_io_perms();
return 0; } @@ -168,7 +167,8 @@ { uint32_t tmp;
- get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_intel_spi);
Modified: trunk/nicnatsemi.c ============================================================================== --- trunk/nicnatsemi.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/nicnatsemi.c Sat Jul 21 19:27:08 2012 (r1551) @@ -54,13 +54,13 @@ static int nicnatsemi_shutdown(void *data) { pci_cleanup(pacc); - release_io_perms(); return 0; }
int nicnatsemi_init(void) { - get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
Modified: trunk/nicrealtek.c ============================================================================== --- trunk/nicrealtek.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/nicrealtek.c Sat Jul 21 19:27:08 2012 (r1551) @@ -56,13 +56,13 @@ { /* FIXME: We forgot to disable software access again. */ pci_cleanup(pacc); - release_io_perms(); return 0; }
int nicrealtek_init(void) { - get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
Modified: trunk/ogp_spi.c ============================================================================== --- trunk/ogp_spi.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/ogp_spi.c Sat Jul 21 19:27:08 2012 (r1551) @@ -99,7 +99,6 @@ { physunmap(ogp_spibar, 4096); pci_cleanup(pacc); - release_io_perms();
return 0; } @@ -129,7 +128,8 @@ return 1; }
- get_io_perms(); + if (rget_io_perms()) + return 1;
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi);
Modified: trunk/programmer.h ============================================================================== --- trunk/programmer.h Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/programmer.h Sat Jul 21 19:27:08 2012 (r1551) @@ -302,8 +302,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); +int rget_io_perms(void); #if CONFIG_INTERNAL == 1 extern int is_laptop; extern int laptop_ok;
Modified: trunk/rayer_spi.c ============================================================================== --- trunk/rayer_spi.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/rayer_spi.c Sat Jul 21 19:27:08 2012 (r1551) @@ -168,7 +168,8 @@ rayer_miso_bit = 4; }
- get_io_perms(); + if (rget_io_perms()) + return 1;
/* Get the initial value before writing to any line. */ lpt_outbyte = INB(lpt_iobase);
Modified: trunk/satamv.c ============================================================================== --- trunk/satamv.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/satamv.c Sat Jul 21 19:27:08 2012 (r1551) @@ -61,7 +61,6 @@ { physunmap(mv_bar, 0x20000); pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -86,7 +85,8 @@ uintptr_t addr; uint32_t tmp;
- get_io_perms(); + if (rget_io_perms()) + return 1;
/* BAR0 has all internal registers memory mapped. */ /* No need to check for errors, pcidev_init() will not return in case @@ -162,7 +162,6 @@
error_out: pci_cleanup(pacc); - release_io_perms(); return 1; }
Modified: trunk/satasii.c ============================================================================== --- trunk/satasii.c Sat Jul 21 18:56:04 2012 (r1550) +++ trunk/satasii.c Sat Jul 21 19:27:08 2012 (r1551) @@ -62,7 +62,6 @@ { physunmap(sii_bar, SATASII_MEMMAP_SIZE); pci_cleanup(pacc); - release_io_perms(); return 0; }
@@ -71,7 +70,8 @@ uint32_t addr; uint16_t reg_offset;
- get_io_perms(); + if (rget_io_perms()) + return 1;
pcidev_init(PCI_BASE_ADDRESS_0, satas_sii);