diff options
author | Corey Minyard <minyard@acm.org> | 2005-09-06 18:18:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 19:57:47 -0400 |
commit | c14979b993021377228958498937bcdd9539cbce (patch) | |
tree | e30638df99aa69f707e7549e4e990e9e92d477ae | |
parent | b224cd3a0ca376dd52f382905c1aaf5a83a54692 (diff) |
[PATCH] ipmi: add per-channel IPMB addresses
IPMI allows multiple IPMB channels on a single interface, and each channel
might have a different IPMB address. However, the driver has only one IPMB
address that it uses for everything. This patch adds new IOCTLS and a new
internal interface for setting per-channel IPMB addresses and LUNs. New
systems are coming out with support for multiple IPMB channels, and they are
broken without this patch.
Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/char/ipmi/ipmi_devintf.c | 94 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 137 | ||||
-rw-r--r-- | include/linux/ipmi.h | 30 |
3 files changed, 201 insertions, 60 deletions
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index e0a53570fea1..5571e92c520f 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -411,6 +411,7 @@ static int ipmi_ioctl(struct inode *inode, | |||
411 | break; | 411 | break; |
412 | } | 412 | } |
413 | 413 | ||
414 | /* The next four are legacy, not per-channel. */ | ||
414 | case IPMICTL_SET_MY_ADDRESS_CMD: | 415 | case IPMICTL_SET_MY_ADDRESS_CMD: |
415 | { | 416 | { |
416 | unsigned int val; | 417 | unsigned int val; |
@@ -420,22 +421,25 @@ static int ipmi_ioctl(struct inode *inode, | |||
420 | break; | 421 | break; |
421 | } | 422 | } |
422 | 423 | ||
423 | ipmi_set_my_address(priv->user, val); | 424 | rv = ipmi_set_my_address(priv->user, 0, val); |
424 | rv = 0; | ||
425 | break; | 425 | break; |
426 | } | 426 | } |
427 | 427 | ||
428 | case IPMICTL_GET_MY_ADDRESS_CMD: | 428 | case IPMICTL_GET_MY_ADDRESS_CMD: |
429 | { | 429 | { |
430 | unsigned int val; | 430 | unsigned int val; |
431 | unsigned char rval; | ||
432 | |||
433 | rv = ipmi_get_my_address(priv->user, 0, &rval); | ||
434 | if (rv) | ||
435 | break; | ||
431 | 436 | ||
432 | val = ipmi_get_my_address(priv->user); | 437 | val = rval; |
433 | 438 | ||
434 | if (copy_to_user(arg, &val, sizeof(val))) { | 439 | if (copy_to_user(arg, &val, sizeof(val))) { |
435 | rv = -EFAULT; | 440 | rv = -EFAULT; |
436 | break; | 441 | break; |
437 | } | 442 | } |
438 | rv = 0; | ||
439 | break; | 443 | break; |
440 | } | 444 | } |
441 | 445 | ||
@@ -448,24 +452,94 @@ static int ipmi_ioctl(struct inode *inode, | |||
448 | break; | 452 | break; |
449 | } | 453 | } |
450 | 454 | ||
451 | ipmi_set_my_LUN(priv->user, val); | 455 | rv = ipmi_set_my_LUN(priv->user, 0, val); |
452 | rv = 0; | ||
453 | break; | 456 | break; |
454 | } | 457 | } |
455 | 458 | ||
456 | case IPMICTL_GET_MY_LUN_CMD: | 459 | case IPMICTL_GET_MY_LUN_CMD: |
457 | { | 460 | { |
458 | unsigned int val; | 461 | unsigned int val; |
462 | unsigned char rval; | ||
463 | |||
464 | rv = ipmi_get_my_LUN(priv->user, 0, &rval); | ||
465 | if (rv) | ||
466 | break; | ||
459 | 467 | ||
460 | val = ipmi_get_my_LUN(priv->user); | 468 | val = rval; |
461 | 469 | ||
462 | if (copy_to_user(arg, &val, sizeof(val))) { | 470 | if (copy_to_user(arg, &val, sizeof(val))) { |
463 | rv = -EFAULT; | 471 | rv = -EFAULT; |
464 | break; | 472 | break; |
465 | } | 473 | } |
466 | rv = 0; | ||
467 | break; | 474 | break; |
468 | } | 475 | } |
476 | |||
477 | case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD: | ||
478 | { | ||
479 | struct ipmi_channel_lun_address_set val; | ||
480 | |||
481 | if (copy_from_user(&val, arg, sizeof(val))) { | ||
482 | rv = -EFAULT; | ||
483 | break; | ||
484 | } | ||
485 | |||
486 | return ipmi_set_my_address(priv->user, val.channel, val.value); | ||
487 | break; | ||
488 | } | ||
489 | |||
490 | case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD: | ||
491 | { | ||
492 | struct ipmi_channel_lun_address_set val; | ||
493 | |||
494 | if (copy_from_user(&val, arg, sizeof(val))) { | ||
495 | rv = -EFAULT; | ||
496 | break; | ||
497 | } | ||
498 | |||
499 | rv = ipmi_get_my_address(priv->user, val.channel, &val.value); | ||
500 | if (rv) | ||
501 | break; | ||
502 | |||
503 | if (copy_to_user(arg, &val, sizeof(val))) { | ||
504 | rv = -EFAULT; | ||
505 | break; | ||
506 | } | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | case IPMICTL_SET_MY_CHANNEL_LUN_CMD: | ||
511 | { | ||
512 | struct ipmi_channel_lun_address_set val; | ||
513 | |||
514 | if (copy_from_user(&val, arg, sizeof(val))) { | ||
515 | rv = -EFAULT; | ||
516 | break; | ||
517 | } | ||
518 | |||
519 | rv = ipmi_set_my_LUN(priv->user, val.channel, val.value); | ||
520 | break; | ||
521 | } | ||
522 | |||
523 | case IPMICTL_GET_MY_CHANNEL_LUN_CMD: | ||
524 | { | ||
525 | struct ipmi_channel_lun_address_set val; | ||
526 | |||
527 | if (copy_from_user(&val, arg, sizeof(val))) { | ||
528 | rv = -EFAULT; | ||
529 | break; | ||
530 | } | ||
531 | |||
532 | rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value); | ||
533 | if (rv) | ||
534 | break; | ||
535 | |||
536 | if (copy_to_user(arg, &val, sizeof(val))) { | ||
537 | rv = -EFAULT; | ||
538 | break; | ||
539 | } | ||
540 | break; | ||
541 | } | ||
542 | |||
469 | case IPMICTL_SET_TIMING_PARMS_CMD: | 543 | case IPMICTL_SET_TIMING_PARMS_CMD: |
470 | { | 544 | { |
471 | struct ipmi_timing_parms parms; | 545 | struct ipmi_timing_parms parms; |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e16c13fe698d..84d477c6f925 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -124,6 +124,14 @@ struct ipmi_channel | |||
124 | { | 124 | { |
125 | unsigned char medium; | 125 | unsigned char medium; |
126 | unsigned char protocol; | 126 | unsigned char protocol; |
127 | |||
128 | /* My slave address. This is initialized to IPMI_BMC_SLAVE_ADDR, | ||
129 | but may be changed by the user. */ | ||
130 | unsigned char address; | ||
131 | |||
132 | /* My LUN. This should generally stay the SMS LUN, but just in | ||
133 | case... */ | ||
134 | unsigned char lun; | ||
127 | }; | 135 | }; |
128 | 136 | ||
129 | #ifdef CONFIG_PROC_FS | 137 | #ifdef CONFIG_PROC_FS |
@@ -135,7 +143,7 @@ struct ipmi_proc_entry | |||
135 | #endif | 143 | #endif |
136 | 144 | ||
137 | #define IPMI_IPMB_NUM_SEQ 64 | 145 | #define IPMI_IPMB_NUM_SEQ 64 |
138 | #define IPMI_MAX_CHANNELS 8 | 146 | #define IPMI_MAX_CHANNELS 16 |
139 | struct ipmi_smi | 147 | struct ipmi_smi |
140 | { | 148 | { |
141 | /* What interface number are we? */ | 149 | /* What interface number are we? */ |
@@ -199,14 +207,6 @@ struct ipmi_smi | |||
199 | this is registered. */ | 207 | this is registered. */ |
200 | ipmi_user_t all_cmd_rcvr; | 208 | ipmi_user_t all_cmd_rcvr; |
201 | 209 | ||
202 | /* My slave address. This is initialized to IPMI_BMC_SLAVE_ADDR, | ||
203 | but may be changed by the user. */ | ||
204 | unsigned char my_address; | ||
205 | |||
206 | /* My LUN. This should generally stay the SMS LUN, but just in | ||
207 | case... */ | ||
208 | unsigned char my_lun; | ||
209 | |||
210 | /* The event receiver for my BMC, only really used at panic | 210 | /* The event receiver for my BMC, only really used at panic |
211 | shutdown as a place to store this. */ | 211 | shutdown as a place to store this. */ |
212 | unsigned char event_receiver; | 212 | unsigned char event_receiver; |
@@ -766,26 +766,44 @@ void ipmi_get_version(ipmi_user_t user, | |||
766 | *minor = user->intf->version_minor; | 766 | *minor = user->intf->version_minor; |
767 | } | 767 | } |
768 | 768 | ||
769 | void ipmi_set_my_address(ipmi_user_t user, | 769 | int ipmi_set_my_address(ipmi_user_t user, |
770 | unsigned char address) | 770 | unsigned int channel, |
771 | unsigned char address) | ||
771 | { | 772 | { |
772 | user->intf->my_address = address; | 773 | if (channel >= IPMI_MAX_CHANNELS) |
774 | return -EINVAL; | ||
775 | user->intf->channels[channel].address = address; | ||
776 | return 0; | ||
773 | } | 777 | } |
774 | 778 | ||
775 | unsigned char ipmi_get_my_address(ipmi_user_t user) | 779 | int ipmi_get_my_address(ipmi_user_t user, |
780 | unsigned int channel, | ||
781 | unsigned char *address) | ||
776 | { | 782 | { |
777 | return user->intf->my_address; | 783 | if (channel >= IPMI_MAX_CHANNELS) |
784 | return -EINVAL; | ||
785 | *address = user->intf->channels[channel].address; | ||
786 | return 0; | ||
778 | } | 787 | } |
779 | 788 | ||
780 | void ipmi_set_my_LUN(ipmi_user_t user, | 789 | int ipmi_set_my_LUN(ipmi_user_t user, |
781 | unsigned char LUN) | 790 | unsigned int channel, |
791 | unsigned char LUN) | ||
782 | { | 792 | { |
783 | user->intf->my_lun = LUN & 0x3; | 793 | if (channel >= IPMI_MAX_CHANNELS) |
794 | return -EINVAL; | ||
795 | user->intf->channels[channel].lun = LUN & 0x3; | ||
796 | return 0; | ||
784 | } | 797 | } |
785 | 798 | ||
786 | unsigned char ipmi_get_my_LUN(ipmi_user_t user) | 799 | int ipmi_get_my_LUN(ipmi_user_t user, |
800 | unsigned int channel, | ||
801 | unsigned char *address) | ||
787 | { | 802 | { |
788 | return user->intf->my_lun; | 803 | if (channel >= IPMI_MAX_CHANNELS) |
804 | return -EINVAL; | ||
805 | *address = user->intf->channels[channel].lun; | ||
806 | return 0; | ||
789 | } | 807 | } |
790 | 808 | ||
791 | int ipmi_set_gets_events(ipmi_user_t user, int val) | 809 | int ipmi_set_gets_events(ipmi_user_t user, int val) |
@@ -1213,7 +1231,7 @@ static inline int i_ipmi_request(ipmi_user_t user, | |||
1213 | unsigned char ipmb_seq; | 1231 | unsigned char ipmb_seq; |
1214 | long seqid; | 1232 | long seqid; |
1215 | 1233 | ||
1216 | if (addr->channel > IPMI_NUM_CHANNELS) { | 1234 | if (addr->channel >= IPMI_NUM_CHANNELS) { |
1217 | spin_lock_irqsave(&intf->counter_lock, flags); | 1235 | spin_lock_irqsave(&intf->counter_lock, flags); |
1218 | intf->sent_invalid_commands++; | 1236 | intf->sent_invalid_commands++; |
1219 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 1237 | spin_unlock_irqrestore(&intf->counter_lock, flags); |
@@ -1346,6 +1364,18 @@ static inline int i_ipmi_request(ipmi_user_t user, | |||
1346 | return rv; | 1364 | return rv; |
1347 | } | 1365 | } |
1348 | 1366 | ||
1367 | static int check_addr(ipmi_smi_t intf, | ||
1368 | struct ipmi_addr *addr, | ||
1369 | unsigned char *saddr, | ||
1370 | unsigned char *lun) | ||
1371 | { | ||
1372 | if (addr->channel >= IPMI_MAX_CHANNELS) | ||
1373 | return -EINVAL; | ||
1374 | *lun = intf->channels[addr->channel].lun; | ||
1375 | *saddr = intf->channels[addr->channel].address; | ||
1376 | return 0; | ||
1377 | } | ||
1378 | |||
1349 | int ipmi_request_settime(ipmi_user_t user, | 1379 | int ipmi_request_settime(ipmi_user_t user, |
1350 | struct ipmi_addr *addr, | 1380 | struct ipmi_addr *addr, |
1351 | long msgid, | 1381 | long msgid, |
@@ -1355,6 +1385,12 @@ int ipmi_request_settime(ipmi_user_t user, | |||
1355 | int retries, | 1385 | int retries, |
1356 | unsigned int retry_time_ms) | 1386 | unsigned int retry_time_ms) |
1357 | { | 1387 | { |
1388 | unsigned char saddr, lun; | ||
1389 | int rv; | ||
1390 | |||
1391 | rv = check_addr(user->intf, addr, &saddr, &lun); | ||
1392 | if (rv) | ||
1393 | return rv; | ||
1358 | return i_ipmi_request(user, | 1394 | return i_ipmi_request(user, |
1359 | user->intf, | 1395 | user->intf, |
1360 | addr, | 1396 | addr, |
@@ -1363,8 +1399,8 @@ int ipmi_request_settime(ipmi_user_t user, | |||
1363 | user_msg_data, | 1399 | user_msg_data, |
1364 | NULL, NULL, | 1400 | NULL, NULL, |
1365 | priority, | 1401 | priority, |
1366 | user->intf->my_address, | 1402 | saddr, |
1367 | user->intf->my_lun, | 1403 | lun, |
1368 | retries, | 1404 | retries, |
1369 | retry_time_ms); | 1405 | retry_time_ms); |
1370 | } | 1406 | } |
@@ -1378,6 +1414,12 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
1378 | struct ipmi_recv_msg *supplied_recv, | 1414 | struct ipmi_recv_msg *supplied_recv, |
1379 | int priority) | 1415 | int priority) |
1380 | { | 1416 | { |
1417 | unsigned char saddr, lun; | ||
1418 | int rv; | ||
1419 | |||
1420 | rv = check_addr(user->intf, addr, &saddr, &lun); | ||
1421 | if (rv) | ||
1422 | return rv; | ||
1381 | return i_ipmi_request(user, | 1423 | return i_ipmi_request(user, |
1382 | user->intf, | 1424 | user->intf, |
1383 | addr, | 1425 | addr, |
@@ -1387,8 +1429,8 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
1387 | supplied_smi, | 1429 | supplied_smi, |
1388 | supplied_recv, | 1430 | supplied_recv, |
1389 | priority, | 1431 | priority, |
1390 | user->intf->my_address, | 1432 | saddr, |
1391 | user->intf->my_lun, | 1433 | lun, |
1392 | -1, 0); | 1434 | -1, 0); |
1393 | } | 1435 | } |
1394 | 1436 | ||
@@ -1397,8 +1439,15 @@ static int ipmb_file_read_proc(char *page, char **start, off_t off, | |||
1397 | { | 1439 | { |
1398 | char *out = (char *) page; | 1440 | char *out = (char *) page; |
1399 | ipmi_smi_t intf = data; | 1441 | ipmi_smi_t intf = data; |
1442 | int i; | ||
1443 | int rv= 0; | ||
1400 | 1444 | ||
1401 | return sprintf(out, "%x\n", intf->my_address); | 1445 | for (i=0; i<IPMI_MAX_CHANNELS; i++) |
1446 | rv += sprintf(out+rv, "%x ", intf->channels[i].address); | ||
1447 | out[rv-1] = '\n'; /* Replace the final space with a newline */ | ||
1448 | out[rv] = '\0'; | ||
1449 | rv++; | ||
1450 | return rv; | ||
1402 | } | 1451 | } |
1403 | 1452 | ||
1404 | static int version_file_read_proc(char *page, char **start, off_t off, | 1453 | static int version_file_read_proc(char *page, char **start, off_t off, |
@@ -1592,8 +1641,8 @@ send_channel_info_cmd(ipmi_smi_t intf, int chan) | |||
1592 | NULL, | 1641 | NULL, |
1593 | NULL, | 1642 | NULL, |
1594 | 0, | 1643 | 0, |
1595 | intf->my_address, | 1644 | intf->channels[0].address, |
1596 | intf->my_lun, | 1645 | intf->channels[0].lun, |
1597 | -1, 0); | 1646 | -1, 0); |
1598 | } | 1647 | } |
1599 | 1648 | ||
@@ -1696,11 +1745,13 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
1696 | new_intf->intf_num = i; | 1745 | new_intf->intf_num = i; |
1697 | new_intf->version_major = version_major; | 1746 | new_intf->version_major = version_major; |
1698 | new_intf->version_minor = version_minor; | 1747 | new_intf->version_minor = version_minor; |
1699 | if (slave_addr == 0) | 1748 | for (j=0; j<IPMI_MAX_CHANNELS; j++) { |
1700 | new_intf->my_address = IPMI_BMC_SLAVE_ADDR; | 1749 | new_intf->channels[j].address |
1701 | else | 1750 | = IPMI_BMC_SLAVE_ADDR; |
1702 | new_intf->my_address = slave_addr; | 1751 | new_intf->channels[j].lun = 2; |
1703 | new_intf->my_lun = 2; /* the SMS LUN. */ | 1752 | } |
1753 | if (slave_addr != 0) | ||
1754 | new_intf->channels[0].address = slave_addr; | ||
1704 | rwlock_init(&(new_intf->users_lock)); | 1755 | rwlock_init(&(new_intf->users_lock)); |
1705 | INIT_LIST_HEAD(&(new_intf->users)); | 1756 | INIT_LIST_HEAD(&(new_intf->users)); |
1706 | new_intf->handlers = handlers; | 1757 | new_intf->handlers = handlers; |
@@ -1985,7 +2036,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
1985 | msg->data[3] = msg->rsp[6]; | 2036 | msg->data[3] = msg->rsp[6]; |
1986 | msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3); | 2037 | msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3); |
1987 | msg->data[5] = ipmb_checksum(&(msg->data[3]), 2); | 2038 | msg->data[5] = ipmb_checksum(&(msg->data[3]), 2); |
1988 | msg->data[6] = intf->my_address; | 2039 | msg->data[6] = intf->channels[msg->rsp[3] & 0xf].address; |
1989 | /* rqseq/lun */ | 2040 | /* rqseq/lun */ |
1990 | msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3); | 2041 | msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3); |
1991 | msg->data[8] = msg->rsp[8]; /* cmd */ | 2042 | msg->data[8] = msg->rsp[8]; /* cmd */ |
@@ -2919,8 +2970,8 @@ static void send_panic_events(char *str) | |||
2919 | &smi_msg, | 2970 | &smi_msg, |
2920 | &recv_msg, | 2971 | &recv_msg, |
2921 | 0, | 2972 | 0, |
2922 | intf->my_address, | 2973 | intf->channels[0].address, |
2923 | intf->my_lun, | 2974 | intf->channels[0].lun, |
2924 | 0, 1); /* Don't retry, and don't wait. */ | 2975 | 0, 1); /* Don't retry, and don't wait. */ |
2925 | } | 2976 | } |
2926 | 2977 | ||
@@ -2965,8 +3016,8 @@ static void send_panic_events(char *str) | |||
2965 | &smi_msg, | 3016 | &smi_msg, |
2966 | &recv_msg, | 3017 | &recv_msg, |
2967 | 0, | 3018 | 0, |
2968 | intf->my_address, | 3019 | intf->channels[0].address, |
2969 | intf->my_lun, | 3020 | intf->channels[0].lun, |
2970 | 0, 1); /* Don't retry, and don't wait. */ | 3021 | 0, 1); /* Don't retry, and don't wait. */ |
2971 | 3022 | ||
2972 | if (intf->local_event_generator) { | 3023 | if (intf->local_event_generator) { |
@@ -2985,8 +3036,8 @@ static void send_panic_events(char *str) | |||
2985 | &smi_msg, | 3036 | &smi_msg, |
2986 | &recv_msg, | 3037 | &recv_msg, |
2987 | 0, | 3038 | 0, |
2988 | intf->my_address, | 3039 | intf->channels[0].address, |
2989 | intf->my_lun, | 3040 | intf->channels[0].lun, |
2990 | 0, 1); /* no retry, and no wait. */ | 3041 | 0, 1); /* no retry, and no wait. */ |
2991 | } | 3042 | } |
2992 | intf->null_user_handler = NULL; | 3043 | intf->null_user_handler = NULL; |
@@ -2996,7 +3047,7 @@ static void send_panic_events(char *str) | |||
2996 | be zero, and it must not be my address. */ | 3047 | be zero, and it must not be my address. */ |
2997 | if (((intf->event_receiver & 1) == 0) | 3048 | if (((intf->event_receiver & 1) == 0) |
2998 | && (intf->event_receiver != 0) | 3049 | && (intf->event_receiver != 0) |
2999 | && (intf->event_receiver != intf->my_address)) | 3050 | && (intf->event_receiver != intf->channels[0].address)) |
3000 | { | 3051 | { |
3001 | /* The event receiver is valid, send an IPMB | 3052 | /* The event receiver is valid, send an IPMB |
3002 | message. */ | 3053 | message. */ |
@@ -3031,7 +3082,7 @@ static void send_panic_events(char *str) | |||
3031 | data[0] = 0; | 3082 | data[0] = 0; |
3032 | data[1] = 0; | 3083 | data[1] = 0; |
3033 | data[2] = 0xf0; /* OEM event without timestamp. */ | 3084 | data[2] = 0xf0; /* OEM event without timestamp. */ |
3034 | data[3] = intf->my_address; | 3085 | data[3] = intf->channels[0].address; |
3035 | data[4] = j++; /* sequence # */ | 3086 | data[4] = j++; /* sequence # */ |
3036 | /* Always give 11 bytes, so strncpy will fill | 3087 | /* Always give 11 bytes, so strncpy will fill |
3037 | it with zeroes for me. */ | 3088 | it with zeroes for me. */ |
@@ -3047,8 +3098,8 @@ static void send_panic_events(char *str) | |||
3047 | &smi_msg, | 3098 | &smi_msg, |
3048 | &recv_msg, | 3099 | &recv_msg, |
3049 | 0, | 3100 | 0, |
3050 | intf->my_address, | 3101 | intf->channels[0].address, |
3051 | intf->my_lun, | 3102 | intf->channels[0].lun, |
3052 | 0, 1); /* no retry, and no wait. */ | 3103 | 0, 1); /* no retry, and no wait. */ |
3053 | } | 3104 | } |
3054 | } | 3105 | } |
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h index 596ca6130159..846b69899776 100644 --- a/include/linux/ipmi.h +++ b/include/linux/ipmi.h | |||
@@ -298,13 +298,19 @@ void ipmi_get_version(ipmi_user_t user, | |||
298 | this user, so it will affect all users of this interface. This is | 298 | this user, so it will affect all users of this interface. This is |
299 | so some initialization code can come in and do the OEM-specific | 299 | so some initialization code can come in and do the OEM-specific |
300 | things it takes to determine your address (if not the BMC) and set | 300 | things it takes to determine your address (if not the BMC) and set |
301 | it for everyone else. */ | 301 | it for everyone else. Note that each channel can have its own address. */ |
302 | void ipmi_set_my_address(ipmi_user_t user, | 302 | int ipmi_set_my_address(ipmi_user_t user, |
303 | unsigned char address); | 303 | unsigned int channel, |
304 | unsigned char ipmi_get_my_address(ipmi_user_t user); | 304 | unsigned char address); |
305 | void ipmi_set_my_LUN(ipmi_user_t user, | 305 | int ipmi_get_my_address(ipmi_user_t user, |
306 | unsigned char LUN); | 306 | unsigned int channel, |
307 | unsigned char ipmi_get_my_LUN(ipmi_user_t user); | 307 | unsigned char *address); |
308 | int ipmi_set_my_LUN(ipmi_user_t user, | ||
309 | unsigned int channel, | ||
310 | unsigned char LUN); | ||
311 | int ipmi_get_my_LUN(ipmi_user_t user, | ||
312 | unsigned int channel, | ||
313 | unsigned char *LUN); | ||
308 | 314 | ||
309 | /* | 315 | /* |
310 | * Like ipmi_request, but lets you specify the number of retries and | 316 | * Like ipmi_request, but lets you specify the number of retries and |
@@ -585,6 +591,16 @@ struct ipmi_cmdspec | |||
585 | * things it takes to determine your address (if not the BMC) and set | 591 | * things it takes to determine your address (if not the BMC) and set |
586 | * it for everyone else. You should probably leave the LUN alone. | 592 | * it for everyone else. You should probably leave the LUN alone. |
587 | */ | 593 | */ |
594 | struct ipmi_channel_lun_address_set | ||
595 | { | ||
596 | unsigned short channel; | ||
597 | unsigned char value; | ||
598 | }; | ||
599 | #define IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 24, struct ipmi_channel_lun_address_set) | ||
600 | #define IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 25, struct ipmi_channel_lun_address_set) | ||
601 | #define IPMICTL_SET_MY_CHANNEL_LUN_CMD _IOR(IPMI_IOC_MAGIC, 26, struct ipmi_channel_lun_address_set) | ||
602 | #define IPMICTL_GET_MY_CHANNEL_LUN_CMD _IOR(IPMI_IOC_MAGIC, 27, struct ipmi_channel_lun_address_set) | ||
603 | /* Legacy interfaces, these only set IPMB 0. */ | ||
588 | #define IPMICTL_SET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 17, unsigned int) | 604 | #define IPMICTL_SET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 17, unsigned int) |
589 | #define IPMICTL_GET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 18, unsigned int) | 605 | #define IPMICTL_GET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 18, unsigned int) |
590 | #define IPMICTL_SET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 19, unsigned int) | 606 | #define IPMICTL_SET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 19, unsigned int) |