diff options
| -rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b36eef0e9d19..02a7dd7a8a55 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -1184,20 +1184,20 @@ static void port_outl(struct si_sm_io *io, unsigned int offset, | |||
| 1184 | static void port_cleanup(struct smi_info *info) | 1184 | static void port_cleanup(struct smi_info *info) |
| 1185 | { | 1185 | { |
| 1186 | unsigned int addr = info->io.addr_data; | 1186 | unsigned int addr = info->io.addr_data; |
| 1187 | int mapsize; | 1187 | int idx; |
| 1188 | 1188 | ||
| 1189 | if (addr) { | 1189 | if (addr) { |
| 1190 | mapsize = ((info->io_size * info->io.regspacing) | 1190 | for (idx = 0; idx < info->io_size; idx++) { |
| 1191 | - (info->io.regspacing - info->io.regsize)); | 1191 | release_region(addr + idx * info->io.regspacing, |
| 1192 | 1192 | info->io.regsize); | |
| 1193 | release_region (addr, mapsize); | 1193 | } |
| 1194 | } | 1194 | } |
| 1195 | } | 1195 | } |
| 1196 | 1196 | ||
| 1197 | static int port_setup(struct smi_info *info) | 1197 | static int port_setup(struct smi_info *info) |
| 1198 | { | 1198 | { |
| 1199 | unsigned int addr = info->io.addr_data; | 1199 | unsigned int addr = info->io.addr_data; |
| 1200 | int mapsize; | 1200 | int idx; |
| 1201 | 1201 | ||
| 1202 | if (!addr) | 1202 | if (!addr) |
| 1203 | return -ENODEV; | 1203 | return -ENODEV; |
| @@ -1225,16 +1225,22 @@ static int port_setup(struct smi_info *info) | |||
| 1225 | return -EINVAL; | 1225 | return -EINVAL; |
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | /* Calculate the total amount of memory to claim. This is an | 1228 | /* Some BIOSes reserve disjoint I/O regions in their ACPI |
| 1229 | * unusual looking calculation, but it avoids claiming any | 1229 | * tables. This causes problems when trying to register the |
| 1230 | * more memory than it has to. It will claim everything | 1230 | * entire I/O region. Therefore we must register each I/O |
| 1231 | * between the first address to the end of the last full | 1231 | * port separately. |
| 1232 | * register. */ | 1232 | */ |
| 1233 | mapsize = ((info->io_size * info->io.regspacing) | 1233 | for (idx = 0; idx < info->io_size; idx++) { |
| 1234 | - (info->io.regspacing - info->io.regsize)); | 1234 | if (request_region(addr + idx * info->io.regspacing, |
| 1235 | 1235 | info->io.regsize, DEVICE_NAME) == NULL) { | |
| 1236 | if (request_region(addr, mapsize, DEVICE_NAME) == NULL) | 1236 | /* Undo allocations */ |
| 1237 | return -EIO; | 1237 | while (idx--) { |
| 1238 | release_region(addr + idx * info->io.regspacing, | ||
| 1239 | info->io.regsize); | ||
| 1240 | } | ||
| 1241 | return -EIO; | ||
| 1242 | } | ||
| 1243 | } | ||
| 1238 | return 0; | 1244 | return 0; |
| 1239 | } | 1245 | } |
| 1240 | 1246 | ||
