diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2012-07-21 17:27:08 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2012-07-21 17:27:08 +0000 |
commit | b5f1abb51b7028862e5923a848179a335422fa37 (patch) | |
tree | 722abce67e8d8864158ec9261405461a28e313b0 | |
parent | dcbddba9cdefcd95847853fc9146976768e15f6d (diff) | |
download | flashrom-b5f1abb51b7028862e5923a848179a335422fa37.zip flashrom-b5f1abb51b7028862e5923a848179a335422fa37.tar.gz |
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
Binary file (standard input) matches
Corresponding to flashrom svn r1551.
-rw-r--r-- | atahpt.c | 4 | ||||
-rw-r--r-- | drkaiser.c | 4 | ||||
-rw-r--r-- | gfxnvidia.c | 4 | ||||
-rw-r--r-- | hwaccess.c | 55 | ||||
-rw-r--r-- | internal.c | 4 | ||||
-rw-r--r-- | nic3com.c | 4 | ||||
-rw-r--r-- | nicintel.c | 7 | ||||
-rw-r--r-- | nicintel_spi.c | 4 | ||||
-rw-r--r-- | nicnatsemi.c | 4 | ||||
-rw-r--r-- | nicrealtek.c | 4 | ||||
-rw-r--r-- | ogp_spi.c | 4 | ||||
-rw-r--r-- | programmer.h | 3 | ||||
-rw-r--r-- | rayer_spi.c | 3 | ||||
-rw-r--r-- | satamv.c | 5 | ||||
-rw-r--r-- | satasii.c | 4 |
15 files changed, 56 insertions, 57 deletions
@@ -60,7 +60,6 @@ static int atahpt_shutdown(void *data) { /* Flash access is disabled automatically by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; } @@ -68,7 +67,8 @@ int atahpt_init(void) { uint32_t reg32; - get_io_perms(); + if (rget_io_perms()) + return 1; io_base_addr = pcidev_init(PCI_BASE_ADDRESS_4, ata_hpt); @@ -60,7 +60,6 @@ static int drkaiser_shutdown(void *data) 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 @@ int drkaiser_init(void) { uint32_t addr; - get_io_perms(); + if (rget_io_perms()) + return 1; addr = pcidev_init(PCI_BASE_ADDRESS_2, drkaiser_pcidev); diff --git a/gfxnvidia.c b/gfxnvidia.c index ddf82e7..782d692 100644 --- a/gfxnvidia.c +++ b/gfxnvidia.c @@ -84,7 +84,6 @@ static int gfxnvidia_shutdown(void *data) * by PCI restore. */ pci_cleanup(pacc); - release_io_perms(); return 0; } @@ -92,7 +91,8 @@ int gfxnvidia_init(void) { uint32_t reg32; - get_io_perms(); + if (rget_io_perms()) + return 1; io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, gfx_nvidia); @@ -45,11 +45,27 @@ static inline void sync_primitive(void) 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 @@ void get_io_perms(void) "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 @@ static inline void sync_primitive(void) } /* 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 @@ static inline void sync_primitive(void) } /* 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 @@ static inline void sync_primitive(void) { } -void get_io_perms(void) -{ -} - -void release_io_perms(void) +int rget_io_perms(void) { + return 0; } #else @@ -159,7 +159,6 @@ enum chipbustype internal_buses_supported = BUS_NONE; static int internal_shutdown(void *data) { - release_io_perms(); return 0; } @@ -226,7 +225,8 @@ int internal_init(void) } free(arg); - get_io_perms(); + if (rget_io_perms()) + return 1; if (register_shutdown(internal_shutdown, NULL)) return 1; @@ -82,13 +82,13 @@ static int nic3com_shutdown(void *data) } 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); @@ -64,7 +64,6 @@ static int nicintel_shutdown(void *data) 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 @@ int nicintel_init(void) 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 @@ error_out_unmap: physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE); error_out: pci_cleanup(pacc); - release_io_perms(); return 1; } diff --git a/nicintel_spi.c b/nicintel_spi.c index 7a02cda..531576c 100644 --- a/nicintel_spi.c +++ b/nicintel_spi.c @@ -159,7 +159,6 @@ static int nicintel_spi_shutdown(void *data) physunmap(nicintel_spibar, 4096); pci_cleanup(pacc); - release_io_perms(); return 0; } @@ -168,7 +167,8 @@ int nicintel_spi_init(void) { uint32_t tmp; - get_io_perms(); + if (rget_io_perms()) + return 1; io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_intel_spi); diff --git a/nicnatsemi.c b/nicnatsemi.c index 4646867..7cdd2fe 100644 --- a/nicnatsemi.c +++ b/nicnatsemi.c @@ -54,13 +54,13 @@ static const struct par_programmer par_programmer_nicnatsemi = { 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); diff --git a/nicrealtek.c b/nicrealtek.c index 61e07d8..afc3d0f 100644 --- a/nicrealtek.c +++ b/nicrealtek.c @@ -56,13 +56,13 @@ static int nicrealtek_shutdown(void *data) { /* 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); @@ -99,7 +99,6 @@ static int ogp_spi_shutdown(void *data) { physunmap(ogp_spibar, 4096); pci_cleanup(pacc); - release_io_perms(); return 0; } @@ -129,7 +128,8 @@ int ogp_spi_init(void) return 1; } - get_io_perms(); + if (rget_io_perms()) + return 1; io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi); diff --git a/programmer.h b/programmer.h index 6f07dd0..f511c71 100644 --- a/programmer.h +++ b/programmer.h @@ -302,8 +302,7 @@ struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device); 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; diff --git a/rayer_spi.c b/rayer_spi.c index 584a6a0..8e48e6e 100644 --- a/rayer_spi.c +++ b/rayer_spi.c @@ -168,7 +168,8 @@ int rayer_spi_init(void) 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); @@ -61,7 +61,6 @@ static int satamv_shutdown(void *data) { physunmap(mv_bar, 0x20000); pci_cleanup(pacc); - release_io_perms(); return 0; } @@ -86,7 +85,8 @@ int satamv_init(void) 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 @@ int satamv_init(void) error_out: pci_cleanup(pacc); - release_io_perms(); return 1; } @@ -62,7 +62,6 @@ static int satasii_shutdown(void *data) { physunmap(sii_bar, SATASII_MEMMAP_SIZE); pci_cleanup(pacc); - release_io_perms(); return 0; } @@ -71,7 +70,8 @@ int satasii_init(void) uint32_t addr; uint16_t reg_offset; - get_io_perms(); + if (rget_io_perms()) + return 1; pcidev_init(PCI_BASE_ADDRESS_0, satas_sii); |