diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_si_intf.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 395 |
1 files changed, 206 insertions, 189 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index a44b97304e95..1abec687865c 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -61,11 +61,11 @@ | |||
61 | # endif | 61 | # endif |
62 | static inline void add_usec_to_timer(struct timer_list *t, long v) | 62 | static inline void add_usec_to_timer(struct timer_list *t, long v) |
63 | { | 63 | { |
64 | t->sub_expires += nsec_to_arch_cycle(v * 1000); | 64 | t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000); |
65 | while (t->sub_expires >= arch_cycles_per_jiffy) | 65 | while (t->arch_cycle_expires >= arch_cycles_per_jiffy) |
66 | { | 66 | { |
67 | t->expires++; | 67 | t->expires++; |
68 | t->sub_expires -= arch_cycles_per_jiffy; | 68 | t->arch_cycle_expires -= arch_cycles_per_jiffy; |
69 | } | 69 | } |
70 | } | 70 | } |
71 | #endif | 71 | #endif |
@@ -75,8 +75,7 @@ static inline void add_usec_to_timer(struct timer_list *t, long v) | |||
75 | #include <asm/io.h> | 75 | #include <asm/io.h> |
76 | #include "ipmi_si_sm.h" | 76 | #include "ipmi_si_sm.h" |
77 | #include <linux/init.h> | 77 | #include <linux/init.h> |
78 | 78 | #include <linux/dmi.h> | |
79 | #define IPMI_SI_VERSION "v33" | ||
80 | 79 | ||
81 | /* Measure times between events in the driver. */ | 80 | /* Measure times between events in the driver. */ |
82 | #undef DEBUG_TIMING | 81 | #undef DEBUG_TIMING |
@@ -109,6 +108,21 @@ enum si_type { | |||
109 | SI_KCS, SI_SMIC, SI_BT | 108 | SI_KCS, SI_SMIC, SI_BT |
110 | }; | 109 | }; |
111 | 110 | ||
111 | struct ipmi_device_id { | ||
112 | unsigned char device_id; | ||
113 | unsigned char device_revision; | ||
114 | unsigned char firmware_revision_1; | ||
115 | unsigned char firmware_revision_2; | ||
116 | unsigned char ipmi_version; | ||
117 | unsigned char additional_device_support; | ||
118 | unsigned char manufacturer_id[3]; | ||
119 | unsigned char product_id[2]; | ||
120 | unsigned char aux_firmware_revision[4]; | ||
121 | } __attribute__((packed)); | ||
122 | |||
123 | #define ipmi_version_major(v) ((v)->ipmi_version & 0xf) | ||
124 | #define ipmi_version_minor(v) ((v)->ipmi_version >> 4) | ||
125 | |||
112 | struct smi_info | 126 | struct smi_info |
113 | { | 127 | { |
114 | ipmi_smi_t intf; | 128 | ipmi_smi_t intf; |
@@ -131,12 +145,24 @@ struct smi_info | |||
131 | void (*irq_cleanup)(struct smi_info *info); | 145 | void (*irq_cleanup)(struct smi_info *info); |
132 | unsigned int io_size; | 146 | unsigned int io_size; |
133 | 147 | ||
148 | /* Per-OEM handler, called from handle_flags(). | ||
149 | Returns 1 when handle_flags() needs to be re-run | ||
150 | or 0 indicating it set si_state itself. | ||
151 | */ | ||
152 | int (*oem_data_avail_handler)(struct smi_info *smi_info); | ||
153 | |||
134 | /* Flags from the last GET_MSG_FLAGS command, used when an ATTN | 154 | /* Flags from the last GET_MSG_FLAGS command, used when an ATTN |
135 | is set to hold the flags until we are done handling everything | 155 | is set to hold the flags until we are done handling everything |
136 | from the flags. */ | 156 | from the flags. */ |
137 | #define RECEIVE_MSG_AVAIL 0x01 | 157 | #define RECEIVE_MSG_AVAIL 0x01 |
138 | #define EVENT_MSG_BUFFER_FULL 0x02 | 158 | #define EVENT_MSG_BUFFER_FULL 0x02 |
139 | #define WDT_PRE_TIMEOUT_INT 0x08 | 159 | #define WDT_PRE_TIMEOUT_INT 0x08 |
160 | #define OEM0_DATA_AVAIL 0x20 | ||
161 | #define OEM1_DATA_AVAIL 0x40 | ||
162 | #define OEM2_DATA_AVAIL 0x80 | ||
163 | #define OEM_DATA_AVAIL (OEM0_DATA_AVAIL | \ | ||
164 | OEM1_DATA_AVAIL | \ | ||
165 | OEM2_DATA_AVAIL) | ||
140 | unsigned char msg_flags; | 166 | unsigned char msg_flags; |
141 | 167 | ||
142 | /* If set to true, this will request events the next time the | 168 | /* If set to true, this will request events the next time the |
@@ -175,11 +201,7 @@ struct smi_info | |||
175 | interrupts. */ | 201 | interrupts. */ |
176 | int interrupt_disabled; | 202 | int interrupt_disabled; |
177 | 203 | ||
178 | unsigned char ipmi_si_dev_rev; | 204 | struct ipmi_device_id device_id; |
179 | unsigned char ipmi_si_fw_rev_major; | ||
180 | unsigned char ipmi_si_fw_rev_minor; | ||
181 | unsigned char ipmi_version_major; | ||
182 | unsigned char ipmi_version_minor; | ||
183 | 205 | ||
184 | /* Slave address, could be reported from DMI. */ | 206 | /* Slave address, could be reported from DMI. */ |
185 | unsigned char slave_addr; | 207 | unsigned char slave_addr; |
@@ -245,7 +267,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
245 | entry = smi_info->xmit_msgs.next; | 267 | entry = smi_info->xmit_msgs.next; |
246 | } | 268 | } |
247 | 269 | ||
248 | if (!entry) { | 270 | if (! entry) { |
249 | smi_info->curr_msg = NULL; | 271 | smi_info->curr_msg = NULL; |
250 | rv = SI_SM_IDLE; | 272 | rv = SI_SM_IDLE; |
251 | } else { | 273 | } else { |
@@ -306,7 +328,7 @@ static void start_clear_flags(struct smi_info *smi_info) | |||
306 | memory, we will re-enable the interrupt. */ | 328 | memory, we will re-enable the interrupt. */ |
307 | static inline void disable_si_irq(struct smi_info *smi_info) | 329 | static inline void disable_si_irq(struct smi_info *smi_info) |
308 | { | 330 | { |
309 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { | 331 | if ((smi_info->irq) && (! smi_info->interrupt_disabled)) { |
310 | disable_irq_nosync(smi_info->irq); | 332 | disable_irq_nosync(smi_info->irq); |
311 | smi_info->interrupt_disabled = 1; | 333 | smi_info->interrupt_disabled = 1; |
312 | } | 334 | } |
@@ -322,6 +344,7 @@ static inline void enable_si_irq(struct smi_info *smi_info) | |||
322 | 344 | ||
323 | static void handle_flags(struct smi_info *smi_info) | 345 | static void handle_flags(struct smi_info *smi_info) |
324 | { | 346 | { |
347 | retry: | ||
325 | if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) { | 348 | if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) { |
326 | /* Watchdog pre-timeout */ | 349 | /* Watchdog pre-timeout */ |
327 | spin_lock(&smi_info->count_lock); | 350 | spin_lock(&smi_info->count_lock); |
@@ -336,7 +359,7 @@ static void handle_flags(struct smi_info *smi_info) | |||
336 | } else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) { | 359 | } else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) { |
337 | /* Messages available. */ | 360 | /* Messages available. */ |
338 | smi_info->curr_msg = ipmi_alloc_smi_msg(); | 361 | smi_info->curr_msg = ipmi_alloc_smi_msg(); |
339 | if (!smi_info->curr_msg) { | 362 | if (! smi_info->curr_msg) { |
340 | disable_si_irq(smi_info); | 363 | disable_si_irq(smi_info); |
341 | smi_info->si_state = SI_NORMAL; | 364 | smi_info->si_state = SI_NORMAL; |
342 | return; | 365 | return; |
@@ -355,7 +378,7 @@ static void handle_flags(struct smi_info *smi_info) | |||
355 | } else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) { | 378 | } else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) { |
356 | /* Events available. */ | 379 | /* Events available. */ |
357 | smi_info->curr_msg = ipmi_alloc_smi_msg(); | 380 | smi_info->curr_msg = ipmi_alloc_smi_msg(); |
358 | if (!smi_info->curr_msg) { | 381 | if (! smi_info->curr_msg) { |
359 | disable_si_irq(smi_info); | 382 | disable_si_irq(smi_info); |
360 | smi_info->si_state = SI_NORMAL; | 383 | smi_info->si_state = SI_NORMAL; |
361 | return; | 384 | return; |
@@ -371,6 +394,10 @@ static void handle_flags(struct smi_info *smi_info) | |||
371 | smi_info->curr_msg->data, | 394 | smi_info->curr_msg->data, |
372 | smi_info->curr_msg->data_size); | 395 | smi_info->curr_msg->data_size); |
373 | smi_info->si_state = SI_GETTING_EVENTS; | 396 | smi_info->si_state = SI_GETTING_EVENTS; |
397 | } else if (smi_info->msg_flags & OEM_DATA_AVAIL) { | ||
398 | if (smi_info->oem_data_avail_handler) | ||
399 | if (smi_info->oem_data_avail_handler(smi_info)) | ||
400 | goto retry; | ||
374 | } else { | 401 | } else { |
375 | smi_info->si_state = SI_NORMAL; | 402 | smi_info->si_state = SI_NORMAL; |
376 | } | 403 | } |
@@ -387,7 +414,7 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
387 | #endif | 414 | #endif |
388 | switch (smi_info->si_state) { | 415 | switch (smi_info->si_state) { |
389 | case SI_NORMAL: | 416 | case SI_NORMAL: |
390 | if (!smi_info->curr_msg) | 417 | if (! smi_info->curr_msg) |
391 | break; | 418 | break; |
392 | 419 | ||
393 | smi_info->curr_msg->rsp_size | 420 | smi_info->curr_msg->rsp_size |
@@ -761,18 +788,20 @@ static void si_restart_short_timer(struct smi_info *smi_info) | |||
761 | #if defined(CONFIG_HIGH_RES_TIMERS) | 788 | #if defined(CONFIG_HIGH_RES_TIMERS) |
762 | unsigned long flags; | 789 | unsigned long flags; |
763 | unsigned long jiffies_now; | 790 | unsigned long jiffies_now; |
791 | unsigned long seq; | ||
764 | 792 | ||
765 | if (del_timer(&(smi_info->si_timer))) { | 793 | if (del_timer(&(smi_info->si_timer))) { |
766 | /* If we don't delete the timer, then it will go off | 794 | /* If we don't delete the timer, then it will go off |
767 | immediately, anyway. So we only process if we | 795 | immediately, anyway. So we only process if we |
768 | actually delete the timer. */ | 796 | actually delete the timer. */ |
769 | 797 | ||
770 | /* We already have irqsave on, so no need for it | 798 | do { |
771 | here. */ | 799 | seq = read_seqbegin_irqsave(&xtime_lock, flags); |
772 | read_lock(&xtime_lock); | 800 | jiffies_now = jiffies; |
773 | jiffies_now = jiffies; | 801 | smi_info->si_timer.expires = jiffies_now; |
774 | smi_info->si_timer.expires = jiffies_now; | 802 | smi_info->si_timer.arch_cycle_expires |
775 | smi_info->si_timer.sub_expires = get_arch_cycles(jiffies_now); | 803 | = get_arch_cycles(jiffies_now); |
804 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
776 | 805 | ||
777 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); | 806 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); |
778 | 807 | ||
@@ -826,15 +855,19 @@ static void smi_timeout(unsigned long data) | |||
826 | /* If the state machine asks for a short delay, then shorten | 855 | /* If the state machine asks for a short delay, then shorten |
827 | the timer timeout. */ | 856 | the timer timeout. */ |
828 | if (smi_result == SI_SM_CALL_WITH_DELAY) { | 857 | if (smi_result == SI_SM_CALL_WITH_DELAY) { |
858 | #if defined(CONFIG_HIGH_RES_TIMERS) | ||
859 | unsigned long seq; | ||
860 | #endif | ||
829 | spin_lock_irqsave(&smi_info->count_lock, flags); | 861 | spin_lock_irqsave(&smi_info->count_lock, flags); |
830 | smi_info->short_timeouts++; | 862 | smi_info->short_timeouts++; |
831 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | 863 | spin_unlock_irqrestore(&smi_info->count_lock, flags); |
832 | #if defined(CONFIG_HIGH_RES_TIMERS) | 864 | #if defined(CONFIG_HIGH_RES_TIMERS) |
833 | read_lock(&xtime_lock); | 865 | do { |
834 | smi_info->si_timer.expires = jiffies; | 866 | seq = read_seqbegin_irqsave(&xtime_lock, flags); |
835 | smi_info->si_timer.sub_expires | 867 | smi_info->si_timer.expires = jiffies; |
836 | = get_arch_cycles(smi_info->si_timer.expires); | 868 | smi_info->si_timer.arch_cycle_expires |
837 | read_unlock(&xtime_lock); | 869 | = get_arch_cycles(smi_info->si_timer.expires); |
870 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
838 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); | 871 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); |
839 | #else | 872 | #else |
840 | smi_info->si_timer.expires = jiffies + 1; | 873 | smi_info->si_timer.expires = jiffies + 1; |
@@ -845,7 +878,7 @@ static void smi_timeout(unsigned long data) | |||
845 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | 878 | spin_unlock_irqrestore(&smi_info->count_lock, flags); |
846 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | 879 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; |
847 | #if defined(CONFIG_HIGH_RES_TIMERS) | 880 | #if defined(CONFIG_HIGH_RES_TIMERS) |
848 | smi_info->si_timer.sub_expires = 0; | 881 | smi_info->si_timer.arch_cycle_expires = 0; |
849 | #endif | 882 | #endif |
850 | } | 883 | } |
851 | 884 | ||
@@ -1014,7 +1047,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1014 | { | 1047 | { |
1015 | int rv; | 1048 | int rv; |
1016 | 1049 | ||
1017 | if (!info->irq) | 1050 | if (! info->irq) |
1018 | return 0; | 1051 | return 0; |
1019 | 1052 | ||
1020 | if (info->si_type == SI_BT) { | 1053 | if (info->si_type == SI_BT) { |
@@ -1023,7 +1056,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1023 | SA_INTERRUPT, | 1056 | SA_INTERRUPT, |
1024 | DEVICE_NAME, | 1057 | DEVICE_NAME, |
1025 | info); | 1058 | info); |
1026 | if (!rv) | 1059 | if (! rv) |
1027 | /* Enable the interrupt in the BT interface. */ | 1060 | /* Enable the interrupt in the BT interface. */ |
1028 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, | 1061 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, |
1029 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); | 1062 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); |
@@ -1048,7 +1081,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1048 | 1081 | ||
1049 | static void std_irq_cleanup(struct smi_info *info) | 1082 | static void std_irq_cleanup(struct smi_info *info) |
1050 | { | 1083 | { |
1051 | if (!info->irq) | 1084 | if (! info->irq) |
1052 | return; | 1085 | return; |
1053 | 1086 | ||
1054 | if (info->si_type == SI_BT) | 1087 | if (info->si_type == SI_BT) |
@@ -1121,7 +1154,7 @@ static int port_setup(struct smi_info *info) | |||
1121 | unsigned int *addr = info->io.info; | 1154 | unsigned int *addr = info->io.info; |
1122 | int mapsize; | 1155 | int mapsize; |
1123 | 1156 | ||
1124 | if (!addr || (!*addr)) | 1157 | if (! addr || (! *addr)) |
1125 | return -ENODEV; | 1158 | return -ENODEV; |
1126 | 1159 | ||
1127 | info->io_cleanup = port_cleanup; | 1160 | info->io_cleanup = port_cleanup; |
@@ -1164,15 +1197,15 @@ static int try_init_port(int intf_num, struct smi_info **new_info) | |||
1164 | { | 1197 | { |
1165 | struct smi_info *info; | 1198 | struct smi_info *info; |
1166 | 1199 | ||
1167 | if (!ports[intf_num]) | 1200 | if (! ports[intf_num]) |
1168 | return -ENODEV; | 1201 | return -ENODEV; |
1169 | 1202 | ||
1170 | if (!is_new_interface(intf_num, IPMI_IO_ADDR_SPACE, | 1203 | if (! is_new_interface(intf_num, IPMI_IO_ADDR_SPACE, |
1171 | ports[intf_num])) | 1204 | ports[intf_num])) |
1172 | return -ENODEV; | 1205 | return -ENODEV; |
1173 | 1206 | ||
1174 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1207 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1175 | if (!info) { | 1208 | if (! info) { |
1176 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (1)\n"); | 1209 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (1)\n"); |
1177 | return -ENOMEM; | 1210 | return -ENOMEM; |
1178 | } | 1211 | } |
@@ -1182,10 +1215,10 @@ static int try_init_port(int intf_num, struct smi_info **new_info) | |||
1182 | info->io.info = &(ports[intf_num]); | 1215 | info->io.info = &(ports[intf_num]); |
1183 | info->io.addr = NULL; | 1216 | info->io.addr = NULL; |
1184 | info->io.regspacing = regspacings[intf_num]; | 1217 | info->io.regspacing = regspacings[intf_num]; |
1185 | if (!info->io.regspacing) | 1218 | if (! info->io.regspacing) |
1186 | info->io.regspacing = DEFAULT_REGSPACING; | 1219 | info->io.regspacing = DEFAULT_REGSPACING; |
1187 | info->io.regsize = regsizes[intf_num]; | 1220 | info->io.regsize = regsizes[intf_num]; |
1188 | if (!info->io.regsize) | 1221 | if (! info->io.regsize) |
1189 | info->io.regsize = DEFAULT_REGSPACING; | 1222 | info->io.regsize = DEFAULT_REGSPACING; |
1190 | info->io.regshift = regshifts[intf_num]; | 1223 | info->io.regshift = regshifts[intf_num]; |
1191 | info->irq = 0; | 1224 | info->irq = 0; |
@@ -1270,7 +1303,7 @@ static int mem_setup(struct smi_info *info) | |||
1270 | unsigned long *addr = info->io.info; | 1303 | unsigned long *addr = info->io.info; |
1271 | int mapsize; | 1304 | int mapsize; |
1272 | 1305 | ||
1273 | if (!addr || (!*addr)) | 1306 | if (! addr || (! *addr)) |
1274 | return -ENODEV; | 1307 | return -ENODEV; |
1275 | 1308 | ||
1276 | info->io_cleanup = mem_cleanup; | 1309 | info->io_cleanup = mem_cleanup; |
@@ -1325,15 +1358,15 @@ static int try_init_mem(int intf_num, struct smi_info **new_info) | |||
1325 | { | 1358 | { |
1326 | struct smi_info *info; | 1359 | struct smi_info *info; |
1327 | 1360 | ||
1328 | if (!addrs[intf_num]) | 1361 | if (! addrs[intf_num]) |
1329 | return -ENODEV; | 1362 | return -ENODEV; |
1330 | 1363 | ||
1331 | if (!is_new_interface(intf_num, IPMI_MEM_ADDR_SPACE, | 1364 | if (! is_new_interface(intf_num, IPMI_MEM_ADDR_SPACE, |
1332 | addrs[intf_num])) | 1365 | addrs[intf_num])) |
1333 | return -ENODEV; | 1366 | return -ENODEV; |
1334 | 1367 | ||
1335 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1368 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1336 | if (!info) { | 1369 | if (! info) { |
1337 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (2)\n"); | 1370 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (2)\n"); |
1338 | return -ENOMEM; | 1371 | return -ENOMEM; |
1339 | } | 1372 | } |
@@ -1343,10 +1376,10 @@ static int try_init_mem(int intf_num, struct smi_info **new_info) | |||
1343 | info->io.info = &addrs[intf_num]; | 1376 | info->io.info = &addrs[intf_num]; |
1344 | info->io.addr = NULL; | 1377 | info->io.addr = NULL; |
1345 | info->io.regspacing = regspacings[intf_num]; | 1378 | info->io.regspacing = regspacings[intf_num]; |
1346 | if (!info->io.regspacing) | 1379 | if (! info->io.regspacing) |
1347 | info->io.regspacing = DEFAULT_REGSPACING; | 1380 | info->io.regspacing = DEFAULT_REGSPACING; |
1348 | info->io.regsize = regsizes[intf_num]; | 1381 | info->io.regsize = regsizes[intf_num]; |
1349 | if (!info->io.regsize) | 1382 | if (! info->io.regsize) |
1350 | info->io.regsize = DEFAULT_REGSPACING; | 1383 | info->io.regsize = DEFAULT_REGSPACING; |
1351 | info->io.regshift = regshifts[intf_num]; | 1384 | info->io.regshift = regshifts[intf_num]; |
1352 | info->irq = 0; | 1385 | info->irq = 0; |
@@ -1404,7 +1437,7 @@ static int acpi_gpe_irq_setup(struct smi_info *info) | |||
1404 | { | 1437 | { |
1405 | acpi_status status; | 1438 | acpi_status status; |
1406 | 1439 | ||
1407 | if (!info->irq) | 1440 | if (! info->irq) |
1408 | return 0; | 1441 | return 0; |
1409 | 1442 | ||
1410 | /* FIXME - is level triggered right? */ | 1443 | /* FIXME - is level triggered right? */ |
@@ -1428,7 +1461,7 @@ static int acpi_gpe_irq_setup(struct smi_info *info) | |||
1428 | 1461 | ||
1429 | static void acpi_gpe_irq_cleanup(struct smi_info *info) | 1462 | static void acpi_gpe_irq_cleanup(struct smi_info *info) |
1430 | { | 1463 | { |
1431 | if (!info->irq) | 1464 | if (! info->irq) |
1432 | return; | 1465 | return; |
1433 | 1466 | ||
1434 | acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe); | 1467 | acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe); |
@@ -1504,10 +1537,10 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) | |||
1504 | addr_space = IPMI_MEM_ADDR_SPACE; | 1537 | addr_space = IPMI_MEM_ADDR_SPACE; |
1505 | else | 1538 | else |
1506 | addr_space = IPMI_IO_ADDR_SPACE; | 1539 | addr_space = IPMI_IO_ADDR_SPACE; |
1507 | if (!is_new_interface(-1, addr_space, spmi->addr.address)) | 1540 | if (! is_new_interface(-1, addr_space, spmi->addr.address)) |
1508 | return -ENODEV; | 1541 | return -ENODEV; |
1509 | 1542 | ||
1510 | if (!spmi->addr.register_bit_width) { | 1543 | if (! spmi->addr.register_bit_width) { |
1511 | acpi_failure = 1; | 1544 | acpi_failure = 1; |
1512 | return -ENODEV; | 1545 | return -ENODEV; |
1513 | } | 1546 | } |
@@ -1534,7 +1567,7 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) | |||
1534 | } | 1567 | } |
1535 | 1568 | ||
1536 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1569 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1537 | if (!info) { | 1570 | if (! info) { |
1538 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (3)\n"); | 1571 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (3)\n"); |
1539 | return -ENOMEM; | 1572 | return -ENOMEM; |
1540 | } | 1573 | } |
@@ -1610,22 +1643,15 @@ typedef struct dmi_ipmi_data | |||
1610 | static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; | 1643 | static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; |
1611 | static int dmi_data_entries; | 1644 | static int dmi_data_entries; |
1612 | 1645 | ||
1613 | typedef struct dmi_header | 1646 | static int __init decode_dmi(struct dmi_header *dm, int intf_num) |
1614 | { | ||
1615 | u8 type; | ||
1616 | u8 length; | ||
1617 | u16 handle; | ||
1618 | } dmi_header_t; | ||
1619 | |||
1620 | static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | ||
1621 | { | 1647 | { |
1622 | u8 __iomem *data = (u8 __iomem *)dm; | 1648 | u8 *data = (u8 *)dm; |
1623 | unsigned long base_addr; | 1649 | unsigned long base_addr; |
1624 | u8 reg_spacing; | 1650 | u8 reg_spacing; |
1625 | u8 len = readb(&dm->length); | 1651 | u8 len = dm->length; |
1626 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; | 1652 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; |
1627 | 1653 | ||
1628 | ipmi_data->type = readb(&data[4]); | 1654 | ipmi_data->type = data[4]; |
1629 | 1655 | ||
1630 | memcpy(&base_addr, data+8, sizeof(unsigned long)); | 1656 | memcpy(&base_addr, data+8, sizeof(unsigned long)); |
1631 | if (len >= 0x11) { | 1657 | if (len >= 0x11) { |
@@ -1640,12 +1666,12 @@ static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | |||
1640 | } | 1666 | } |
1641 | /* If bit 4 of byte 0x10 is set, then the lsb for the address | 1667 | /* If bit 4 of byte 0x10 is set, then the lsb for the address |
1642 | is odd. */ | 1668 | is odd. */ |
1643 | ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4); | 1669 | ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); |
1644 | 1670 | ||
1645 | ipmi_data->irq = readb(&data[0x11]); | 1671 | ipmi_data->irq = data[0x11]; |
1646 | 1672 | ||
1647 | /* The top two bits of byte 0x10 hold the register spacing. */ | 1673 | /* The top two bits of byte 0x10 hold the register spacing. */ |
1648 | reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6; | 1674 | reg_spacing = (data[0x10] & 0xC0) >> 6; |
1649 | switch(reg_spacing){ | 1675 | switch(reg_spacing){ |
1650 | case 0x00: /* Byte boundaries */ | 1676 | case 0x00: /* Byte boundaries */ |
1651 | ipmi_data->offset = 1; | 1677 | ipmi_data->offset = 1; |
@@ -1673,7 +1699,7 @@ static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | |||
1673 | ipmi_data->offset = 1; | 1699 | ipmi_data->offset = 1; |
1674 | } | 1700 | } |
1675 | 1701 | ||
1676 | ipmi_data->slave_addr = readb(&data[6]); | 1702 | ipmi_data->slave_addr = data[6]; |
1677 | 1703 | ||
1678 | if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { | 1704 | if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { |
1679 | dmi_data_entries++; | 1705 | dmi_data_entries++; |
@@ -1685,94 +1711,29 @@ static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | |||
1685 | return -1; | 1711 | return -1; |
1686 | } | 1712 | } |
1687 | 1713 | ||
1688 | static int dmi_table(u32 base, int len, int num) | 1714 | static void __init dmi_find_bmc(void) |
1689 | { | 1715 | { |
1690 | u8 __iomem *buf; | 1716 | struct dmi_device *dev = NULL; |
1691 | struct dmi_header __iomem *dm; | ||
1692 | u8 __iomem *data; | ||
1693 | int i=1; | ||
1694 | int status=-1; | ||
1695 | int intf_num = 0; | 1717 | int intf_num = 0; |
1696 | 1718 | ||
1697 | buf = ioremap(base, len); | 1719 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { |
1698 | if(buf==NULL) | 1720 | if (intf_num >= SI_MAX_DRIVERS) |
1699 | return -1; | 1721 | break; |
1700 | |||
1701 | data = buf; | ||
1702 | |||
1703 | while(i<num && (data - buf) < len) | ||
1704 | { | ||
1705 | dm=(dmi_header_t __iomem *)data; | ||
1706 | |||
1707 | if((data-buf+readb(&dm->length)) >= len) | ||
1708 | break; | ||
1709 | |||
1710 | if (readb(&dm->type) == 38) { | ||
1711 | if (decode_dmi(dm, intf_num) == 0) { | ||
1712 | intf_num++; | ||
1713 | if (intf_num >= SI_MAX_DRIVERS) | ||
1714 | break; | ||
1715 | } | ||
1716 | } | ||
1717 | |||
1718 | data+=readb(&dm->length); | ||
1719 | while((data-buf) < len && (readb(data)||readb(data+1))) | ||
1720 | data++; | ||
1721 | data+=2; | ||
1722 | i++; | ||
1723 | } | ||
1724 | iounmap(buf); | ||
1725 | |||
1726 | return status; | ||
1727 | } | ||
1728 | |||
1729 | static inline int dmi_checksum(u8 *buf) | ||
1730 | { | ||
1731 | u8 sum=0; | ||
1732 | int a; | ||
1733 | |||
1734 | for(a=0; a<15; a++) | ||
1735 | sum+=buf[a]; | ||
1736 | return (sum==0); | ||
1737 | } | ||
1738 | |||
1739 | static int dmi_decode(void) | ||
1740 | { | ||
1741 | u8 buf[15]; | ||
1742 | u32 fp=0xF0000; | ||
1743 | |||
1744 | #ifdef CONFIG_SIMNOW | ||
1745 | return -1; | ||
1746 | #endif | ||
1747 | |||
1748 | while(fp < 0xFFFFF) | ||
1749 | { | ||
1750 | isa_memcpy_fromio(buf, fp, 15); | ||
1751 | if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) | ||
1752 | { | ||
1753 | u16 num=buf[13]<<8|buf[12]; | ||
1754 | u16 len=buf[7]<<8|buf[6]; | ||
1755 | u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]; | ||
1756 | 1722 | ||
1757 | if(dmi_table(base, len, num) == 0) | 1723 | decode_dmi((struct dmi_header *) dev->device_data, intf_num++); |
1758 | return 0; | ||
1759 | } | ||
1760 | fp+=16; | ||
1761 | } | 1724 | } |
1762 | |||
1763 | return -1; | ||
1764 | } | 1725 | } |
1765 | 1726 | ||
1766 | static int try_init_smbios(int intf_num, struct smi_info **new_info) | 1727 | static int try_init_smbios(int intf_num, struct smi_info **new_info) |
1767 | { | 1728 | { |
1768 | struct smi_info *info; | 1729 | struct smi_info *info; |
1769 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; | 1730 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; |
1770 | char *io_type; | 1731 | char *io_type; |
1771 | 1732 | ||
1772 | if (intf_num >= dmi_data_entries) | 1733 | if (intf_num >= dmi_data_entries) |
1773 | return -ENODEV; | 1734 | return -ENODEV; |
1774 | 1735 | ||
1775 | switch(ipmi_data->type) { | 1736 | switch (ipmi_data->type) { |
1776 | case 0x01: /* KCS */ | 1737 | case 0x01: /* KCS */ |
1777 | si_type[intf_num] = "kcs"; | 1738 | si_type[intf_num] = "kcs"; |
1778 | break; | 1739 | break; |
@@ -1787,7 +1748,7 @@ static int try_init_smbios(int intf_num, struct smi_info **new_info) | |||
1787 | } | 1748 | } |
1788 | 1749 | ||
1789 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1750 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1790 | if (!info) { | 1751 | if (! info) { |
1791 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (4)\n"); | 1752 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (4)\n"); |
1792 | return -ENOMEM; | 1753 | return -ENOMEM; |
1793 | } | 1754 | } |
@@ -1811,7 +1772,7 @@ static int try_init_smbios(int intf_num, struct smi_info **new_info) | |||
1811 | 1772 | ||
1812 | regspacings[intf_num] = ipmi_data->offset; | 1773 | regspacings[intf_num] = ipmi_data->offset; |
1813 | info->io.regspacing = regspacings[intf_num]; | 1774 | info->io.regspacing = regspacings[intf_num]; |
1814 | if (!info->io.regspacing) | 1775 | if (! info->io.regspacing) |
1815 | info->io.regspacing = DEFAULT_REGSPACING; | 1776 | info->io.regspacing = DEFAULT_REGSPACING; |
1816 | info->io.regsize = DEFAULT_REGSPACING; | 1777 | info->io.regsize = DEFAULT_REGSPACING; |
1817 | info->io.regshift = regshifts[intf_num]; | 1778 | info->io.regshift = regshifts[intf_num]; |
@@ -1853,14 +1814,14 @@ static int find_pci_smic(int intf_num, struct smi_info **new_info) | |||
1853 | 1814 | ||
1854 | pci_smic_checked = 1; | 1815 | pci_smic_checked = 1; |
1855 | 1816 | ||
1856 | if ((pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID, | 1817 | pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID, NULL); |
1857 | NULL))) | 1818 | if (! pci_dev) { |
1858 | ; | 1819 | pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL); |
1859 | else if ((pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL)) && | 1820 | if (pci_dev && (pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)) |
1860 | pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID) | 1821 | fe_rmc = 1; |
1861 | fe_rmc = 1; | 1822 | else |
1862 | else | 1823 | return -ENODEV; |
1863 | return -ENODEV; | 1824 | } |
1864 | 1825 | ||
1865 | error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr); | 1826 | error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr); |
1866 | if (error) | 1827 | if (error) |
@@ -1873,7 +1834,7 @@ static int find_pci_smic(int intf_num, struct smi_info **new_info) | |||
1873 | } | 1834 | } |
1874 | 1835 | ||
1875 | /* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */ | 1836 | /* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */ |
1876 | if (!(base_addr & 0x0001)) | 1837 | if (! (base_addr & 0x0001)) |
1877 | { | 1838 | { |
1878 | pci_dev_put(pci_dev); | 1839 | pci_dev_put(pci_dev); |
1879 | printk(KERN_ERR | 1840 | printk(KERN_ERR |
@@ -1883,17 +1844,17 @@ static int find_pci_smic(int intf_num, struct smi_info **new_info) | |||
1883 | } | 1844 | } |
1884 | 1845 | ||
1885 | base_addr &= 0xFFFE; | 1846 | base_addr &= 0xFFFE; |
1886 | if (!fe_rmc) | 1847 | if (! fe_rmc) |
1887 | /* Data register starts at base address + 1 in eRMC */ | 1848 | /* Data register starts at base address + 1 in eRMC */ |
1888 | ++base_addr; | 1849 | ++base_addr; |
1889 | 1850 | ||
1890 | if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) { | 1851 | if (! is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) { |
1891 | pci_dev_put(pci_dev); | 1852 | pci_dev_put(pci_dev); |
1892 | return -ENODEV; | 1853 | return -ENODEV; |
1893 | } | 1854 | } |
1894 | 1855 | ||
1895 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1856 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1896 | if (!info) { | 1857 | if (! info) { |
1897 | pci_dev_put(pci_dev); | 1858 | pci_dev_put(pci_dev); |
1898 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n"); | 1859 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n"); |
1899 | return -ENOMEM; | 1860 | return -ENOMEM; |
@@ -1904,7 +1865,7 @@ static int find_pci_smic(int intf_num, struct smi_info **new_info) | |||
1904 | ports[intf_num] = base_addr; | 1865 | ports[intf_num] = base_addr; |
1905 | info->io.info = &(ports[intf_num]); | 1866 | info->io.info = &(ports[intf_num]); |
1906 | info->io.regspacing = regspacings[intf_num]; | 1867 | info->io.regspacing = regspacings[intf_num]; |
1907 | if (!info->io.regspacing) | 1868 | if (! info->io.regspacing) |
1908 | info->io.regspacing = DEFAULT_REGSPACING; | 1869 | info->io.regspacing = DEFAULT_REGSPACING; |
1909 | info->io.regsize = DEFAULT_REGSPACING; | 1870 | info->io.regsize = DEFAULT_REGSPACING; |
1910 | info->io.regshift = regshifts[intf_num]; | 1871 | info->io.regshift = regshifts[intf_num]; |
@@ -1925,7 +1886,7 @@ static int find_pci_smic(int intf_num, struct smi_info **new_info) | |||
1925 | static int try_init_plug_and_play(int intf_num, struct smi_info **new_info) | 1886 | static int try_init_plug_and_play(int intf_num, struct smi_info **new_info) |
1926 | { | 1887 | { |
1927 | #ifdef CONFIG_PCI | 1888 | #ifdef CONFIG_PCI |
1928 | if (find_pci_smic(intf_num, new_info)==0) | 1889 | if (find_pci_smic(intf_num, new_info) == 0) |
1929 | return 0; | 1890 | return 0; |
1930 | #endif | 1891 | #endif |
1931 | /* Include other methods here. */ | 1892 | /* Include other methods here. */ |
@@ -1943,7 +1904,7 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
1943 | int rv = 0; | 1904 | int rv = 0; |
1944 | 1905 | ||
1945 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | 1906 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); |
1946 | if (!resp) | 1907 | if (! resp) |
1947 | return -ENOMEM; | 1908 | return -ENOMEM; |
1948 | 1909 | ||
1949 | /* Do a Get Device ID command, since it comes back with some | 1910 | /* Do a Get Device ID command, since it comes back with some |
@@ -1992,11 +1953,8 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
1992 | } | 1953 | } |
1993 | 1954 | ||
1994 | /* Record info from the get device id, in case we need it. */ | 1955 | /* Record info from the get device id, in case we need it. */ |
1995 | smi_info->ipmi_si_dev_rev = resp[4] & 0xf; | 1956 | memcpy(&smi_info->device_id, &resp[3], |
1996 | smi_info->ipmi_si_fw_rev_major = resp[5] & 0x7f; | 1957 | min_t(unsigned long, resp_len-3, sizeof(smi_info->device_id))); |
1997 | smi_info->ipmi_si_fw_rev_minor = resp[6]; | ||
1998 | smi_info->ipmi_version_major = resp[7] & 0xf; | ||
1999 | smi_info->ipmi_version_minor = resp[7] >> 4; | ||
2000 | 1958 | ||
2001 | out: | 1959 | out: |
2002 | kfree(resp); | 1960 | kfree(resp); |
@@ -2028,7 +1986,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
2028 | struct smi_info *smi = data; | 1986 | struct smi_info *smi = data; |
2029 | 1987 | ||
2030 | out += sprintf(out, "interrupts_enabled: %d\n", | 1988 | out += sprintf(out, "interrupts_enabled: %d\n", |
2031 | smi->irq && !smi->interrupt_disabled); | 1989 | smi->irq && ! smi->interrupt_disabled); |
2032 | out += sprintf(out, "short_timeouts: %ld\n", | 1990 | out += sprintf(out, "short_timeouts: %ld\n", |
2033 | smi->short_timeouts); | 1991 | smi->short_timeouts); |
2034 | out += sprintf(out, "long_timeouts: %ld\n", | 1992 | out += sprintf(out, "long_timeouts: %ld\n", |
@@ -2057,6 +2015,73 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
2057 | return (out - ((char *) page)); | 2015 | return (out - ((char *) page)); |
2058 | } | 2016 | } |
2059 | 2017 | ||
2018 | /* | ||
2019 | * oem_data_avail_to_receive_msg_avail | ||
2020 | * @info - smi_info structure with msg_flags set | ||
2021 | * | ||
2022 | * Converts flags from OEM_DATA_AVAIL to RECEIVE_MSG_AVAIL | ||
2023 | * Returns 1 indicating need to re-run handle_flags(). | ||
2024 | */ | ||
2025 | static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info) | ||
2026 | { | ||
2027 | smi_info->msg_flags = ((smi_info->msg_flags & ~OEM_DATA_AVAIL) | | ||
2028 | RECEIVE_MSG_AVAIL); | ||
2029 | return 1; | ||
2030 | } | ||
2031 | |||
2032 | /* | ||
2033 | * setup_dell_poweredge_oem_data_handler | ||
2034 | * @info - smi_info.device_id must be populated | ||
2035 | * | ||
2036 | * Systems that match, but have firmware version < 1.40 may assert | ||
2037 | * OEM0_DATA_AVAIL on their own, without being told via Set Flags that | ||
2038 | * it's safe to do so. Such systems will de-assert OEM1_DATA_AVAIL | ||
2039 | * upon receipt of IPMI_GET_MSG_CMD, so we should treat these flags | ||
2040 | * as RECEIVE_MSG_AVAIL instead. | ||
2041 | * | ||
2042 | * As Dell has no plans to release IPMI 1.5 firmware that *ever* | ||
2043 | * assert the OEM[012] bits, and if it did, the driver would have to | ||
2044 | * change to handle that properly, we don't actually check for the | ||
2045 | * firmware version. | ||
2046 | * Device ID = 0x20 BMC on PowerEdge 8G servers | ||
2047 | * Device Revision = 0x80 | ||
2048 | * Firmware Revision1 = 0x01 BMC version 1.40 | ||
2049 | * Firmware Revision2 = 0x40 BCD encoded | ||
2050 | * IPMI Version = 0x51 IPMI 1.5 | ||
2051 | * Manufacturer ID = A2 02 00 Dell IANA | ||
2052 | * | ||
2053 | */ | ||
2054 | #define DELL_POWEREDGE_8G_BMC_DEVICE_ID 0x20 | ||
2055 | #define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80 | ||
2056 | #define DELL_POWEREDGE_8G_BMC_IPMI_VERSION 0x51 | ||
2057 | #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00} | ||
2058 | static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info) | ||
2059 | { | ||
2060 | struct ipmi_device_id *id = &smi_info->device_id; | ||
2061 | const char mfr[3]=DELL_IANA_MFR_ID; | ||
2062 | if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) | ||
2063 | && (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID) | ||
2064 | && (id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV) | ||
2065 | && (id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION)) | ||
2066 | { | ||
2067 | smi_info->oem_data_avail_handler = | ||
2068 | oem_data_avail_to_receive_msg_avail; | ||
2069 | } | ||
2070 | } | ||
2071 | |||
2072 | /* | ||
2073 | * setup_oem_data_handler | ||
2074 | * @info - smi_info.device_id must be filled in already | ||
2075 | * | ||
2076 | * Fills in smi_info.device_id.oem_data_available_handler | ||
2077 | * when we know what function to use there. | ||
2078 | */ | ||
2079 | |||
2080 | static void setup_oem_data_handler(struct smi_info *smi_info) | ||
2081 | { | ||
2082 | setup_dell_poweredge_oem_data_handler(smi_info); | ||
2083 | } | ||
2084 | |||
2060 | /* Returns 0 if initialized, or negative on an error. */ | 2085 | /* Returns 0 if initialized, or negative on an error. */ |
2061 | static int init_one_smi(int intf_num, struct smi_info **smi) | 2086 | static int init_one_smi(int intf_num, struct smi_info **smi) |
2062 | { | 2087 | { |
@@ -2068,19 +2093,15 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2068 | if (rv) | 2093 | if (rv) |
2069 | rv = try_init_port(intf_num, &new_smi); | 2094 | rv = try_init_port(intf_num, &new_smi); |
2070 | #ifdef CONFIG_ACPI_INTERPRETER | 2095 | #ifdef CONFIG_ACPI_INTERPRETER |
2071 | if ((rv) && (si_trydefaults)) { | 2096 | if (rv && si_trydefaults) |
2072 | rv = try_init_acpi(intf_num, &new_smi); | 2097 | rv = try_init_acpi(intf_num, &new_smi); |
2073 | } | ||
2074 | #endif | 2098 | #endif |
2075 | #ifdef CONFIG_X86 | 2099 | #ifdef CONFIG_X86 |
2076 | if ((rv) && (si_trydefaults)) { | 2100 | if (rv && si_trydefaults) |
2077 | rv = try_init_smbios(intf_num, &new_smi); | 2101 | rv = try_init_smbios(intf_num, &new_smi); |
2078 | } | ||
2079 | #endif | 2102 | #endif |
2080 | if ((rv) && (si_trydefaults)) { | 2103 | if (rv && si_trydefaults) |
2081 | rv = try_init_plug_and_play(intf_num, &new_smi); | 2104 | rv = try_init_plug_and_play(intf_num, &new_smi); |
2082 | } | ||
2083 | |||
2084 | 2105 | ||
2085 | if (rv) | 2106 | if (rv) |
2086 | return rv; | 2107 | return rv; |
@@ -2090,7 +2111,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2090 | new_smi->si_sm = NULL; | 2111 | new_smi->si_sm = NULL; |
2091 | new_smi->handlers = NULL; | 2112 | new_smi->handlers = NULL; |
2092 | 2113 | ||
2093 | if (!new_smi->irq_setup) { | 2114 | if (! new_smi->irq_setup) { |
2094 | new_smi->irq = irqs[intf_num]; | 2115 | new_smi->irq = irqs[intf_num]; |
2095 | new_smi->irq_setup = std_irq_setup; | 2116 | new_smi->irq_setup = std_irq_setup; |
2096 | new_smi->irq_cleanup = std_irq_cleanup; | 2117 | new_smi->irq_cleanup = std_irq_cleanup; |
@@ -2124,7 +2145,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2124 | 2145 | ||
2125 | /* Allocate the state machine's data and initialize it. */ | 2146 | /* Allocate the state machine's data and initialize it. */ |
2126 | new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); | 2147 | new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); |
2127 | if (!new_smi->si_sm) { | 2148 | if (! new_smi->si_sm) { |
2128 | printk(" Could not allocate state machine memory\n"); | 2149 | printk(" Could not allocate state machine memory\n"); |
2129 | rv = -ENOMEM; | 2150 | rv = -ENOMEM; |
2130 | goto out_err; | 2151 | goto out_err; |
@@ -2155,6 +2176,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2155 | if (rv) | 2176 | if (rv) |
2156 | goto out_err; | 2177 | goto out_err; |
2157 | 2178 | ||
2179 | setup_oem_data_handler(new_smi); | ||
2180 | |||
2158 | /* Try to claim any interrupts. */ | 2181 | /* Try to claim any interrupts. */ |
2159 | new_smi->irq_setup(new_smi); | 2182 | new_smi->irq_setup(new_smi); |
2160 | 2183 | ||
@@ -2188,8 +2211,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2188 | 2211 | ||
2189 | rv = ipmi_register_smi(&handlers, | 2212 | rv = ipmi_register_smi(&handlers, |
2190 | new_smi, | 2213 | new_smi, |
2191 | new_smi->ipmi_version_major, | 2214 | ipmi_version_major(&new_smi->device_id), |
2192 | new_smi->ipmi_version_minor, | 2215 | ipmi_version_minor(&new_smi->device_id), |
2193 | new_smi->slave_addr, | 2216 | new_smi->slave_addr, |
2194 | &(new_smi->intf)); | 2217 | &(new_smi->intf)); |
2195 | if (rv) { | 2218 | if (rv) { |
@@ -2230,7 +2253,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2230 | 2253 | ||
2231 | /* Wait for the timer to stop. This avoids problems with race | 2254 | /* Wait for the timer to stop. This avoids problems with race |
2232 | conditions removing the timer here. */ | 2255 | conditions removing the timer here. */ |
2233 | while (!new_smi->timer_stopped) { | 2256 | while (! new_smi->timer_stopped) { |
2234 | set_current_state(TASK_UNINTERRUPTIBLE); | 2257 | set_current_state(TASK_UNINTERRUPTIBLE); |
2235 | schedule_timeout(1); | 2258 | schedule_timeout(1); |
2236 | } | 2259 | } |
@@ -2270,7 +2293,7 @@ static __init int init_ipmi_si(void) | |||
2270 | /* Parse out the si_type string into its components. */ | 2293 | /* Parse out the si_type string into its components. */ |
2271 | str = si_type_str; | 2294 | str = si_type_str; |
2272 | if (*str != '\0') { | 2295 | if (*str != '\0') { |
2273 | for (i=0; (i<SI_MAX_PARMS) && (*str != '\0'); i++) { | 2296 | for (i = 0; (i < SI_MAX_PARMS) && (*str != '\0'); i++) { |
2274 | si_type[i] = str; | 2297 | si_type[i] = str; |
2275 | str = strchr(str, ','); | 2298 | str = strchr(str, ','); |
2276 | if (str) { | 2299 | if (str) { |
@@ -2282,22 +2305,14 @@ static __init int init_ipmi_si(void) | |||
2282 | } | 2305 | } |
2283 | } | 2306 | } |
2284 | 2307 | ||
2285 | printk(KERN_INFO "IPMI System Interface driver version " | 2308 | printk(KERN_INFO "IPMI System Interface driver.\n"); |
2286 | IPMI_SI_VERSION); | ||
2287 | if (kcs_smi_handlers.version) | ||
2288 | printk(", KCS version %s", kcs_smi_handlers.version); | ||
2289 | if (smic_smi_handlers.version) | ||
2290 | printk(", SMIC version %s", smic_smi_handlers.version); | ||
2291 | if (bt_smi_handlers.version) | ||
2292 | printk(", BT version %s", bt_smi_handlers.version); | ||
2293 | printk("\n"); | ||
2294 | 2309 | ||
2295 | #ifdef CONFIG_X86 | 2310 | #ifdef CONFIG_X86 |
2296 | dmi_decode(); | 2311 | dmi_find_bmc(); |
2297 | #endif | 2312 | #endif |
2298 | 2313 | ||
2299 | rv = init_one_smi(0, &(smi_infos[pos])); | 2314 | rv = init_one_smi(0, &(smi_infos[pos])); |
2300 | if (rv && !ports[0] && si_trydefaults) { | 2315 | if (rv && ! ports[0] && si_trydefaults) { |
2301 | /* If we are trying defaults and the initial port is | 2316 | /* If we are trying defaults and the initial port is |
2302 | not set, then set it. */ | 2317 | not set, then set it. */ |
2303 | si_type[0] = "kcs"; | 2318 | si_type[0] = "kcs"; |
@@ -2319,7 +2334,7 @@ static __init int init_ipmi_si(void) | |||
2319 | if (rv == 0) | 2334 | if (rv == 0) |
2320 | pos++; | 2335 | pos++; |
2321 | 2336 | ||
2322 | for (i=1; i < SI_MAX_PARMS; i++) { | 2337 | for (i = 1; i < SI_MAX_PARMS; i++) { |
2323 | rv = init_one_smi(i, &(smi_infos[pos])); | 2338 | rv = init_one_smi(i, &(smi_infos[pos])); |
2324 | if (rv == 0) | 2339 | if (rv == 0) |
2325 | pos++; | 2340 | pos++; |
@@ -2361,14 +2376,14 @@ static void __exit cleanup_one_si(struct smi_info *to_clean) | |||
2361 | 2376 | ||
2362 | /* Wait for the timer to stop. This avoids problems with race | 2377 | /* Wait for the timer to stop. This avoids problems with race |
2363 | conditions removing the timer here. */ | 2378 | conditions removing the timer here. */ |
2364 | while (!to_clean->timer_stopped) { | 2379 | while (! to_clean->timer_stopped) { |
2365 | set_current_state(TASK_UNINTERRUPTIBLE); | 2380 | set_current_state(TASK_UNINTERRUPTIBLE); |
2366 | schedule_timeout(1); | 2381 | schedule_timeout(1); |
2367 | } | 2382 | } |
2368 | 2383 | ||
2369 | /* Interrupts and timeouts are stopped, now make sure the | 2384 | /* Interrupts and timeouts are stopped, now make sure the |
2370 | interface is in a clean state. */ | 2385 | interface is in a clean state. */ |
2371 | while ((to_clean->curr_msg) || (to_clean->si_state != SI_NORMAL)) { | 2386 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
2372 | poll(to_clean); | 2387 | poll(to_clean); |
2373 | set_current_state(TASK_UNINTERRUPTIBLE); | 2388 | set_current_state(TASK_UNINTERRUPTIBLE); |
2374 | schedule_timeout(1); | 2389 | schedule_timeout(1); |
@@ -2392,13 +2407,15 @@ static __exit void cleanup_ipmi_si(void) | |||
2392 | { | 2407 | { |
2393 | int i; | 2408 | int i; |
2394 | 2409 | ||
2395 | if (!initialized) | 2410 | if (! initialized) |
2396 | return; | 2411 | return; |
2397 | 2412 | ||
2398 | for (i=0; i<SI_MAX_DRIVERS; i++) { | 2413 | for (i = 0; i < SI_MAX_DRIVERS; i++) { |
2399 | cleanup_one_si(smi_infos[i]); | 2414 | cleanup_one_si(smi_infos[i]); |
2400 | } | 2415 | } |
2401 | } | 2416 | } |
2402 | module_exit(cleanup_ipmi_si); | 2417 | module_exit(cleanup_ipmi_si); |
2403 | 2418 | ||
2404 | MODULE_LICENSE("GPL"); | 2419 | MODULE_LICENSE("GPL"); |
2420 | MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); | ||
2421 | MODULE_DESCRIPTION("Interface to the IPMI driver for the KCS, SMIC, and BT system interfaces."); | ||