diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_si_intf.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 1057 |
1 files changed, 572 insertions, 485 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e59b638766ef..12f858dc9994 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
53 | #include <linux/ioport.h> | 53 | #include <linux/ioport.h> |
54 | #include <linux/notifier.h> | 54 | #include <linux/notifier.h> |
55 | #include <linux/mutex.h> | ||
55 | #include <linux/kthread.h> | 56 | #include <linux/kthread.h> |
56 | #include <asm/irq.h> | 57 | #include <asm/irq.h> |
57 | #ifdef CONFIG_HIGH_RES_TIMERS | 58 | #ifdef CONFIG_HIGH_RES_TIMERS |
@@ -109,21 +110,15 @@ enum si_intf_state { | |||
109 | enum si_type { | 110 | enum si_type { |
110 | SI_KCS, SI_SMIC, SI_BT | 111 | SI_KCS, SI_SMIC, SI_BT |
111 | }; | 112 | }; |
113 | static char *si_to_str[] = { "KCS", "SMIC", "BT" }; | ||
112 | 114 | ||
113 | struct ipmi_device_id { | 115 | #define DEVICE_NAME "ipmi_si" |
114 | unsigned char device_id; | 116 | |
115 | unsigned char device_revision; | 117 | static struct device_driver ipmi_driver = |
116 | unsigned char firmware_revision_1; | 118 | { |
117 | unsigned char firmware_revision_2; | 119 | .name = DEVICE_NAME, |
118 | unsigned char ipmi_version; | 120 | .bus = &platform_bus_type |
119 | unsigned char additional_device_support; | 121 | }; |
120 | unsigned char manufacturer_id[3]; | ||
121 | unsigned char product_id[2]; | ||
122 | unsigned char aux_firmware_revision[4]; | ||
123 | } __attribute__((packed)); | ||
124 | |||
125 | #define ipmi_version_major(v) ((v)->ipmi_version & 0xf) | ||
126 | #define ipmi_version_minor(v) ((v)->ipmi_version >> 4) | ||
127 | 122 | ||
128 | struct smi_info | 123 | struct smi_info |
129 | { | 124 | { |
@@ -147,6 +142,9 @@ struct smi_info | |||
147 | int (*irq_setup)(struct smi_info *info); | 142 | int (*irq_setup)(struct smi_info *info); |
148 | void (*irq_cleanup)(struct smi_info *info); | 143 | void (*irq_cleanup)(struct smi_info *info); |
149 | unsigned int io_size; | 144 | unsigned int io_size; |
145 | char *addr_source; /* ACPI, PCI, SMBIOS, hardcode, default. */ | ||
146 | void (*addr_source_cleanup)(struct smi_info *info); | ||
147 | void *addr_source_data; | ||
150 | 148 | ||
151 | /* Per-OEM handler, called from handle_flags(). | 149 | /* Per-OEM handler, called from handle_flags(). |
152 | Returns 1 when handle_flags() needs to be re-run | 150 | Returns 1 when handle_flags() needs to be re-run |
@@ -203,8 +201,17 @@ struct smi_info | |||
203 | interrupts. */ | 201 | interrupts. */ |
204 | int interrupt_disabled; | 202 | int interrupt_disabled; |
205 | 203 | ||
204 | /* From the get device id response... */ | ||
206 | struct ipmi_device_id device_id; | 205 | struct ipmi_device_id device_id; |
207 | 206 | ||
207 | /* Driver model stuff. */ | ||
208 | struct device *dev; | ||
209 | struct platform_device *pdev; | ||
210 | |||
211 | /* True if we allocated the device, false if it came from | ||
212 | * someplace else (like PCI). */ | ||
213 | int dev_registered; | ||
214 | |||
208 | /* Slave address, could be reported from DMI. */ | 215 | /* Slave address, could be reported from DMI. */ |
209 | unsigned char slave_addr; | 216 | unsigned char slave_addr; |
210 | 217 | ||
@@ -224,8 +231,12 @@ struct smi_info | |||
224 | unsigned long incoming_messages; | 231 | unsigned long incoming_messages; |
225 | 232 | ||
226 | struct task_struct *thread; | 233 | struct task_struct *thread; |
234 | |||
235 | struct list_head link; | ||
227 | }; | 236 | }; |
228 | 237 | ||
238 | static int try_smi_init(struct smi_info *smi); | ||
239 | |||
229 | static struct notifier_block *xaction_notifier_list; | 240 | static struct notifier_block *xaction_notifier_list; |
230 | static int register_xaction_notifier(struct notifier_block * nb) | 241 | static int register_xaction_notifier(struct notifier_block * nb) |
231 | { | 242 | { |
@@ -271,13 +282,13 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
271 | spin_lock(&(smi_info->msg_lock)); | 282 | spin_lock(&(smi_info->msg_lock)); |
272 | 283 | ||
273 | /* Pick the high priority queue first. */ | 284 | /* Pick the high priority queue first. */ |
274 | if (! list_empty(&(smi_info->hp_xmit_msgs))) { | 285 | if (!list_empty(&(smi_info->hp_xmit_msgs))) { |
275 | entry = smi_info->hp_xmit_msgs.next; | 286 | entry = smi_info->hp_xmit_msgs.next; |
276 | } else if (! list_empty(&(smi_info->xmit_msgs))) { | 287 | } else if (!list_empty(&(smi_info->xmit_msgs))) { |
277 | entry = smi_info->xmit_msgs.next; | 288 | entry = smi_info->xmit_msgs.next; |
278 | } | 289 | } |
279 | 290 | ||
280 | if (! entry) { | 291 | if (!entry) { |
281 | smi_info->curr_msg = NULL; | 292 | smi_info->curr_msg = NULL; |
282 | rv = SI_SM_IDLE; | 293 | rv = SI_SM_IDLE; |
283 | } else { | 294 | } else { |
@@ -344,7 +355,7 @@ static void start_clear_flags(struct smi_info *smi_info) | |||
344 | memory, we will re-enable the interrupt. */ | 355 | memory, we will re-enable the interrupt. */ |
345 | static inline void disable_si_irq(struct smi_info *smi_info) | 356 | static inline void disable_si_irq(struct smi_info *smi_info) |
346 | { | 357 | { |
347 | if ((smi_info->irq) && (! smi_info->interrupt_disabled)) { | 358 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
348 | disable_irq_nosync(smi_info->irq); | 359 | disable_irq_nosync(smi_info->irq); |
349 | smi_info->interrupt_disabled = 1; | 360 | smi_info->interrupt_disabled = 1; |
350 | } | 361 | } |
@@ -375,7 +386,7 @@ static void handle_flags(struct smi_info *smi_info) | |||
375 | } else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) { | 386 | } else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) { |
376 | /* Messages available. */ | 387 | /* Messages available. */ |
377 | smi_info->curr_msg = ipmi_alloc_smi_msg(); | 388 | smi_info->curr_msg = ipmi_alloc_smi_msg(); |
378 | if (! smi_info->curr_msg) { | 389 | if (!smi_info->curr_msg) { |
379 | disable_si_irq(smi_info); | 390 | disable_si_irq(smi_info); |
380 | smi_info->si_state = SI_NORMAL; | 391 | smi_info->si_state = SI_NORMAL; |
381 | return; | 392 | return; |
@@ -394,7 +405,7 @@ static void handle_flags(struct smi_info *smi_info) | |||
394 | } else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) { | 405 | } else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) { |
395 | /* Events available. */ | 406 | /* Events available. */ |
396 | smi_info->curr_msg = ipmi_alloc_smi_msg(); | 407 | smi_info->curr_msg = ipmi_alloc_smi_msg(); |
397 | if (! smi_info->curr_msg) { | 408 | if (!smi_info->curr_msg) { |
398 | disable_si_irq(smi_info); | 409 | disable_si_irq(smi_info); |
399 | smi_info->si_state = SI_NORMAL; | 410 | smi_info->si_state = SI_NORMAL; |
400 | return; | 411 | return; |
@@ -430,7 +441,7 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
430 | #endif | 441 | #endif |
431 | switch (smi_info->si_state) { | 442 | switch (smi_info->si_state) { |
432 | case SI_NORMAL: | 443 | case SI_NORMAL: |
433 | if (! smi_info->curr_msg) | 444 | if (!smi_info->curr_msg) |
434 | break; | 445 | break; |
435 | 446 | ||
436 | smi_info->curr_msg->rsp_size | 447 | smi_info->curr_msg->rsp_size |
@@ -880,7 +891,7 @@ static void smi_timeout(unsigned long data) | |||
880 | 891 | ||
881 | smi_info->last_timeout_jiffies = jiffies_now; | 892 | smi_info->last_timeout_jiffies = jiffies_now; |
882 | 893 | ||
883 | if ((smi_info->irq) && (! smi_info->interrupt_disabled)) { | 894 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
884 | /* Running with interrupts, only do long timeouts. */ | 895 | /* Running with interrupts, only do long timeouts. */ |
885 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | 896 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; |
886 | spin_lock_irqsave(&smi_info->count_lock, flags); | 897 | spin_lock_irqsave(&smi_info->count_lock, flags); |
@@ -974,15 +985,10 @@ static struct ipmi_smi_handlers handlers = | |||
974 | a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */ | 985 | a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */ |
975 | 986 | ||
976 | #define SI_MAX_PARMS 4 | 987 | #define SI_MAX_PARMS 4 |
977 | #define SI_MAX_DRIVERS ((SI_MAX_PARMS * 2) + 2) | 988 | static LIST_HEAD(smi_infos); |
978 | static struct smi_info *smi_infos[SI_MAX_DRIVERS] = | 989 | static DECLARE_MUTEX(smi_infos_lock); |
979 | { NULL, NULL, NULL, NULL }; | 990 | static int smi_num; /* Used to sequence the SMIs */ |
980 | 991 | ||
981 | #define DEVICE_NAME "ipmi_si" | ||
982 | |||
983 | #define DEFAULT_KCS_IO_PORT 0xca2 | ||
984 | #define DEFAULT_SMIC_IO_PORT 0xca9 | ||
985 | #define DEFAULT_BT_IO_PORT 0xe4 | ||
986 | #define DEFAULT_REGSPACING 1 | 992 | #define DEFAULT_REGSPACING 1 |
987 | 993 | ||
988 | static int si_trydefaults = 1; | 994 | static int si_trydefaults = 1; |
@@ -1053,38 +1059,23 @@ MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for" | |||
1053 | " by interface number."); | 1059 | " by interface number."); |
1054 | 1060 | ||
1055 | 1061 | ||
1062 | #define IPMI_IO_ADDR_SPACE 0 | ||
1056 | #define IPMI_MEM_ADDR_SPACE 1 | 1063 | #define IPMI_MEM_ADDR_SPACE 1 |
1057 | #define IPMI_IO_ADDR_SPACE 2 | 1064 | static char *addr_space_to_str[] = { "I/O", "memory" }; |
1058 | 1065 | ||
1059 | #if defined(CONFIG_ACPI) || defined(CONFIG_DMI) || defined(CONFIG_PCI) | 1066 | static void std_irq_cleanup(struct smi_info *info) |
1060 | static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr) | ||
1061 | { | 1067 | { |
1062 | int i; | 1068 | if (info->si_type == SI_BT) |
1063 | 1069 | /* Disable the interrupt in the BT interface. */ | |
1064 | for (i = 0; i < SI_MAX_PARMS; ++i) { | 1070 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0); |
1065 | /* Don't check our address. */ | 1071 | free_irq(info->irq, info); |
1066 | if (i == intf) | ||
1067 | continue; | ||
1068 | if (si_type[i] != NULL) { | ||
1069 | if ((addr_space == IPMI_MEM_ADDR_SPACE && | ||
1070 | base_addr == addrs[i]) || | ||
1071 | (addr_space == IPMI_IO_ADDR_SPACE && | ||
1072 | base_addr == ports[i])) | ||
1073 | return 0; | ||
1074 | } | ||
1075 | else | ||
1076 | break; | ||
1077 | } | ||
1078 | |||
1079 | return 1; | ||
1080 | } | 1072 | } |
1081 | #endif | ||
1082 | 1073 | ||
1083 | static int std_irq_setup(struct smi_info *info) | 1074 | static int std_irq_setup(struct smi_info *info) |
1084 | { | 1075 | { |
1085 | int rv; | 1076 | int rv; |
1086 | 1077 | ||
1087 | if (! info->irq) | 1078 | if (!info->irq) |
1088 | return 0; | 1079 | return 0; |
1089 | 1080 | ||
1090 | if (info->si_type == SI_BT) { | 1081 | if (info->si_type == SI_BT) { |
@@ -1093,7 +1084,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1093 | SA_INTERRUPT, | 1084 | SA_INTERRUPT, |
1094 | DEVICE_NAME, | 1085 | DEVICE_NAME, |
1095 | info); | 1086 | info); |
1096 | if (! rv) | 1087 | if (!rv) |
1097 | /* Enable the interrupt in the BT interface. */ | 1088 | /* Enable the interrupt in the BT interface. */ |
1098 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, | 1089 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, |
1099 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); | 1090 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); |
@@ -1110,88 +1101,77 @@ static int std_irq_setup(struct smi_info *info) | |||
1110 | DEVICE_NAME, info->irq); | 1101 | DEVICE_NAME, info->irq); |
1111 | info->irq = 0; | 1102 | info->irq = 0; |
1112 | } else { | 1103 | } else { |
1104 | info->irq_cleanup = std_irq_cleanup; | ||
1113 | printk(" Using irq %d\n", info->irq); | 1105 | printk(" Using irq %d\n", info->irq); |
1114 | } | 1106 | } |
1115 | 1107 | ||
1116 | return rv; | 1108 | return rv; |
1117 | } | 1109 | } |
1118 | 1110 | ||
1119 | static void std_irq_cleanup(struct smi_info *info) | ||
1120 | { | ||
1121 | if (! info->irq) | ||
1122 | return; | ||
1123 | |||
1124 | if (info->si_type == SI_BT) | ||
1125 | /* Disable the interrupt in the BT interface. */ | ||
1126 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0); | ||
1127 | free_irq(info->irq, info); | ||
1128 | } | ||
1129 | |||
1130 | static unsigned char port_inb(struct si_sm_io *io, unsigned int offset) | 1111 | static unsigned char port_inb(struct si_sm_io *io, unsigned int offset) |
1131 | { | 1112 | { |
1132 | unsigned int *addr = io->info; | 1113 | unsigned int addr = io->addr_data; |
1133 | 1114 | ||
1134 | return inb((*addr)+(offset*io->regspacing)); | 1115 | return inb(addr + (offset * io->regspacing)); |
1135 | } | 1116 | } |
1136 | 1117 | ||
1137 | static void port_outb(struct si_sm_io *io, unsigned int offset, | 1118 | static void port_outb(struct si_sm_io *io, unsigned int offset, |
1138 | unsigned char b) | 1119 | unsigned char b) |
1139 | { | 1120 | { |
1140 | unsigned int *addr = io->info; | 1121 | unsigned int addr = io->addr_data; |
1141 | 1122 | ||
1142 | outb(b, (*addr)+(offset * io->regspacing)); | 1123 | outb(b, addr + (offset * io->regspacing)); |
1143 | } | 1124 | } |
1144 | 1125 | ||
1145 | static unsigned char port_inw(struct si_sm_io *io, unsigned int offset) | 1126 | static unsigned char port_inw(struct si_sm_io *io, unsigned int offset) |
1146 | { | 1127 | { |
1147 | unsigned int *addr = io->info; | 1128 | unsigned int addr = io->addr_data; |
1148 | 1129 | ||
1149 | return (inw((*addr)+(offset * io->regspacing)) >> io->regshift) & 0xff; | 1130 | return (inw(addr + (offset * io->regspacing)) >> io->regshift) & 0xff; |
1150 | } | 1131 | } |
1151 | 1132 | ||
1152 | static void port_outw(struct si_sm_io *io, unsigned int offset, | 1133 | static void port_outw(struct si_sm_io *io, unsigned int offset, |
1153 | unsigned char b) | 1134 | unsigned char b) |
1154 | { | 1135 | { |
1155 | unsigned int *addr = io->info; | 1136 | unsigned int addr = io->addr_data; |
1156 | 1137 | ||
1157 | outw(b << io->regshift, (*addr)+(offset * io->regspacing)); | 1138 | outw(b << io->regshift, addr + (offset * io->regspacing)); |
1158 | } | 1139 | } |
1159 | 1140 | ||
1160 | static unsigned char port_inl(struct si_sm_io *io, unsigned int offset) | 1141 | static unsigned char port_inl(struct si_sm_io *io, unsigned int offset) |
1161 | { | 1142 | { |
1162 | unsigned int *addr = io->info; | 1143 | unsigned int addr = io->addr_data; |
1163 | 1144 | ||
1164 | return (inl((*addr)+(offset * io->regspacing)) >> io->regshift) & 0xff; | 1145 | return (inl(addr + (offset * io->regspacing)) >> io->regshift) & 0xff; |
1165 | } | 1146 | } |
1166 | 1147 | ||
1167 | static void port_outl(struct si_sm_io *io, unsigned int offset, | 1148 | static void port_outl(struct si_sm_io *io, unsigned int offset, |
1168 | unsigned char b) | 1149 | unsigned char b) |
1169 | { | 1150 | { |
1170 | unsigned int *addr = io->info; | 1151 | unsigned int addr = io->addr_data; |
1171 | 1152 | ||
1172 | outl(b << io->regshift, (*addr)+(offset * io->regspacing)); | 1153 | outl(b << io->regshift, addr+(offset * io->regspacing)); |
1173 | } | 1154 | } |
1174 | 1155 | ||
1175 | static void port_cleanup(struct smi_info *info) | 1156 | static void port_cleanup(struct smi_info *info) |
1176 | { | 1157 | { |
1177 | unsigned int *addr = info->io.info; | 1158 | unsigned int addr = info->io.addr_data; |
1178 | int mapsize; | 1159 | int mapsize; |
1179 | 1160 | ||
1180 | if (addr && (*addr)) { | 1161 | if (addr) { |
1181 | mapsize = ((info->io_size * info->io.regspacing) | 1162 | mapsize = ((info->io_size * info->io.regspacing) |
1182 | - (info->io.regspacing - info->io.regsize)); | 1163 | - (info->io.regspacing - info->io.regsize)); |
1183 | 1164 | ||
1184 | release_region (*addr, mapsize); | 1165 | release_region (addr, mapsize); |
1185 | } | 1166 | } |
1186 | kfree(info); | ||
1187 | } | 1167 | } |
1188 | 1168 | ||
1189 | static int port_setup(struct smi_info *info) | 1169 | static int port_setup(struct smi_info *info) |
1190 | { | 1170 | { |
1191 | unsigned int *addr = info->io.info; | 1171 | unsigned int addr = info->io.addr_data; |
1192 | int mapsize; | 1172 | int mapsize; |
1193 | 1173 | ||
1194 | if (! addr || (! *addr)) | 1174 | if (!addr) |
1195 | return -ENODEV; | 1175 | return -ENODEV; |
1196 | 1176 | ||
1197 | info->io_cleanup = port_cleanup; | 1177 | info->io_cleanup = port_cleanup; |
@@ -1225,51 +1205,11 @@ static int port_setup(struct smi_info *info) | |||
1225 | mapsize = ((info->io_size * info->io.regspacing) | 1205 | mapsize = ((info->io_size * info->io.regspacing) |
1226 | - (info->io.regspacing - info->io.regsize)); | 1206 | - (info->io.regspacing - info->io.regsize)); |
1227 | 1207 | ||
1228 | if (request_region(*addr, mapsize, DEVICE_NAME) == NULL) | 1208 | if (request_region(addr, mapsize, DEVICE_NAME) == NULL) |
1229 | return -EIO; | 1209 | return -EIO; |
1230 | return 0; | 1210 | return 0; |
1231 | } | 1211 | } |
1232 | 1212 | ||
1233 | static int try_init_port(int intf_num, struct smi_info **new_info) | ||
1234 | { | ||
1235 | struct smi_info *info; | ||
1236 | |||
1237 | if (! ports[intf_num]) | ||
1238 | return -ENODEV; | ||
1239 | |||
1240 | if (! is_new_interface(intf_num, IPMI_IO_ADDR_SPACE, | ||
1241 | ports[intf_num])) | ||
1242 | return -ENODEV; | ||
1243 | |||
1244 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
1245 | if (! info) { | ||
1246 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (1)\n"); | ||
1247 | return -ENOMEM; | ||
1248 | } | ||
1249 | memset(info, 0, sizeof(*info)); | ||
1250 | |||
1251 | info->io_setup = port_setup; | ||
1252 | info->io.info = &(ports[intf_num]); | ||
1253 | info->io.addr = NULL; | ||
1254 | info->io.regspacing = regspacings[intf_num]; | ||
1255 | if (! info->io.regspacing) | ||
1256 | info->io.regspacing = DEFAULT_REGSPACING; | ||
1257 | info->io.regsize = regsizes[intf_num]; | ||
1258 | if (! info->io.regsize) | ||
1259 | info->io.regsize = DEFAULT_REGSPACING; | ||
1260 | info->io.regshift = regshifts[intf_num]; | ||
1261 | info->irq = 0; | ||
1262 | info->irq_setup = NULL; | ||
1263 | *new_info = info; | ||
1264 | |||
1265 | if (si_type[intf_num] == NULL) | ||
1266 | si_type[intf_num] = "kcs"; | ||
1267 | |||
1268 | printk("ipmi_si: Trying \"%s\" at I/O port 0x%x\n", | ||
1269 | si_type[intf_num], ports[intf_num]); | ||
1270 | return 0; | ||
1271 | } | ||
1272 | |||
1273 | static unsigned char intf_mem_inb(struct si_sm_io *io, unsigned int offset) | 1213 | static unsigned char intf_mem_inb(struct si_sm_io *io, unsigned int offset) |
1274 | { | 1214 | { |
1275 | return readb((io->addr)+(offset * io->regspacing)); | 1215 | return readb((io->addr)+(offset * io->regspacing)); |
@@ -1321,7 +1261,7 @@ static void mem_outq(struct si_sm_io *io, unsigned int offset, | |||
1321 | 1261 | ||
1322 | static void mem_cleanup(struct smi_info *info) | 1262 | static void mem_cleanup(struct smi_info *info) |
1323 | { | 1263 | { |
1324 | unsigned long *addr = info->io.info; | 1264 | unsigned long addr = info->io.addr_data; |
1325 | int mapsize; | 1265 | int mapsize; |
1326 | 1266 | ||
1327 | if (info->io.addr) { | 1267 | if (info->io.addr) { |
@@ -1330,17 +1270,16 @@ static void mem_cleanup(struct smi_info *info) | |||
1330 | mapsize = ((info->io_size * info->io.regspacing) | 1270 | mapsize = ((info->io_size * info->io.regspacing) |
1331 | - (info->io.regspacing - info->io.regsize)); | 1271 | - (info->io.regspacing - info->io.regsize)); |
1332 | 1272 | ||
1333 | release_mem_region(*addr, mapsize); | 1273 | release_mem_region(addr, mapsize); |
1334 | } | 1274 | } |
1335 | kfree(info); | ||
1336 | } | 1275 | } |
1337 | 1276 | ||
1338 | static int mem_setup(struct smi_info *info) | 1277 | static int mem_setup(struct smi_info *info) |
1339 | { | 1278 | { |
1340 | unsigned long *addr = info->io.info; | 1279 | unsigned long addr = info->io.addr_data; |
1341 | int mapsize; | 1280 | int mapsize; |
1342 | 1281 | ||
1343 | if (! addr || (! *addr)) | 1282 | if (!addr) |
1344 | return -ENODEV; | 1283 | return -ENODEV; |
1345 | 1284 | ||
1346 | info->io_cleanup = mem_cleanup; | 1285 | info->io_cleanup = mem_cleanup; |
@@ -1380,57 +1319,83 @@ static int mem_setup(struct smi_info *info) | |||
1380 | mapsize = ((info->io_size * info->io.regspacing) | 1319 | mapsize = ((info->io_size * info->io.regspacing) |
1381 | - (info->io.regspacing - info->io.regsize)); | 1320 | - (info->io.regspacing - info->io.regsize)); |
1382 | 1321 | ||
1383 | if (request_mem_region(*addr, mapsize, DEVICE_NAME) == NULL) | 1322 | if (request_mem_region(addr, mapsize, DEVICE_NAME) == NULL) |
1384 | return -EIO; | 1323 | return -EIO; |
1385 | 1324 | ||
1386 | info->io.addr = ioremap(*addr, mapsize); | 1325 | info->io.addr = ioremap(addr, mapsize); |
1387 | if (info->io.addr == NULL) { | 1326 | if (info->io.addr == NULL) { |
1388 | release_mem_region(*addr, mapsize); | 1327 | release_mem_region(addr, mapsize); |
1389 | return -EIO; | 1328 | return -EIO; |
1390 | } | 1329 | } |
1391 | return 0; | 1330 | return 0; |
1392 | } | 1331 | } |
1393 | 1332 | ||
1394 | static int try_init_mem(int intf_num, struct smi_info **new_info) | 1333 | |
1334 | static __devinit void hardcode_find_bmc(void) | ||
1395 | { | 1335 | { |
1336 | int i; | ||
1396 | struct smi_info *info; | 1337 | struct smi_info *info; |
1397 | 1338 | ||
1398 | if (! addrs[intf_num]) | 1339 | for (i = 0; i < SI_MAX_PARMS; i++) { |
1399 | return -ENODEV; | 1340 | if (!ports[i] && !addrs[i]) |
1341 | continue; | ||
1400 | 1342 | ||
1401 | if (! is_new_interface(intf_num, IPMI_MEM_ADDR_SPACE, | 1343 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
1402 | addrs[intf_num])) | 1344 | if (!info) |
1403 | return -ENODEV; | 1345 | return; |
1404 | 1346 | ||
1405 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1347 | info->addr_source = "hardcoded"; |
1406 | if (! info) { | ||
1407 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (2)\n"); | ||
1408 | return -ENOMEM; | ||
1409 | } | ||
1410 | memset(info, 0, sizeof(*info)); | ||
1411 | 1348 | ||
1412 | info->io_setup = mem_setup; | 1349 | if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) { |
1413 | info->io.info = &addrs[intf_num]; | 1350 | info->si_type = SI_KCS; |
1414 | info->io.addr = NULL; | 1351 | } else if (strcmp(si_type[i], "smic") == 0) { |
1415 | info->io.regspacing = regspacings[intf_num]; | 1352 | info->si_type = SI_SMIC; |
1416 | if (! info->io.regspacing) | 1353 | } else if (strcmp(si_type[i], "bt") == 0) { |
1417 | info->io.regspacing = DEFAULT_REGSPACING; | 1354 | info->si_type = SI_BT; |
1418 | info->io.regsize = regsizes[intf_num]; | 1355 | } else { |
1419 | if (! info->io.regsize) | 1356 | printk(KERN_WARNING |
1420 | info->io.regsize = DEFAULT_REGSPACING; | 1357 | "ipmi_si: Interface type specified " |
1421 | info->io.regshift = regshifts[intf_num]; | 1358 | "for interface %d, was invalid: %s\n", |
1422 | info->irq = 0; | 1359 | i, si_type[i]); |
1423 | info->irq_setup = NULL; | 1360 | kfree(info); |
1424 | *new_info = info; | 1361 | continue; |
1362 | } | ||
1425 | 1363 | ||
1426 | if (si_type[intf_num] == NULL) | 1364 | if (ports[i]) { |
1427 | si_type[intf_num] = "kcs"; | 1365 | /* An I/O port */ |
1366 | info->io_setup = port_setup; | ||
1367 | info->io.addr_data = ports[i]; | ||
1368 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | ||
1369 | } else if (addrs[i]) { | ||
1370 | /* A memory port */ | ||
1371 | info->io_setup = mem_setup; | ||
1372 | info->io.addr_data = addrs[i]; | ||
1373 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
1374 | } else { | ||
1375 | printk(KERN_WARNING | ||
1376 | "ipmi_si: Interface type specified " | ||
1377 | "for interface %d, " | ||
1378 | "but port and address were not set or " | ||
1379 | "set to zero.\n", i); | ||
1380 | kfree(info); | ||
1381 | continue; | ||
1382 | } | ||
1428 | 1383 | ||
1429 | printk("ipmi_si: Trying \"%s\" at memory address 0x%lx\n", | 1384 | info->io.addr = NULL; |
1430 | si_type[intf_num], addrs[intf_num]); | 1385 | info->io.regspacing = regspacings[i]; |
1431 | return 0; | 1386 | if (!info->io.regspacing) |
1432 | } | 1387 | info->io.regspacing = DEFAULT_REGSPACING; |
1388 | info->io.regsize = regsizes[i]; | ||
1389 | if (!info->io.regsize) | ||
1390 | info->io.regsize = DEFAULT_REGSPACING; | ||
1391 | info->io.regshift = regshifts[i]; | ||
1392 | info->irq = irqs[i]; | ||
1393 | if (info->irq) | ||
1394 | info->irq_setup = std_irq_setup; | ||
1433 | 1395 | ||
1396 | try_smi_init(info); | ||
1397 | } | ||
1398 | } | ||
1434 | 1399 | ||
1435 | #ifdef CONFIG_ACPI | 1400 | #ifdef CONFIG_ACPI |
1436 | 1401 | ||
@@ -1470,11 +1435,19 @@ static u32 ipmi_acpi_gpe(void *context) | |||
1470 | return ACPI_INTERRUPT_HANDLED; | 1435 | return ACPI_INTERRUPT_HANDLED; |
1471 | } | 1436 | } |
1472 | 1437 | ||
1438 | static void acpi_gpe_irq_cleanup(struct smi_info *info) | ||
1439 | { | ||
1440 | if (!info->irq) | ||
1441 | return; | ||
1442 | |||
1443 | acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe); | ||
1444 | } | ||
1445 | |||
1473 | static int acpi_gpe_irq_setup(struct smi_info *info) | 1446 | static int acpi_gpe_irq_setup(struct smi_info *info) |
1474 | { | 1447 | { |
1475 | acpi_status status; | 1448 | acpi_status status; |
1476 | 1449 | ||
1477 | if (! info->irq) | 1450 | if (!info->irq) |
1478 | return 0; | 1451 | return 0; |
1479 | 1452 | ||
1480 | /* FIXME - is level triggered right? */ | 1453 | /* FIXME - is level triggered right? */ |
@@ -1491,19 +1464,12 @@ static int acpi_gpe_irq_setup(struct smi_info *info) | |||
1491 | info->irq = 0; | 1464 | info->irq = 0; |
1492 | return -EINVAL; | 1465 | return -EINVAL; |
1493 | } else { | 1466 | } else { |
1467 | info->irq_cleanup = acpi_gpe_irq_cleanup; | ||
1494 | printk(" Using ACPI GPE %d\n", info->irq); | 1468 | printk(" Using ACPI GPE %d\n", info->irq); |
1495 | return 0; | 1469 | return 0; |
1496 | } | 1470 | } |
1497 | } | 1471 | } |
1498 | 1472 | ||
1499 | static void acpi_gpe_irq_cleanup(struct smi_info *info) | ||
1500 | { | ||
1501 | if (! info->irq) | ||
1502 | return; | ||
1503 | |||
1504 | acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe); | ||
1505 | } | ||
1506 | |||
1507 | /* | 1473 | /* |
1508 | * Defined at | 1474 | * Defined at |
1509 | * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf | 1475 | * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf |
@@ -1546,28 +1512,12 @@ struct SPMITable { | |||
1546 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ | 1512 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ |
1547 | }; | 1513 | }; |
1548 | 1514 | ||
1549 | static int try_init_acpi(int intf_num, struct smi_info **new_info) | 1515 | static __devinit int try_init_acpi(struct SPMITable *spmi) |
1550 | { | 1516 | { |
1551 | struct smi_info *info; | 1517 | struct smi_info *info; |
1552 | acpi_status status; | ||
1553 | struct SPMITable *spmi; | ||
1554 | char *io_type; | 1518 | char *io_type; |
1555 | u8 addr_space; | 1519 | u8 addr_space; |
1556 | 1520 | ||
1557 | if (acpi_disabled) | ||
1558 | return -ENODEV; | ||
1559 | |||
1560 | if (acpi_failure) | ||
1561 | return -ENODEV; | ||
1562 | |||
1563 | status = acpi_get_firmware_table("SPMI", intf_num+1, | ||
1564 | ACPI_LOGICAL_ADDRESSING, | ||
1565 | (struct acpi_table_header **) &spmi); | ||
1566 | if (status != AE_OK) { | ||
1567 | acpi_failure = 1; | ||
1568 | return -ENODEV; | ||
1569 | } | ||
1570 | |||
1571 | if (spmi->IPMIlegacy != 1) { | 1521 | if (spmi->IPMIlegacy != 1) { |
1572 | printk(KERN_INFO "IPMI: Bad SPMI legacy %d\n", spmi->IPMIlegacy); | 1522 | printk(KERN_INFO "IPMI: Bad SPMI legacy %d\n", spmi->IPMIlegacy); |
1573 | return -ENODEV; | 1523 | return -ENODEV; |
@@ -1577,47 +1527,42 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) | |||
1577 | addr_space = IPMI_MEM_ADDR_SPACE; | 1527 | addr_space = IPMI_MEM_ADDR_SPACE; |
1578 | else | 1528 | else |
1579 | addr_space = IPMI_IO_ADDR_SPACE; | 1529 | addr_space = IPMI_IO_ADDR_SPACE; |
1580 | if (! is_new_interface(-1, addr_space, spmi->addr.address)) | 1530 | |
1581 | return -ENODEV; | 1531 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
1532 | if (!info) { | ||
1533 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (3)\n"); | ||
1534 | return -ENOMEM; | ||
1535 | } | ||
1536 | |||
1537 | info->addr_source = "ACPI"; | ||
1582 | 1538 | ||
1583 | /* Figure out the interface type. */ | 1539 | /* Figure out the interface type. */ |
1584 | switch (spmi->InterfaceType) | 1540 | switch (spmi->InterfaceType) |
1585 | { | 1541 | { |
1586 | case 1: /* KCS */ | 1542 | case 1: /* KCS */ |
1587 | si_type[intf_num] = "kcs"; | 1543 | info->si_type = SI_KCS; |
1588 | break; | 1544 | break; |
1589 | |||
1590 | case 2: /* SMIC */ | 1545 | case 2: /* SMIC */ |
1591 | si_type[intf_num] = "smic"; | 1546 | info->si_type = SI_SMIC; |
1592 | break; | 1547 | break; |
1593 | |||
1594 | case 3: /* BT */ | 1548 | case 3: /* BT */ |
1595 | si_type[intf_num] = "bt"; | 1549 | info->si_type = SI_BT; |
1596 | break; | 1550 | break; |
1597 | |||
1598 | default: | 1551 | default: |
1599 | printk(KERN_INFO "ipmi_si: Unknown ACPI/SPMI SI type %d\n", | 1552 | printk(KERN_INFO "ipmi_si: Unknown ACPI/SPMI SI type %d\n", |
1600 | spmi->InterfaceType); | 1553 | spmi->InterfaceType); |
1554 | kfree(info); | ||
1601 | return -EIO; | 1555 | return -EIO; |
1602 | } | 1556 | } |
1603 | 1557 | ||
1604 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
1605 | if (! info) { | ||
1606 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (3)\n"); | ||
1607 | return -ENOMEM; | ||
1608 | } | ||
1609 | memset(info, 0, sizeof(*info)); | ||
1610 | |||
1611 | if (spmi->InterruptType & 1) { | 1558 | if (spmi->InterruptType & 1) { |
1612 | /* We've got a GPE interrupt. */ | 1559 | /* We've got a GPE interrupt. */ |
1613 | info->irq = spmi->GPE; | 1560 | info->irq = spmi->GPE; |
1614 | info->irq_setup = acpi_gpe_irq_setup; | 1561 | info->irq_setup = acpi_gpe_irq_setup; |
1615 | info->irq_cleanup = acpi_gpe_irq_cleanup; | ||
1616 | } else if (spmi->InterruptType & 2) { | 1562 | } else if (spmi->InterruptType & 2) { |
1617 | /* We've got an APIC/SAPIC interrupt. */ | 1563 | /* We've got an APIC/SAPIC interrupt. */ |
1618 | info->irq = spmi->GlobalSystemInterrupt; | 1564 | info->irq = spmi->GlobalSystemInterrupt; |
1619 | info->irq_setup = std_irq_setup; | 1565 | info->irq_setup = std_irq_setup; |
1620 | info->irq_cleanup = std_irq_cleanup; | ||
1621 | } else { | 1566 | } else { |
1622 | /* Use the default interrupt setting. */ | 1567 | /* Use the default interrupt setting. */ |
1623 | info->irq = 0; | 1568 | info->irq = 0; |
@@ -1626,43 +1571,60 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) | |||
1626 | 1571 | ||
1627 | if (spmi->addr.register_bit_width) { | 1572 | if (spmi->addr.register_bit_width) { |
1628 | /* A (hopefully) properly formed register bit width. */ | 1573 | /* A (hopefully) properly formed register bit width. */ |
1629 | regspacings[intf_num] = spmi->addr.register_bit_width / 8; | ||
1630 | info->io.regspacing = spmi->addr.register_bit_width / 8; | 1574 | info->io.regspacing = spmi->addr.register_bit_width / 8; |
1631 | } else { | 1575 | } else { |
1632 | regspacings[intf_num] = DEFAULT_REGSPACING; | ||
1633 | info->io.regspacing = DEFAULT_REGSPACING; | 1576 | info->io.regspacing = DEFAULT_REGSPACING; |
1634 | } | 1577 | } |
1635 | regsizes[intf_num] = regspacings[intf_num]; | 1578 | info->io.regsize = info->io.regspacing; |
1636 | info->io.regsize = regsizes[intf_num]; | 1579 | info->io.regshift = spmi->addr.register_bit_offset; |
1637 | regshifts[intf_num] = spmi->addr.register_bit_offset; | ||
1638 | info->io.regshift = regshifts[intf_num]; | ||
1639 | 1580 | ||
1640 | if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 1581 | if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
1641 | io_type = "memory"; | 1582 | io_type = "memory"; |
1642 | info->io_setup = mem_setup; | 1583 | info->io_setup = mem_setup; |
1643 | addrs[intf_num] = spmi->addr.address; | 1584 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
1644 | info->io.info = &(addrs[intf_num]); | ||
1645 | } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { | 1585 | } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
1646 | io_type = "I/O"; | 1586 | io_type = "I/O"; |
1647 | info->io_setup = port_setup; | 1587 | info->io_setup = port_setup; |
1648 | ports[intf_num] = spmi->addr.address; | 1588 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; |
1649 | info->io.info = &(ports[intf_num]); | ||
1650 | } else { | 1589 | } else { |
1651 | kfree(info); | 1590 | kfree(info); |
1652 | printk("ipmi_si: Unknown ACPI I/O Address type\n"); | 1591 | printk("ipmi_si: Unknown ACPI I/O Address type\n"); |
1653 | return -EIO; | 1592 | return -EIO; |
1654 | } | 1593 | } |
1594 | info->io.addr_data = spmi->addr.address; | ||
1655 | 1595 | ||
1656 | *new_info = info; | 1596 | try_smi_init(info); |
1657 | 1597 | ||
1658 | printk("ipmi_si: ACPI/SPMI specifies \"%s\" %s SI @ 0x%lx\n", | ||
1659 | si_type[intf_num], io_type, (unsigned long) spmi->addr.address); | ||
1660 | return 0; | 1598 | return 0; |
1661 | } | 1599 | } |
1600 | |||
1601 | static __devinit void acpi_find_bmc(void) | ||
1602 | { | ||
1603 | acpi_status status; | ||
1604 | struct SPMITable *spmi; | ||
1605 | int i; | ||
1606 | |||
1607 | if (acpi_disabled) | ||
1608 | return; | ||
1609 | |||
1610 | if (acpi_failure) | ||
1611 | return; | ||
1612 | |||
1613 | for (i = 0; ; i++) { | ||
1614 | status = acpi_get_firmware_table("SPMI", i+1, | ||
1615 | ACPI_LOGICAL_ADDRESSING, | ||
1616 | (struct acpi_table_header **) | ||
1617 | &spmi); | ||
1618 | if (status != AE_OK) | ||
1619 | return; | ||
1620 | |||
1621 | try_init_acpi(spmi); | ||
1622 | } | ||
1623 | } | ||
1662 | #endif | 1624 | #endif |
1663 | 1625 | ||
1664 | #ifdef CONFIG_DMI | 1626 | #ifdef CONFIG_DMI |
1665 | typedef struct dmi_ipmi_data | 1627 | struct dmi_ipmi_data |
1666 | { | 1628 | { |
1667 | u8 type; | 1629 | u8 type; |
1668 | u8 addr_space; | 1630 | u8 addr_space; |
@@ -1670,49 +1632,46 @@ typedef struct dmi_ipmi_data | |||
1670 | u8 irq; | 1632 | u8 irq; |
1671 | u8 offset; | 1633 | u8 offset; |
1672 | u8 slave_addr; | 1634 | u8 slave_addr; |
1673 | } dmi_ipmi_data_t; | 1635 | }; |
1674 | |||
1675 | static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; | ||
1676 | static int dmi_data_entries; | ||
1677 | 1636 | ||
1678 | static int __init decode_dmi(struct dmi_header *dm, int intf_num) | 1637 | static int __devinit decode_dmi(struct dmi_header *dm, |
1638 | struct dmi_ipmi_data *dmi) | ||
1679 | { | 1639 | { |
1680 | u8 *data = (u8 *)dm; | 1640 | u8 *data = (u8 *)dm; |
1681 | unsigned long base_addr; | 1641 | unsigned long base_addr; |
1682 | u8 reg_spacing; | 1642 | u8 reg_spacing; |
1683 | u8 len = dm->length; | 1643 | u8 len = dm->length; |
1684 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; | ||
1685 | 1644 | ||
1686 | ipmi_data->type = data[4]; | 1645 | dmi->type = data[4]; |
1687 | 1646 | ||
1688 | memcpy(&base_addr, data+8, sizeof(unsigned long)); | 1647 | memcpy(&base_addr, data+8, sizeof(unsigned long)); |
1689 | if (len >= 0x11) { | 1648 | if (len >= 0x11) { |
1690 | if (base_addr & 1) { | 1649 | if (base_addr & 1) { |
1691 | /* I/O */ | 1650 | /* I/O */ |
1692 | base_addr &= 0xFFFE; | 1651 | base_addr &= 0xFFFE; |
1693 | ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; | 1652 | dmi->addr_space = IPMI_IO_ADDR_SPACE; |
1694 | } | 1653 | } |
1695 | else { | 1654 | else { |
1696 | /* Memory */ | 1655 | /* Memory */ |
1697 | ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE; | 1656 | dmi->addr_space = IPMI_MEM_ADDR_SPACE; |
1698 | } | 1657 | } |
1699 | /* If bit 4 of byte 0x10 is set, then the lsb for the address | 1658 | /* If bit 4 of byte 0x10 is set, then the lsb for the address |
1700 | is odd. */ | 1659 | is odd. */ |
1701 | ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); | 1660 | dmi->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); |
1702 | 1661 | ||
1703 | ipmi_data->irq = data[0x11]; | 1662 | dmi->irq = data[0x11]; |
1704 | 1663 | ||
1705 | /* The top two bits of byte 0x10 hold the register spacing. */ | 1664 | /* The top two bits of byte 0x10 hold the register spacing. */ |
1706 | reg_spacing = (data[0x10] & 0xC0) >> 6; | 1665 | reg_spacing = (data[0x10] & 0xC0) >> 6; |
1707 | switch(reg_spacing){ | 1666 | switch(reg_spacing){ |
1708 | case 0x00: /* Byte boundaries */ | 1667 | case 0x00: /* Byte boundaries */ |
1709 | ipmi_data->offset = 1; | 1668 | dmi->offset = 1; |
1710 | break; | 1669 | break; |
1711 | case 0x01: /* 32-bit boundaries */ | 1670 | case 0x01: /* 32-bit boundaries */ |
1712 | ipmi_data->offset = 4; | 1671 | dmi->offset = 4; |
1713 | break; | 1672 | break; |
1714 | case 0x02: /* 16-byte boundaries */ | 1673 | case 0x02: /* 16-byte boundaries */ |
1715 | ipmi_data->offset = 16; | 1674 | dmi->offset = 16; |
1716 | break; | 1675 | break; |
1717 | default: | 1676 | default: |
1718 | /* Some other interface, just ignore it. */ | 1677 | /* Some other interface, just ignore it. */ |
@@ -1726,217 +1685,227 @@ static int __init decode_dmi(struct dmi_header *dm, int intf_num) | |||
1726 | * wrong (and all that I have seen are I/O) so we just | 1685 | * wrong (and all that I have seen are I/O) so we just |
1727 | * ignore that bit and assume I/O. Systems that use | 1686 | * ignore that bit and assume I/O. Systems that use |
1728 | * memory should use the newer spec, anyway. */ | 1687 | * memory should use the newer spec, anyway. */ |
1729 | ipmi_data->base_addr = base_addr & 0xfffe; | 1688 | dmi->base_addr = base_addr & 0xfffe; |
1730 | ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; | 1689 | dmi->addr_space = IPMI_IO_ADDR_SPACE; |
1731 | ipmi_data->offset = 1; | 1690 | dmi->offset = 1; |
1732 | } | ||
1733 | |||
1734 | ipmi_data->slave_addr = data[6]; | ||
1735 | |||
1736 | if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { | ||
1737 | dmi_data_entries++; | ||
1738 | return 0; | ||
1739 | } | 1691 | } |
1740 | 1692 | ||
1741 | memset(ipmi_data, 0, sizeof(dmi_ipmi_data_t)); | 1693 | dmi->slave_addr = data[6]; |
1742 | 1694 | ||
1743 | return -1; | 1695 | return 0; |
1744 | } | 1696 | } |
1745 | 1697 | ||
1746 | static void __init dmi_find_bmc(void) | 1698 | static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) |
1747 | { | 1699 | { |
1748 | struct dmi_device *dev = NULL; | 1700 | struct smi_info *info; |
1749 | int intf_num = 0; | ||
1750 | |||
1751 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { | ||
1752 | if (intf_num >= SI_MAX_DRIVERS) | ||
1753 | break; | ||
1754 | 1701 | ||
1755 | decode_dmi((struct dmi_header *) dev->device_data, intf_num++); | 1702 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
1703 | if (!info) { | ||
1704 | printk(KERN_ERR | ||
1705 | "ipmi_si: Could not allocate SI data\n"); | ||
1706 | return; | ||
1756 | } | 1707 | } |
1757 | } | ||
1758 | |||
1759 | static int try_init_smbios(int intf_num, struct smi_info **new_info) | ||
1760 | { | ||
1761 | struct smi_info *info; | ||
1762 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; | ||
1763 | char *io_type; | ||
1764 | 1708 | ||
1765 | if (intf_num >= dmi_data_entries) | 1709 | info->addr_source = "SMBIOS"; |
1766 | return -ENODEV; | ||
1767 | 1710 | ||
1768 | switch (ipmi_data->type) { | 1711 | switch (ipmi_data->type) { |
1769 | case 0x01: /* KCS */ | 1712 | case 0x01: /* KCS */ |
1770 | si_type[intf_num] = "kcs"; | 1713 | info->si_type = SI_KCS; |
1771 | break; | 1714 | break; |
1772 | case 0x02: /* SMIC */ | 1715 | case 0x02: /* SMIC */ |
1773 | si_type[intf_num] = "smic"; | 1716 | info->si_type = SI_SMIC; |
1774 | break; | 1717 | break; |
1775 | case 0x03: /* BT */ | 1718 | case 0x03: /* BT */ |
1776 | si_type[intf_num] = "bt"; | 1719 | info->si_type = SI_BT; |
1777 | break; | 1720 | break; |
1778 | default: | 1721 | default: |
1779 | return -EIO; | 1722 | return; |
1780 | } | ||
1781 | |||
1782 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
1783 | if (! info) { | ||
1784 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (4)\n"); | ||
1785 | return -ENOMEM; | ||
1786 | } | 1723 | } |
1787 | memset(info, 0, sizeof(*info)); | ||
1788 | 1724 | ||
1789 | if (ipmi_data->addr_space == 1) { | 1725 | switch (ipmi_data->addr_space) { |
1790 | io_type = "memory"; | 1726 | case IPMI_MEM_ADDR_SPACE: |
1791 | info->io_setup = mem_setup; | 1727 | info->io_setup = mem_setup; |
1792 | addrs[intf_num] = ipmi_data->base_addr; | 1728 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; |
1793 | info->io.info = &(addrs[intf_num]); | 1729 | break; |
1794 | } else if (ipmi_data->addr_space == 2) { | 1730 | |
1795 | io_type = "I/O"; | 1731 | case IPMI_IO_ADDR_SPACE: |
1796 | info->io_setup = port_setup; | 1732 | info->io_setup = port_setup; |
1797 | ports[intf_num] = ipmi_data->base_addr; | 1733 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
1798 | info->io.info = &(ports[intf_num]); | 1734 | break; |
1799 | } else { | 1735 | |
1736 | default: | ||
1800 | kfree(info); | 1737 | kfree(info); |
1801 | printk("ipmi_si: Unknown SMBIOS I/O Address type.\n"); | 1738 | printk(KERN_WARNING |
1802 | return -EIO; | 1739 | "ipmi_si: Unknown SMBIOS I/O Address type: %d.\n", |
1740 | ipmi_data->addr_space); | ||
1741 | return; | ||
1803 | } | 1742 | } |
1743 | info->io.addr_data = ipmi_data->base_addr; | ||
1804 | 1744 | ||
1805 | regspacings[intf_num] = ipmi_data->offset; | 1745 | info->io.regspacing = ipmi_data->offset; |
1806 | info->io.regspacing = regspacings[intf_num]; | 1746 | if (!info->io.regspacing) |
1807 | if (! info->io.regspacing) | ||
1808 | info->io.regspacing = DEFAULT_REGSPACING; | 1747 | info->io.regspacing = DEFAULT_REGSPACING; |
1809 | info->io.regsize = DEFAULT_REGSPACING; | 1748 | info->io.regsize = DEFAULT_REGSPACING; |
1810 | info->io.regshift = regshifts[intf_num]; | 1749 | info->io.regshift = 0; |
1811 | 1750 | ||
1812 | info->slave_addr = ipmi_data->slave_addr; | 1751 | info->slave_addr = ipmi_data->slave_addr; |
1813 | 1752 | ||
1814 | irqs[intf_num] = ipmi_data->irq; | 1753 | info->irq = ipmi_data->irq; |
1754 | if (info->irq) | ||
1755 | info->irq_setup = std_irq_setup; | ||
1815 | 1756 | ||
1816 | *new_info = info; | 1757 | try_smi_init(info); |
1758 | } | ||
1817 | 1759 | ||
1818 | printk("ipmi_si: Found SMBIOS-specified state machine at %s" | 1760 | static void __devinit dmi_find_bmc(void) |
1819 | " address 0x%lx, slave address 0x%x\n", | 1761 | { |
1820 | io_type, (unsigned long)ipmi_data->base_addr, | 1762 | struct dmi_device *dev = NULL; |
1821 | ipmi_data->slave_addr); | 1763 | struct dmi_ipmi_data data; |
1822 | return 0; | 1764 | int rv; |
1765 | |||
1766 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { | ||
1767 | rv = decode_dmi((struct dmi_header *) dev->device_data, &data); | ||
1768 | if (!rv) | ||
1769 | try_init_dmi(&data); | ||
1770 | } | ||
1823 | } | 1771 | } |
1824 | #endif /* CONFIG_DMI */ | 1772 | #endif /* CONFIG_DMI */ |
1825 | 1773 | ||
1826 | #ifdef CONFIG_PCI | 1774 | #ifdef CONFIG_PCI |
1827 | 1775 | ||
1828 | #define PCI_ERMC_CLASSCODE 0x0C0700 | 1776 | #define PCI_ERMC_CLASSCODE 0x0C0700 |
1777 | #define PCI_ERMC_CLASSCODE_MASK 0xffffff00 | ||
1778 | #define PCI_ERMC_CLASSCODE_TYPE_MASK 0xff | ||
1779 | #define PCI_ERMC_CLASSCODE_TYPE_SMIC 0x00 | ||
1780 | #define PCI_ERMC_CLASSCODE_TYPE_KCS 0x01 | ||
1781 | #define PCI_ERMC_CLASSCODE_TYPE_BT 0x02 | ||
1782 | |||
1829 | #define PCI_HP_VENDOR_ID 0x103C | 1783 | #define PCI_HP_VENDOR_ID 0x103C |
1830 | #define PCI_MMC_DEVICE_ID 0x121A | 1784 | #define PCI_MMC_DEVICE_ID 0x121A |
1831 | #define PCI_MMC_ADDR_CW 0x10 | 1785 | #define PCI_MMC_ADDR_CW 0x10 |
1832 | 1786 | ||
1833 | /* Avoid more than one attempt to probe pci smic. */ | 1787 | static void ipmi_pci_cleanup(struct smi_info *info) |
1834 | static int pci_smic_checked = 0; | 1788 | { |
1789 | struct pci_dev *pdev = info->addr_source_data; | ||
1790 | |||
1791 | pci_disable_device(pdev); | ||
1792 | } | ||
1835 | 1793 | ||
1836 | static int find_pci_smic(int intf_num, struct smi_info **new_info) | 1794 | static int __devinit ipmi_pci_probe(struct pci_dev *pdev, |
1795 | const struct pci_device_id *ent) | ||
1837 | { | 1796 | { |
1838 | struct smi_info *info; | 1797 | int rv; |
1839 | int error; | 1798 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; |
1840 | struct pci_dev *pci_dev = NULL; | 1799 | struct smi_info *info; |
1841 | u16 base_addr; | 1800 | int first_reg_offset = 0; |
1842 | int fe_rmc = 0; | ||
1843 | 1801 | ||
1844 | if (pci_smic_checked) | 1802 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
1845 | return -ENODEV; | 1803 | if (!info) |
1804 | return ENOMEM; | ||
1846 | 1805 | ||
1847 | pci_smic_checked = 1; | 1806 | info->addr_source = "PCI"; |
1848 | 1807 | ||
1849 | pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID, NULL); | 1808 | switch (class_type) { |
1850 | if (! pci_dev) { | 1809 | case PCI_ERMC_CLASSCODE_TYPE_SMIC: |
1851 | pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL); | 1810 | info->si_type = SI_SMIC; |
1852 | if (pci_dev && (pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)) | 1811 | break; |
1853 | fe_rmc = 1; | ||
1854 | else | ||
1855 | return -ENODEV; | ||
1856 | } | ||
1857 | 1812 | ||
1858 | error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr); | 1813 | case PCI_ERMC_CLASSCODE_TYPE_KCS: |
1859 | if (error) | 1814 | info->si_type = SI_KCS; |
1860 | { | 1815 | break; |
1861 | pci_dev_put(pci_dev); | 1816 | |
1862 | printk(KERN_ERR | 1817 | case PCI_ERMC_CLASSCODE_TYPE_BT: |
1863 | "ipmi_si: pci_read_config_word() failed (%d).\n", | 1818 | info->si_type = SI_BT; |
1864 | error); | 1819 | break; |
1865 | return -ENODEV; | 1820 | |
1821 | default: | ||
1822 | kfree(info); | ||
1823 | printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n", | ||
1824 | pci_name(pdev), class_type); | ||
1825 | return ENOMEM; | ||
1866 | } | 1826 | } |
1867 | 1827 | ||
1868 | /* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */ | 1828 | rv = pci_enable_device(pdev); |
1869 | if (! (base_addr & 0x0001)) | 1829 | if (rv) { |
1870 | { | 1830 | printk(KERN_ERR "ipmi_si: %s: couldn't enable PCI device\n", |
1871 | pci_dev_put(pci_dev); | 1831 | pci_name(pdev)); |
1872 | printk(KERN_ERR | 1832 | kfree(info); |
1873 | "ipmi_si: memory mapped I/O not supported for PCI" | 1833 | return rv; |
1874 | " smic.\n"); | ||
1875 | return -ENODEV; | ||
1876 | } | 1834 | } |
1877 | 1835 | ||
1878 | base_addr &= 0xFFFE; | 1836 | info->addr_source_cleanup = ipmi_pci_cleanup; |
1879 | if (! fe_rmc) | 1837 | info->addr_source_data = pdev; |
1880 | /* Data register starts at base address + 1 in eRMC */ | ||
1881 | ++base_addr; | ||
1882 | 1838 | ||
1883 | if (! is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) { | 1839 | if (pdev->subsystem_vendor == PCI_HP_VENDOR_ID) |
1884 | pci_dev_put(pci_dev); | 1840 | first_reg_offset = 1; |
1885 | return -ENODEV; | ||
1886 | } | ||
1887 | 1841 | ||
1888 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1842 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { |
1889 | if (! info) { | 1843 | info->io_setup = port_setup; |
1890 | pci_dev_put(pci_dev); | 1844 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
1891 | printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n"); | 1845 | } else { |
1892 | return -ENOMEM; | 1846 | info->io_setup = mem_setup; |
1847 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
1893 | } | 1848 | } |
1894 | memset(info, 0, sizeof(*info)); | 1849 | info->io.addr_data = pci_resource_start(pdev, 0); |
1895 | 1850 | ||
1896 | info->io_setup = port_setup; | 1851 | info->io.regspacing = DEFAULT_REGSPACING; |
1897 | ports[intf_num] = base_addr; | ||
1898 | info->io.info = &(ports[intf_num]); | ||
1899 | info->io.regspacing = regspacings[intf_num]; | ||
1900 | if (! info->io.regspacing) | ||
1901 | info->io.regspacing = DEFAULT_REGSPACING; | ||
1902 | info->io.regsize = DEFAULT_REGSPACING; | 1852 | info->io.regsize = DEFAULT_REGSPACING; |
1903 | info->io.regshift = regshifts[intf_num]; | 1853 | info->io.regshift = 0; |
1904 | 1854 | ||
1905 | *new_info = info; | 1855 | info->irq = pdev->irq; |
1856 | if (info->irq) | ||
1857 | info->irq_setup = std_irq_setup; | ||
1906 | 1858 | ||
1907 | irqs[intf_num] = pci_dev->irq; | 1859 | info->dev = &pdev->dev; |
1908 | si_type[intf_num] = "smic"; | ||
1909 | 1860 | ||
1910 | printk("ipmi_si: Found PCI SMIC at I/O address 0x%lx\n", | 1861 | return try_smi_init(info); |
1911 | (long unsigned int) base_addr); | 1862 | } |
1912 | 1863 | ||
1913 | pci_dev_put(pci_dev); | 1864 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) |
1865 | { | ||
1866 | } | ||
1867 | |||
1868 | #ifdef CONFIG_PM | ||
1869 | static int ipmi_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1870 | { | ||
1914 | return 0; | 1871 | return 0; |
1915 | } | 1872 | } |
1916 | #endif /* CONFIG_PCI */ | ||
1917 | 1873 | ||
1918 | static int try_init_plug_and_play(int intf_num, struct smi_info **new_info) | 1874 | static int ipmi_pci_resume(struct pci_dev *pdev) |
1919 | { | 1875 | { |
1920 | #ifdef CONFIG_PCI | 1876 | return 0; |
1921 | if (find_pci_smic(intf_num, new_info) == 0) | 1877 | } |
1922 | return 0; | ||
1923 | #endif | 1878 | #endif |
1924 | /* Include other methods here. */ | ||
1925 | 1879 | ||
1926 | return -ENODEV; | 1880 | static struct pci_device_id ipmi_pci_devices[] = { |
1927 | } | 1881 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, |
1882 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) } | ||
1883 | }; | ||
1884 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); | ||
1885 | |||
1886 | static struct pci_driver ipmi_pci_driver = { | ||
1887 | .name = DEVICE_NAME, | ||
1888 | .id_table = ipmi_pci_devices, | ||
1889 | .probe = ipmi_pci_probe, | ||
1890 | .remove = __devexit_p(ipmi_pci_remove), | ||
1891 | #ifdef CONFIG_PM | ||
1892 | .suspend = ipmi_pci_suspend, | ||
1893 | .resume = ipmi_pci_resume, | ||
1894 | #endif | ||
1895 | }; | ||
1896 | #endif /* CONFIG_PCI */ | ||
1928 | 1897 | ||
1929 | 1898 | ||
1930 | static int try_get_dev_id(struct smi_info *smi_info) | 1899 | static int try_get_dev_id(struct smi_info *smi_info) |
1931 | { | 1900 | { |
1932 | unsigned char msg[2]; | 1901 | unsigned char msg[2]; |
1933 | unsigned char *resp; | 1902 | unsigned char *resp; |
1934 | unsigned long resp_len; | 1903 | unsigned long resp_len; |
1935 | enum si_sm_result smi_result; | 1904 | enum si_sm_result smi_result; |
1936 | int rv = 0; | 1905 | int rv = 0; |
1937 | 1906 | ||
1938 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | 1907 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); |
1939 | if (! resp) | 1908 | if (!resp) |
1940 | return -ENOMEM; | 1909 | return -ENOMEM; |
1941 | 1910 | ||
1942 | /* Do a Get Device ID command, since it comes back with some | 1911 | /* Do a Get Device ID command, since it comes back with some |
@@ -1972,7 +1941,7 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
1972 | /* Otherwise, we got some data. */ | 1941 | /* Otherwise, we got some data. */ |
1973 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, | 1942 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, |
1974 | resp, IPMI_MAX_MSG_LENGTH); | 1943 | resp, IPMI_MAX_MSG_LENGTH); |
1975 | if (resp_len < 6) { | 1944 | if (resp_len < 14) { |
1976 | /* That's odd, it should be longer. */ | 1945 | /* That's odd, it should be longer. */ |
1977 | rv = -EINVAL; | 1946 | rv = -EINVAL; |
1978 | goto out; | 1947 | goto out; |
@@ -1985,8 +1954,7 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
1985 | } | 1954 | } |
1986 | 1955 | ||
1987 | /* Record info from the get device id, in case we need it. */ | 1956 | /* Record info from the get device id, in case we need it. */ |
1988 | memcpy(&smi_info->device_id, &resp[3], | 1957 | ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id); |
1989 | min_t(unsigned long, resp_len-3, sizeof(smi_info->device_id))); | ||
1990 | 1958 | ||
1991 | out: | 1959 | out: |
1992 | kfree(resp); | 1960 | kfree(resp); |
@@ -2018,7 +1986,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
2018 | struct smi_info *smi = data; | 1986 | struct smi_info *smi = data; |
2019 | 1987 | ||
2020 | out += sprintf(out, "interrupts_enabled: %d\n", | 1988 | out += sprintf(out, "interrupts_enabled: %d\n", |
2021 | smi->irq && ! smi->interrupt_disabled); | 1989 | smi->irq && !smi->interrupt_disabled); |
2022 | out += sprintf(out, "short_timeouts: %ld\n", | 1990 | out += sprintf(out, "short_timeouts: %ld\n", |
2023 | smi->short_timeouts); | 1991 | smi->short_timeouts); |
2024 | out += sprintf(out, "long_timeouts: %ld\n", | 1992 | out += sprintf(out, "long_timeouts: %ld\n", |
@@ -2089,15 +2057,14 @@ static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info) | |||
2089 | #define DELL_POWEREDGE_8G_BMC_DEVICE_ID 0x20 | 2057 | #define DELL_POWEREDGE_8G_BMC_DEVICE_ID 0x20 |
2090 | #define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80 | 2058 | #define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80 |
2091 | #define DELL_POWEREDGE_8G_BMC_IPMI_VERSION 0x51 | 2059 | #define DELL_POWEREDGE_8G_BMC_IPMI_VERSION 0x51 |
2092 | #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00} | 2060 | #define DELL_IANA_MFR_ID 0x0002a2 |
2093 | static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info) | 2061 | static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info) |
2094 | { | 2062 | { |
2095 | struct ipmi_device_id *id = &smi_info->device_id; | 2063 | struct ipmi_device_id *id = &smi_info->device_id; |
2096 | const char mfr[3]=DELL_IANA_MFR_ID; | 2064 | if (id->manufacturer_id == DELL_IANA_MFR_ID) { |
2097 | if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))) { | ||
2098 | if (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID && | 2065 | if (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID && |
2099 | id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV && | 2066 | id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV && |
2100 | id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) { | 2067 | id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) { |
2101 | smi_info->oem_data_avail_handler = | 2068 | smi_info->oem_data_avail_handler = |
2102 | oem_data_avail_to_receive_msg_avail; | 2069 | oem_data_avail_to_receive_msg_avail; |
2103 | } | 2070 | } |
@@ -2169,8 +2136,7 @@ static void | |||
2169 | setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info) | 2136 | setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info) |
2170 | { | 2137 | { |
2171 | struct ipmi_device_id *id = &smi_info->device_id; | 2138 | struct ipmi_device_id *id = &smi_info->device_id; |
2172 | const char mfr[3]=DELL_IANA_MFR_ID; | 2139 | if (id->manufacturer_id == DELL_IANA_MFR_ID && |
2173 | if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) && | ||
2174 | smi_info->si_type == SI_BT) | 2140 | smi_info->si_type == SI_BT) |
2175 | register_xaction_notifier(&dell_poweredge_bt_xaction_notifier); | 2141 | register_xaction_notifier(&dell_poweredge_bt_xaction_notifier); |
2176 | } | 2142 | } |
@@ -2200,62 +2166,110 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | |||
2200 | del_timer_sync(&smi_info->si_timer); | 2166 | del_timer_sync(&smi_info->si_timer); |
2201 | } | 2167 | } |
2202 | 2168 | ||
2203 | /* Returns 0 if initialized, or negative on an error. */ | 2169 | static struct ipmi_default_vals |
2204 | static int init_one_smi(int intf_num, struct smi_info **smi) | ||
2205 | { | 2170 | { |
2206 | int rv; | 2171 | int type; |
2207 | struct smi_info *new_smi; | 2172 | int port; |
2173 | } __devinit ipmi_defaults[] = | ||
2174 | { | ||
2175 | { .type = SI_KCS, .port = 0xca2 }, | ||
2176 | { .type = SI_SMIC, .port = 0xca9 }, | ||
2177 | { .type = SI_BT, .port = 0xe4 }, | ||
2178 | { .port = 0 } | ||
2179 | }; | ||
2208 | 2180 | ||
2181 | static __devinit void default_find_bmc(void) | ||
2182 | { | ||
2183 | struct smi_info *info; | ||
2184 | int i; | ||
2209 | 2185 | ||
2210 | rv = try_init_mem(intf_num, &new_smi); | 2186 | for (i = 0; ; i++) { |
2211 | if (rv) | 2187 | if (!ipmi_defaults[i].port) |
2212 | rv = try_init_port(intf_num, &new_smi); | 2188 | break; |
2213 | #ifdef CONFIG_ACPI | ||
2214 | if (rv && si_trydefaults) | ||
2215 | rv = try_init_acpi(intf_num, &new_smi); | ||
2216 | #endif | ||
2217 | #ifdef CONFIG_DMI | ||
2218 | if (rv && si_trydefaults) | ||
2219 | rv = try_init_smbios(intf_num, &new_smi); | ||
2220 | #endif | ||
2221 | if (rv && si_trydefaults) | ||
2222 | rv = try_init_plug_and_play(intf_num, &new_smi); | ||
2223 | 2189 | ||
2224 | if (rv) | 2190 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
2225 | return rv; | 2191 | if (!info) |
2192 | return; | ||
2226 | 2193 | ||
2227 | /* So we know not to free it unless we have allocated one. */ | 2194 | info->addr_source = NULL; |
2228 | new_smi->intf = NULL; | ||
2229 | new_smi->si_sm = NULL; | ||
2230 | new_smi->handlers = NULL; | ||
2231 | 2195 | ||
2232 | if (! new_smi->irq_setup) { | 2196 | info->si_type = ipmi_defaults[i].type; |
2233 | new_smi->irq = irqs[intf_num]; | 2197 | info->io_setup = port_setup; |
2234 | new_smi->irq_setup = std_irq_setup; | 2198 | info->io.addr_data = ipmi_defaults[i].port; |
2235 | new_smi->irq_cleanup = std_irq_cleanup; | 2199 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
2236 | } | ||
2237 | 2200 | ||
2238 | /* Default to KCS if no type is specified. */ | 2201 | info->io.addr = NULL; |
2239 | if (si_type[intf_num] == NULL) { | 2202 | info->io.regspacing = DEFAULT_REGSPACING; |
2240 | if (si_trydefaults) | 2203 | info->io.regsize = DEFAULT_REGSPACING; |
2241 | si_type[intf_num] = "kcs"; | 2204 | info->io.regshift = 0; |
2242 | else { | 2205 | |
2243 | rv = -EINVAL; | 2206 | if (try_smi_init(info) == 0) { |
2244 | goto out_err; | 2207 | /* Found one... */ |
2208 | printk(KERN_INFO "ipmi_si: Found default %s state" | ||
2209 | " machine at %s address 0x%lx\n", | ||
2210 | si_to_str[info->si_type], | ||
2211 | addr_space_to_str[info->io.addr_type], | ||
2212 | info->io.addr_data); | ||
2213 | return; | ||
2245 | } | 2214 | } |
2246 | } | 2215 | } |
2216 | } | ||
2217 | |||
2218 | static int is_new_interface(struct smi_info *info) | ||
2219 | { | ||
2220 | struct smi_info *e; | ||
2221 | |||
2222 | list_for_each_entry(e, &smi_infos, link) { | ||
2223 | if (e->io.addr_type != info->io.addr_type) | ||
2224 | continue; | ||
2225 | if (e->io.addr_data == info->io.addr_data) | ||
2226 | return 0; | ||
2227 | } | ||
2228 | |||
2229 | return 1; | ||
2230 | } | ||
2231 | |||
2232 | static int try_smi_init(struct smi_info *new_smi) | ||
2233 | { | ||
2234 | int rv; | ||
2235 | |||
2236 | if (new_smi->addr_source) { | ||
2237 | printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" | ||
2238 | " machine at %s address 0x%lx, slave address 0x%x," | ||
2239 | " irq %d\n", | ||
2240 | new_smi->addr_source, | ||
2241 | si_to_str[new_smi->si_type], | ||
2242 | addr_space_to_str[new_smi->io.addr_type], | ||
2243 | new_smi->io.addr_data, | ||
2244 | new_smi->slave_addr, new_smi->irq); | ||
2245 | } | ||
2246 | |||
2247 | down(&smi_infos_lock); | ||
2248 | if (!is_new_interface(new_smi)) { | ||
2249 | printk(KERN_WARNING "ipmi_si: duplicate interface\n"); | ||
2250 | rv = -EBUSY; | ||
2251 | goto out_err; | ||
2252 | } | ||
2247 | 2253 | ||
2248 | /* Set up the state machine to use. */ | 2254 | /* So we know not to free it unless we have allocated one. */ |
2249 | if (strcmp(si_type[intf_num], "kcs") == 0) { | 2255 | new_smi->intf = NULL; |
2256 | new_smi->si_sm = NULL; | ||
2257 | new_smi->handlers = NULL; | ||
2258 | |||
2259 | switch (new_smi->si_type) { | ||
2260 | case SI_KCS: | ||
2250 | new_smi->handlers = &kcs_smi_handlers; | 2261 | new_smi->handlers = &kcs_smi_handlers; |
2251 | new_smi->si_type = SI_KCS; | 2262 | break; |
2252 | } else if (strcmp(si_type[intf_num], "smic") == 0) { | 2263 | |
2264 | case SI_SMIC: | ||
2253 | new_smi->handlers = &smic_smi_handlers; | 2265 | new_smi->handlers = &smic_smi_handlers; |
2254 | new_smi->si_type = SI_SMIC; | 2266 | break; |
2255 | } else if (strcmp(si_type[intf_num], "bt") == 0) { | 2267 | |
2268 | case SI_BT: | ||
2256 | new_smi->handlers = &bt_smi_handlers; | 2269 | new_smi->handlers = &bt_smi_handlers; |
2257 | new_smi->si_type = SI_BT; | 2270 | break; |
2258 | } else { | 2271 | |
2272 | default: | ||
2259 | /* No support for anything else yet. */ | 2273 | /* No support for anything else yet. */ |
2260 | rv = -EIO; | 2274 | rv = -EIO; |
2261 | goto out_err; | 2275 | goto out_err; |
@@ -2263,7 +2277,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2263 | 2277 | ||
2264 | /* Allocate the state machine's data and initialize it. */ | 2278 | /* Allocate the state machine's data and initialize it. */ |
2265 | new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); | 2279 | new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); |
2266 | if (! new_smi->si_sm) { | 2280 | if (!new_smi->si_sm) { |
2267 | printk(" Could not allocate state machine memory\n"); | 2281 | printk(" Could not allocate state machine memory\n"); |
2268 | rv = -ENOMEM; | 2282 | rv = -ENOMEM; |
2269 | goto out_err; | 2283 | goto out_err; |
@@ -2284,21 +2298,29 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2284 | 2298 | ||
2285 | /* Do low-level detection first. */ | 2299 | /* Do low-level detection first. */ |
2286 | if (new_smi->handlers->detect(new_smi->si_sm)) { | 2300 | if (new_smi->handlers->detect(new_smi->si_sm)) { |
2301 | if (new_smi->addr_source) | ||
2302 | printk(KERN_INFO "ipmi_si: Interface detection" | ||
2303 | " failed\n"); | ||
2287 | rv = -ENODEV; | 2304 | rv = -ENODEV; |
2288 | goto out_err; | 2305 | goto out_err; |
2289 | } | 2306 | } |
2290 | 2307 | ||
2291 | /* Attempt a get device id command. If it fails, we probably | 2308 | /* Attempt a get device id command. If it fails, we probably |
2292 | don't have a SMI here. */ | 2309 | don't have a BMC here. */ |
2293 | rv = try_get_dev_id(new_smi); | 2310 | rv = try_get_dev_id(new_smi); |
2294 | if (rv) | 2311 | if (rv) { |
2312 | if (new_smi->addr_source) | ||
2313 | printk(KERN_INFO "ipmi_si: There appears to be no BMC" | ||
2314 | " at this location\n"); | ||
2295 | goto out_err; | 2315 | goto out_err; |
2316 | } | ||
2296 | 2317 | ||
2297 | setup_oem_data_handler(new_smi); | 2318 | setup_oem_data_handler(new_smi); |
2298 | setup_xaction_handlers(new_smi); | 2319 | setup_xaction_handlers(new_smi); |
2299 | 2320 | ||
2300 | /* Try to claim any interrupts. */ | 2321 | /* Try to claim any interrupts. */ |
2301 | new_smi->irq_setup(new_smi); | 2322 | if (new_smi->irq_setup) |
2323 | new_smi->irq_setup(new_smi); | ||
2302 | 2324 | ||
2303 | INIT_LIST_HEAD(&(new_smi->xmit_msgs)); | 2325 | INIT_LIST_HEAD(&(new_smi->xmit_msgs)); |
2304 | INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); | 2326 | INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); |
@@ -2308,7 +2330,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2308 | 2330 | ||
2309 | new_smi->interrupt_disabled = 0; | 2331 | new_smi->interrupt_disabled = 0; |
2310 | atomic_set(&new_smi->stop_operation, 0); | 2332 | atomic_set(&new_smi->stop_operation, 0); |
2311 | new_smi->intf_num = intf_num; | 2333 | new_smi->intf_num = smi_num; |
2334 | smi_num++; | ||
2312 | 2335 | ||
2313 | /* Start clearing the flags before we enable interrupts or the | 2336 | /* Start clearing the flags before we enable interrupts or the |
2314 | timer to avoid racing with the timer. */ | 2337 | timer to avoid racing with the timer. */ |
@@ -2332,10 +2355,36 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2332 | new_smi->thread = kthread_run(ipmi_thread, new_smi, | 2355 | new_smi->thread = kthread_run(ipmi_thread, new_smi, |
2333 | "kipmi%d", new_smi->intf_num); | 2356 | "kipmi%d", new_smi->intf_num); |
2334 | 2357 | ||
2358 | if (!new_smi->dev) { | ||
2359 | /* If we don't already have a device from something | ||
2360 | * else (like PCI), then register a new one. */ | ||
2361 | new_smi->pdev = platform_device_alloc("ipmi_si", | ||
2362 | new_smi->intf_num); | ||
2363 | if (rv) { | ||
2364 | printk(KERN_ERR | ||
2365 | "ipmi_si_intf:" | ||
2366 | " Unable to allocate platform device\n"); | ||
2367 | goto out_err_stop_timer; | ||
2368 | } | ||
2369 | new_smi->dev = &new_smi->pdev->dev; | ||
2370 | new_smi->dev->driver = &ipmi_driver; | ||
2371 | |||
2372 | rv = platform_device_register(new_smi->pdev); | ||
2373 | if (rv) { | ||
2374 | printk(KERN_ERR | ||
2375 | "ipmi_si_intf:" | ||
2376 | " Unable to register system interface device:" | ||
2377 | " %d\n", | ||
2378 | rv); | ||
2379 | goto out_err_stop_timer; | ||
2380 | } | ||
2381 | new_smi->dev_registered = 1; | ||
2382 | } | ||
2383 | |||
2335 | rv = ipmi_register_smi(&handlers, | 2384 | rv = ipmi_register_smi(&handlers, |
2336 | new_smi, | 2385 | new_smi, |
2337 | ipmi_version_major(&new_smi->device_id), | 2386 | &new_smi->device_id, |
2338 | ipmi_version_minor(&new_smi->device_id), | 2387 | new_smi->dev, |
2339 | new_smi->slave_addr, | 2388 | new_smi->slave_addr, |
2340 | &(new_smi->intf)); | 2389 | &(new_smi->intf)); |
2341 | if (rv) { | 2390 | if (rv) { |
@@ -2365,9 +2414,11 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2365 | goto out_err_stop_timer; | 2414 | goto out_err_stop_timer; |
2366 | } | 2415 | } |
2367 | 2416 | ||
2368 | *smi = new_smi; | 2417 | list_add_tail(&new_smi->link, &smi_infos); |
2418 | |||
2419 | up(&smi_infos_lock); | ||
2369 | 2420 | ||
2370 | printk(" IPMI %s interface initialized\n", si_type[intf_num]); | 2421 | printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); |
2371 | 2422 | ||
2372 | return 0; | 2423 | return 0; |
2373 | 2424 | ||
@@ -2379,7 +2430,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2379 | if (new_smi->intf) | 2430 | if (new_smi->intf) |
2380 | ipmi_unregister_smi(new_smi->intf); | 2431 | ipmi_unregister_smi(new_smi->intf); |
2381 | 2432 | ||
2382 | new_smi->irq_cleanup(new_smi); | 2433 | if (new_smi->irq_cleanup) |
2434 | new_smi->irq_cleanup(new_smi); | ||
2383 | 2435 | ||
2384 | /* Wait until we know that we are out of any interrupt | 2436 | /* Wait until we know that we are out of any interrupt |
2385 | handlers might have been running before we freed the | 2437 | handlers might have been running before we freed the |
@@ -2391,23 +2443,41 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2391 | new_smi->handlers->cleanup(new_smi->si_sm); | 2443 | new_smi->handlers->cleanup(new_smi->si_sm); |
2392 | kfree(new_smi->si_sm); | 2444 | kfree(new_smi->si_sm); |
2393 | } | 2445 | } |
2446 | if (new_smi->addr_source_cleanup) | ||
2447 | new_smi->addr_source_cleanup(new_smi); | ||
2394 | if (new_smi->io_cleanup) | 2448 | if (new_smi->io_cleanup) |
2395 | new_smi->io_cleanup(new_smi); | 2449 | new_smi->io_cleanup(new_smi); |
2396 | 2450 | ||
2451 | if (new_smi->dev_registered) | ||
2452 | platform_device_unregister(new_smi->pdev); | ||
2453 | |||
2454 | kfree(new_smi); | ||
2455 | |||
2456 | up(&smi_infos_lock); | ||
2457 | |||
2397 | return rv; | 2458 | return rv; |
2398 | } | 2459 | } |
2399 | 2460 | ||
2400 | static __init int init_ipmi_si(void) | 2461 | static __devinit int init_ipmi_si(void) |
2401 | { | 2462 | { |
2402 | int rv = 0; | ||
2403 | int pos = 0; | ||
2404 | int i; | 2463 | int i; |
2405 | char *str; | 2464 | char *str; |
2465 | int rv; | ||
2406 | 2466 | ||
2407 | if (initialized) | 2467 | if (initialized) |
2408 | return 0; | 2468 | return 0; |
2409 | initialized = 1; | 2469 | initialized = 1; |
2410 | 2470 | ||
2471 | /* Register the device drivers. */ | ||
2472 | rv = driver_register(&ipmi_driver); | ||
2473 | if (rv) { | ||
2474 | printk(KERN_ERR | ||
2475 | "init_ipmi_si: Unable to register driver: %d\n", | ||
2476 | rv); | ||
2477 | return rv; | ||
2478 | } | ||
2479 | |||
2480 | |||
2411 | /* Parse out the si_type string into its components. */ | 2481 | /* Parse out the si_type string into its components. */ |
2412 | str = si_type_str; | 2482 | str = si_type_str; |
2413 | if (*str != '\0') { | 2483 | if (*str != '\0') { |
@@ -2425,63 +2495,66 @@ static __init int init_ipmi_si(void) | |||
2425 | 2495 | ||
2426 | printk(KERN_INFO "IPMI System Interface driver.\n"); | 2496 | printk(KERN_INFO "IPMI System Interface driver.\n"); |
2427 | 2497 | ||
2498 | hardcode_find_bmc(); | ||
2499 | |||
2428 | #ifdef CONFIG_DMI | 2500 | #ifdef CONFIG_DMI |
2429 | dmi_find_bmc(); | 2501 | dmi_find_bmc(); |
2430 | #endif | 2502 | #endif |
2431 | 2503 | ||
2432 | rv = init_one_smi(0, &(smi_infos[pos])); | 2504 | #ifdef CONFIG_ACPI |
2433 | if (rv && ! ports[0] && si_trydefaults) { | 2505 | if (si_trydefaults) |
2434 | /* If we are trying defaults and the initial port is | 2506 | acpi_find_bmc(); |
2435 | not set, then set it. */ | 2507 | #endif |
2436 | si_type[0] = "kcs"; | ||
2437 | ports[0] = DEFAULT_KCS_IO_PORT; | ||
2438 | rv = init_one_smi(0, &(smi_infos[pos])); | ||
2439 | if (rv) { | ||
2440 | /* No KCS - try SMIC */ | ||
2441 | si_type[0] = "smic"; | ||
2442 | ports[0] = DEFAULT_SMIC_IO_PORT; | ||
2443 | rv = init_one_smi(0, &(smi_infos[pos])); | ||
2444 | } | ||
2445 | if (rv) { | ||
2446 | /* No SMIC - try BT */ | ||
2447 | si_type[0] = "bt"; | ||
2448 | ports[0] = DEFAULT_BT_IO_PORT; | ||
2449 | rv = init_one_smi(0, &(smi_infos[pos])); | ||
2450 | } | ||
2451 | } | ||
2452 | if (rv == 0) | ||
2453 | pos++; | ||
2454 | 2508 | ||
2455 | for (i = 1; i < SI_MAX_PARMS; i++) { | 2509 | #ifdef CONFIG_PCI |
2456 | rv = init_one_smi(i, &(smi_infos[pos])); | 2510 | pci_module_init(&ipmi_pci_driver); |
2457 | if (rv == 0) | 2511 | #endif |
2458 | pos++; | 2512 | |
2513 | if (si_trydefaults) { | ||
2514 | down(&smi_infos_lock); | ||
2515 | if (list_empty(&smi_infos)) { | ||
2516 | /* No BMC was found, try defaults. */ | ||
2517 | up(&smi_infos_lock); | ||
2518 | default_find_bmc(); | ||
2519 | } else { | ||
2520 | up(&smi_infos_lock); | ||
2521 | } | ||
2459 | } | 2522 | } |
2460 | 2523 | ||
2461 | if (smi_infos[0] == NULL) { | 2524 | down(&smi_infos_lock); |
2525 | if (list_empty(&smi_infos)) { | ||
2526 | up(&smi_infos_lock); | ||
2527 | #ifdef CONFIG_PCI | ||
2528 | pci_unregister_driver(&ipmi_pci_driver); | ||
2529 | #endif | ||
2462 | printk("ipmi_si: Unable to find any System Interface(s)\n"); | 2530 | printk("ipmi_si: Unable to find any System Interface(s)\n"); |
2463 | return -ENODEV; | 2531 | return -ENODEV; |
2532 | } else { | ||
2533 | up(&smi_infos_lock); | ||
2534 | return 0; | ||
2464 | } | 2535 | } |
2465 | |||
2466 | return 0; | ||
2467 | } | 2536 | } |
2468 | module_init(init_ipmi_si); | 2537 | module_init(init_ipmi_si); |
2469 | 2538 | ||
2470 | static void __exit cleanup_one_si(struct smi_info *to_clean) | 2539 | static void __devexit cleanup_one_si(struct smi_info *to_clean) |
2471 | { | 2540 | { |
2472 | int rv; | 2541 | int rv; |
2473 | unsigned long flags; | 2542 | unsigned long flags; |
2474 | 2543 | ||
2475 | if (! to_clean) | 2544 | if (!to_clean) |
2476 | return; | 2545 | return; |
2477 | 2546 | ||
2547 | list_del(&to_clean->link); | ||
2548 | |||
2478 | /* Tell the timer and interrupt handlers that we are shutting | 2549 | /* Tell the timer and interrupt handlers that we are shutting |
2479 | down. */ | 2550 | down. */ |
2480 | spin_lock_irqsave(&(to_clean->si_lock), flags); | 2551 | spin_lock_irqsave(&(to_clean->si_lock), flags); |
2481 | spin_lock(&(to_clean->msg_lock)); | 2552 | spin_lock(&(to_clean->msg_lock)); |
2482 | 2553 | ||
2483 | atomic_inc(&to_clean->stop_operation); | 2554 | atomic_inc(&to_clean->stop_operation); |
2484 | to_clean->irq_cleanup(to_clean); | 2555 | |
2556 | if (to_clean->irq_cleanup) | ||
2557 | to_clean->irq_cleanup(to_clean); | ||
2485 | 2558 | ||
2486 | spin_unlock(&(to_clean->msg_lock)); | 2559 | spin_unlock(&(to_clean->msg_lock)); |
2487 | spin_unlock_irqrestore(&(to_clean->si_lock), flags); | 2560 | spin_unlock_irqrestore(&(to_clean->si_lock), flags); |
@@ -2511,20 +2584,34 @@ static void __exit cleanup_one_si(struct smi_info *to_clean) | |||
2511 | 2584 | ||
2512 | kfree(to_clean->si_sm); | 2585 | kfree(to_clean->si_sm); |
2513 | 2586 | ||
2587 | if (to_clean->addr_source_cleanup) | ||
2588 | to_clean->addr_source_cleanup(to_clean); | ||
2514 | if (to_clean->io_cleanup) | 2589 | if (to_clean->io_cleanup) |
2515 | to_clean->io_cleanup(to_clean); | 2590 | to_clean->io_cleanup(to_clean); |
2591 | |||
2592 | if (to_clean->dev_registered) | ||
2593 | platform_device_unregister(to_clean->pdev); | ||
2594 | |||
2595 | kfree(to_clean); | ||
2516 | } | 2596 | } |
2517 | 2597 | ||
2518 | static __exit void cleanup_ipmi_si(void) | 2598 | static __exit void cleanup_ipmi_si(void) |
2519 | { | 2599 | { |
2520 | int i; | 2600 | struct smi_info *e, *tmp_e; |
2521 | 2601 | ||
2522 | if (! initialized) | 2602 | if (!initialized) |
2523 | return; | 2603 | return; |
2524 | 2604 | ||
2525 | for (i = 0; i < SI_MAX_DRIVERS; i++) { | 2605 | #ifdef CONFIG_PCI |
2526 | cleanup_one_si(smi_infos[i]); | 2606 | pci_unregister_driver(&ipmi_pci_driver); |
2527 | } | 2607 | #endif |
2608 | |||
2609 | down(&smi_infos_lock); | ||
2610 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) | ||
2611 | cleanup_one_si(e); | ||
2612 | up(&smi_infos_lock); | ||
2613 | |||
2614 | driver_unregister(&ipmi_driver); | ||
2528 | } | 2615 | } |
2529 | module_exit(cleanup_ipmi_si); | 2616 | module_exit(cleanup_ipmi_si); |
2530 | 2617 | ||