Changeset 1615
- Timestamp:
- 11/16/02 20:40:06 (6 years ago)
- Files:
-
- lm-sensors/trunk/kernel/busses/i2c-ipmi.c (modified) (13 diffs)
- lm-sensors/trunk/kernel/chips/bmcsensors.c (modified) (13 diffs)
- lm-sensors/trunk/prog/sensors/chips.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lm-sensors/trunk/kernel/busses/i2c-ipmi.c
r1593 r1615 1 1 /* 2 i2c- bmc.c - Part of lm_sensors, Linux kernel modules for hardware2 i2c-ipmi.c - Part of lm_sensors, Linux kernel modules for hardware 3 3 monitoring 4 4 Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> … … 20 20 21 21 /* 22 This implements an 22 This implements a "dummy" i2c adapter for clients to access the 23 BMC via IPMI messages. Supports only one BMC and one client for now! 23 24 */ 24 25 25 #include <linux/version.h>26 26 #include <linux/module.h> 27 27 #include <linux/kernel.h> … … 31 31 #include "version.h" 32 32 33 34 static void bmc_inc_use(struct i2c_adapter *adapter);35 static void bmc_dec_use(struct i2c_adapter *adapter);36 static u32 bmc_func(struct i2c_adapter *adapter);33 static void i2c_ipmi_inc_use(struct i2c_adapter *adapter); 34 static void i2c_ipmi_dec_use(struct i2c_adapter *adapter); 35 static u32 i2c_ipmi_func(struct i2c_adapter *adapter); 36 static int bmcclient_i2c_send_message(struct i2c_adapter *, char *, int); 37 37 38 38 #ifdef MODULE … … 41 41 extern 42 42 #endif 43 int __init i2c_ bmc_init(void);44 static int __init bmc_cleanup(void);43 int __init i2c_ipmi_init(void); 44 static int __init i2c_ipmi_cleanup(void); 45 45 46 46 #ifdef MODULE … … 50 50 51 51 /* I2C Data */ 52 /* This is the actual algorithm we define */ 53 static struct i2c_algorithm bmc_algorithm = { 54 /* name */ "IPMI algorithm", 55 /* id */ I2C_ALGO_IPMI, 56 /* master_xfer */ NULL, 57 /* smbus_access */ NULL, 58 /* slave_send */ NULL, 59 /* slave_rcv */ NULL, 60 /* algo_control */ NULL, 61 /* functionality */ &bmc_func, 62 }; 63 64 static struct i2c_adapter bmc_adapter = { 65 /* name */ "IPMI adapter", 66 /* id */ I2C_ALGO_IPMI | I2C_HW_IPMI, 67 /* algorithm */ &bmc_algorithm, 68 /* algo_data */ NULL, 69 /* inc_use */ &bmc_inc_use, 70 /* dec_use */ &bmc_dec_use, 71 /* data */ NULL, 52 static struct i2c_algorithm i2c_ipmi_algorithm = { 53 .name = "IPMI algorithm", 54 .id = I2C_ALGO_IPMI, 55 .master_xfer = NULL, 56 .smbus_xfer = NULL, 57 .slave_send = &bmcclient_i2c_send_message, 58 .slave_recv = NULL, 59 .algo_control = NULL, 60 .functionality = &i2c_ipmi_func, 61 }; 62 63 static struct i2c_adapter i2c_ipmi_adapter = { 64 .name = "IPMI adapter", 65 .id = I2C_ALGO_IPMI | I2C_HW_IPMI, 66 .algo = &i2c_ipmi_algorithm, 67 .algo_data = NULL, 68 .inc_use = &i2c_ipmi_inc_use, 69 .dec_use = &i2c_ipmi_dec_use, 70 .data = NULL, 72 71 /* Other fields not initialized */ 73 72 }; 74 73 75 74 /* IPMI Data */ 76 static ipmi_user_t i2c_bmc_user;77 75 static ipmi_user_t i2c_ipmi_user; 78 76 static unsigned char ipmi_version_major; … … 82 80 IPMI_SYSTEM_INTERFACE_ADDR_TYPE, 83 81 IPMI_BMC_CHANNEL, 84 NULL82 {0} 85 83 }; /* send address */ 86 84 static struct ipmi_msg message; /* send message */ 87 85 static long msgid; /* message ID */ 88 static int interfaces; 89 static int (*rcv_callback)(struct i2c_client *client,unsigned int cmd, void *arg); 90 91 /* Used in bmc_init/cleanup */ 92 /* 93 static int __initdata bmc_initialized; 94 */ 95 96 void bmc_inc_use(struct i2c_adapter *adapter) 86 static int interfaces; /* number of BMC's found */ 87 static int (*rcv_callback)(struct i2c_client *client, unsigned int cmd, 88 void *arg); 89 90 void i2c_ipmi_inc_use(struct i2c_adapter *adapter) 97 91 { 98 92 #ifdef MODULE … … 101 95 } 102 96 103 void bmc_dec_use(struct i2c_adapter *adapter)97 void i2c_ipmi_dec_use(struct i2c_adapter *adapter) 104 98 { 105 99 #ifdef MODULE … … 108 102 } 109 103 110 /* We can't do a thing... */ 111 static u32 bmc_func(struct i2c_adapter *adapter) 112 { 113 return 0; 114 } 115 116 /*-----------------------------------*/ 117 118 void bmc_i2c_send_message(int id, struct ipmi_msg * msg) 119 { 120 ipmi_request(i2c_bmc_user, &address, id, msg, 0); 121 } 122 123 void bmcclient_i2c_send_message(struct i2c_client *client, int id, struct ipmi_msg * msg) 124 { 125 id = (id & 0xffff) | 0x10000; 104 /* Dummy adapter... */ 105 static u32 i2c_ipmi_func(struct i2c_adapter *adapter) 106 { 107 return 0; 108 } 109 110 /************** Message Sending **************/ 111 112 static void ipmi_i2c_send_message(int id, struct ipmi_msg * msg) 113 { 114 ipmi_request(i2c_ipmi_user, &address, id, msg, 0); 115 } 116 117 /* This is the message send function exported to the client 118 via the i2c_adapter struct. 119 We use the existing (but unused) slave_send function pointer. 120 Hence the ugly casts. */ 121 static int bmcclient_i2c_send_message(struct i2c_adapter *clnt, 122 char * mesg, int id) 123 { 124 struct ipmi_msg *msg = (struct ipmi_msg *) mesg; 125 struct i2c_client *client = (struct i2c_client *) clnt; 126 127 /* todo: keep track of multiple clients and save callback for each */ 128 id = (id & 0xffffff) | 0x1000000; 126 129 rcv_callback = client->driver->command; 127 bmc_i2c_send_message(id, msg); 128 } 129 130 ipmi_i2c_send_message(id, msg); 131 return 0; 132 } 133 134 /************** Message Receiving **************/ 130 135 131 136 static void ipmi_i2c_msg_handler(struct ipmi_recv_msg *msg, 132 137 void *handler_data) 133 138 { 134 int rcvid = msg->msgid & 0xffff; 135 int client = (msg->msgid >> 16) & 0xf; 136 137 if (msg->msg.data[0] != 0) { 138 printk(KERN_ERR "IPMI BMC response: Error 0x%x on cmd 0x%x\n", 139 msg->msg.data[0], 140 msg->msg.cmd); 141 } else { 142 /* 143 printk(KERN_INFO "IPMI BMC response: No error on cmd 0x%x\n", 144 msg->msg.cmd); 145 */ 146 } 147 148 139 int rcvid = msg->msgid & 0xffffff; 140 int client = (msg->msgid >> 24) & 0xf; 141 142 if (msg->msg.data[0] != 0) 143 printk(KERN_WARNING "IPMI BMC response: Error 0x%x on cmd 0x%x\n", 144 msg->msg.data[0], msg->msg.cmd); 145 146 /* todo: keep track of multiple clients */ 149 147 if(client == 1 && rcv_callback != NULL) 150 148 (*rcv_callback)(NULL, client, msg); … … 158 156 }; 159 157 158 /**************** Initialization ****************/ 159 160 160 /* callback for each BMC found */ 161 161 static void ipmi_register_bmc(int ipmi_intf) 162 162 { 163 163 unsigned long flags; 164 int rv = -EBUSY;164 int rv; 165 165 166 166 if(interfaces > 0) { /* 1 max for now */ 167 167 printk(KERN_INFO 168 "i2c- bmc.o: Additional IPMI interface %d not supported\n",168 "i2c-ipmi.o: Additional IPMI interface %d not supported\n", 169 169 ipmi_intf); 170 170 return; 171 171 } 172 172 173 rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &i2c_ bmc_user);173 rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &i2c_ipmi_user); 174 174 if (rv < 0) { 175 printk(KERN_ERR "i2c- bmc.o: Unable to register with ipmi\n");175 printk(KERN_ERR "i2c-ipmi.o: Unable to register with ipmi\n"); 176 176 return; 177 177 } 178 178 179 ipmi_get_version(i2c_bmc_user, 180 &ipmi_version_major, 181 &ipmi_version_minor); 182 183 if ((rv = i2c_add_adapter(&bmc_adapter))) { 184 printk(KERN_ERR "i2c-bmc.o: Adapter registration failed, " 185 "module i2c-bmc.o is not inserted\n."); 179 if ((rv = i2c_add_adapter(&i2c_ipmi_adapter))) { 180 printk(KERN_ERR "i2c-ipmi.o: Adapter registration failed, " 181 "module i2c-ipmi.o is not inserted\n."); 186 182 return; 187 183 } 188 184 185 ipmi_get_version(i2c_ipmi_user, &ipmi_version_major, 186 &ipmi_version_minor); 189 187 printk(KERN_INFO 190 "i2c- bmc.o: Registered IPMI interface %d with version %d.%d\n",188 "i2c-ipmi.o: Registered IPMI interface %d with version %d.%d\n", 191 189 ipmi_intf, ipmi_version_major, ipmi_version_minor); 192 190 interfaces++; 193 191 } 194 192 195 196 193 static void ipmi_new_smi(int if_num) 197 194 { … … 201 198 static void ipmi_smi_gone(int if_num) 202 199 { 203 /* TBD */ 200 if (interfaces >= 1) { 201 i2c_del_adapter(&i2c_ipmi_adapter); 202 ipmi_destroy_user(i2c_ipmi_user); 203 interfaces--; 204 } 204 205 } 205 206 … … 210 211 }; 211 212 212 int __init i2c_ bmc_init(void)213 int __init i2c_ipmi_init(void) 213 214 { 214 215 int rv; 215 216 216 printk(KERN_INFO "i2c- bmc.o version %s (%s)\n", LM_VERSION, LM_DATE);217 printk(KERN_INFO "i2c-ipmi.o version %s (%s)\n", LM_VERSION, LM_DATE); 217 218 218 219 rv = ipmi_smi_watcher_register(&smi_watcher); … … 223 224 } 224 225 225 printk(KERN_INFO "i2c- bmc.o: BMC access for i2c modules initialized.\n");226 return 0; 227 } 228 229 int __init bmc_cleanup(void)226 printk(KERN_INFO "i2c-ipmi.o: BMC access for i2c modules initialized.\n"); 227 return 0; 228 } 229 230 int __init ipmi_cleanup(void) 230 231 { 231 232 ipmi_smi_watcher_unregister(&smi_watcher); 232 if (interfaces >= 1) { 233 i2c_del_adapter(&bmc_adapter); 234 ipmi_destroy_user(i2c_bmc_user); 235 interfaces--; 236 } 237 return 0; 238 } 239 240 #ifdef MODULE 241 EXPORT_SYMBOL(bmcclient_i2c_send_message); 242 233 ipmi_smi_gone(0); 234 return 0; 235 } 236 237 #ifdef MODULE 243 238 MODULE_AUTHOR("M. D. Studebaker <mdsxyz123@yahoo.com>"); 244 MODULE_DESCRIPTION(" BMC busaccess through i2c");239 MODULE_DESCRIPTION("IPMI-BMC access through i2c"); 245 240 #ifdef MODULE_LICENSE 246 241 MODULE_LICENSE("GPL"); … … 249 244 int init_module(void) 250 245 { 251 return i2c_ bmc_init();246 return i2c_ipmi_init(); 252 247 } 253 248 254 249 int cleanup_module(void) 255 250 { 256 return bmc_cleanup();251 return ipmi_cleanup(); 257 252 } 258 253 lm-sensors/trunk/kernel/chips/bmcsensors.c
r1605 r1615 130 130 u8 capab; 131 131 u16 thresh_mask; 132 u8 format; 132 133 u8 linear; 133 134 s16 m; … … 233 234 "lower critical threshold", 234 235 "lower non-critical threshold", 235 "positive-going hysteresis", /* not used */236 "negative-going hysteresis" 236 "positive-going hysteresis", 237 "negative-going hysteresis" /* unused */ 237 238 }; 238 239 … … 270 271 /* select lower threshold */ 271 272 if(((capab & 0x30) == 0x10) || /* readable hysteresis ? */ 272 ((capab & 0x30) == 0x20)) /* neghyst */273 sdrd[i].lim2 = 7;273 ((capab & 0x30) == 0x20)) /* pos hyst */ 274 sdrd[i].lim2 = 6; 274 275 else if(mask & 0x02) { /* lower crit */ 275 276 sdrd[i].lim2 = 4; … … 359 360 } 360 361 sdrd[i].sysctl = bmcsensors_dir_table[i].ctl_name; 361 if(sdrd[i].linear != 0) { 362 printk(KERN_INFO "bmcsensors.o: sensor %d: (type 0x%x) nonlinear function 0x%.2x unsupported\n", 363 i, sdrd[i].stype, sdrd[i].linear); 364 } 365 ipmi_sprintf(id, sdrd[i].id, sdrd[i].string_type, sdrd[i].id_length); 366 printk(KERN_INFO "bmcsensors.o: registering sensor %d: '%s' (type 0x%.2x) as %s " 367 "(m=%d; b=%d; k1=%d; k2=%d; cap=0x%.2x; mask=0x%.4x)\n", 368 i, id, sdrd[i].stype, bmcsensors_dir_table[i].procname, 362 printk(KERN_INFO "bmcsensors.o: registering sensor %d: (type 0x%.2x) " 363 "(fmt=%d; m=%d; b=%d; k1=%d; k2=%d; cap=0x%.2x; mask=0x%.4x)\n", 364 i, sdrd[i].stype, sdrd[i].format, 369 365 sdrd[i].m, sdrd[i].b,sdrd[i].k & 0xf, sdrd[i].k >> 4, 370 366 sdrd[i].capab, sdrd[i].thresh_mask); 367 if(sdrd[i].id_length) { 368 ipmi_sprintf(id, sdrd[i].id, sdrd[i].string_type, sdrd[i].id_length); 369 printk(KERN_INFO "bmcsensors.o: sensors.conf: label %s \"%s\"\n", 370 bmcsensors_dir_table[i].procname, id); 371 } 371 372 bmcsensors_select_thresholds(i); 373 if(sdrd[i].linear != 0) { 374 printk(KERN_INFO "bmcsensors.o: sensor %d: nonlinear function 0x%.2x unsupported\n", 375 i, sdrd[i].linear); 376 } 377 if((sdrd[i].format & 0x03) == 0x02) { 378 printk(KERN_INFO "bmcsensors.o: sensor %d: 1's complement format unsupported\n", 379 i); 380 } else if((sdrd[i].format & 0x03) == 0x03) { 381 printk(KERN_INFO "bmcsensors.o: sensor %d: threshold sensor only, no readings available", 382 i); 383 } 372 384 if(sdrd[i].lim1_write || sdrd[i].lim2_write) 373 385 bmcsensors_dir_table[i].mode = 0644; … … 495 507 sdrd[sdrd_count].thresh_mask = (data[22] << 8) | data[21]; 496 508 if(type == 1) { 509 sdrd[sdrd_count].format = data[24] >> 6; 497 510 sdrd[sdrd_count].linear = data[26] & 0x7f; 498 511 sdrd[sdrd_count].m = data[27]; … … 529 542 } 530 543 } 531 /*532 } else {533 printk(KERN_INFO "bmcsensors.o: Ignoring sensor type 0x%x\n", stype);534 }535 */536 /*537 printk(KERN_INFO "bmcsensors.o: STATE_SDR: record = 0x%x; version = 0x%x, type = 0x%x; length=0x%x\n",538 record, version, type, length);539 printk(KERN_INFO "bmcsensors.o: STATE_SDR: owner = 0x%x; lun = 0x%x, number = 0x%x; entity=0x%x\n",540 owner, lun, number, entity);541 printk(KERN_INFO "bmcsensors.o: STATE_SDR: instance = 0x%x; init = 0x%x, capab = 0x%x; stype=0x%x\n",542 instance, init, capab, stype);543 printk(KERN_INFO "bmcsensors.o: STATE_SDR: code = 0x%x\n",544 code);545 printk(KERN_INFO "bmcsensors.o: STATE_SDR: next = 0x%x\n", nextrecord);546 } else {547 printk(KERN_INFO "bmcsensors.o: unknown STATE_SDR type 0x%x\n", type);548 */549 544 } 550 545 … … 616 611 msg->cmd); 617 612 #endif 613 /* 618 614 bmcclient_i2c_send_message(&bmc_client, msgid++, msg); 615 */ 616 bmc_client.adapter->algo->slave_send((struct i2c_adapter *) &bmc_client, 617 (char *) msg, msgid++); 619 618 620 619 } … … 661 660 int bmcsensors_attach_adapter(struct i2c_adapter *adapter) 662 661 { 663 /* 664 not really i2c or isa so i2c_detect not required 665 */ 666 printk(KERN_INFO "bmcsensors.o: in bmcsensors_detect() for ID %x\n", 667 adapter->algo->id); 668 669 if(adapter->algo->id != I2C_ALGO_IPMI) { 662 if(adapter->algo->id != I2C_ALGO_IPMI) 670 663 return 0; 671 }672 664 673 665 if(bmcsensors_initialized >= 2) { 674 printk(KERN_INFO "bmcsensors.o: limit of 1\n");666 printk(KERN_INFO "bmcsensors.o: Additional IPMI adapter not supported\n"); 675 667 return 0; 676 668 } … … 687 679 bmc_client.adapter = adapter; 688 680 bmc_data.valid = 0; 689 /*690 init_MUTEX(bmc_data.update_lock);691 */692 681 693 682 if ((err = i2c_attach_client(&bmc_client))) { … … 697 686 bmcsensors_initialized = 2; 698 687 699 /* initialize some key data */700 688 state = STATE_INIT; 701 689 sdrd_count = 0; … … 776 764 if(state != STATE_READING) { 777 765 state = STATE_READING; 778 printk(KERN_DEBUG "bmcsensors.o: Starting update\n");779 766 bmcsensors_get_reading(client, 0); 780 767 } … … 819 806 long r; 820 807 808 /* fixme signed/unsigned */ 809 r = value * sdrd[i].m; 810 821 811 k1 = sdrd[i].k & 0x0f; 822 812 k2 = sdrd[i].k >> 4; 823 824 r = value * sdrd[i].m;825 813 if(k1 < 8) 826 814 r += sdrd[i].b * exps[k1]; … … 867 855 else 868 856 results[0] = 0; 869 if(sdrd[i].lim2 >= 0) 857 results[2] = convert_value(sdrd[i].reading, i); 858 if(sdrd[i].lim2 >= 0) { 870 859 results[1] = convert_value(sdrd[i].limits[sdrd[i].lim2], i); 871 else 860 if(sdrd[i].lim2 == 6) /* pos. threshold */ 861 results[1] = results[2] - results[1]; 862 } else 872 863 results[1] = 0; 873 results[2] = convert_value(sdrd[i].reading, i);874 864 *nrels_mag = 3; 875 865 } lm-sensors/trunk/prog/sensors/chips.c
r1606 r1615 3650 3650 { 3651 3651 char *label = NULL; 3652 double cur,min,max ,fdiv;3652 double cur,min,max; 3653 3653 int alarms, valid, i; 3654 3654 … … 3683 3683 if (!sensors_get_label_and_valid(*name,SENSORS_BMC_FAN1+i,&label,&valid) && 3684 3684 !sensors_get_feature(*name,SENSORS_BMC_FAN1+i,&cur) && 3685 /*3686 !sensors_get_feature(*name,SENSORS_BMC_FAN1_DIV+i,&fdiv) &&3687 */3688 3685 !sensors_get_feature(*name,SENSORS_BMC_FAN1_MIN+i,&min)) { 3689 3686 if (valid) { 3690 3687 print_label(label,10); 3691 printf("%4.0f RPM (min = %4.0f RPM , div = %1.0f)%s\n",3692 cur,min, fdiv,alarms&BMC_ALARM_FAN1?"ALARM":"");3688 printf("%4.0f RPM (min = %4.0f RPM) %s\n", 3689 cur,min,alarms&BMC_ALARM_FAN1?"ALARM":""); 3693 3690 } 3694 3691 }
