ibmasm-utils-3.0/0000755000175000017500000000000010251437017012736 5ustar chuckchuckibmasm-utils-3.0/src/0000755000175000017500000000000010251444421013522 5ustar chuckchuckibmasm-utils-3.0/src/README0000644000175000017500000002321410251444421014404 0ustar chuckchuck IBM Advanced System Management Driver for Linux version 3.0 CONTENTS -------- 1.0 Overview 2.0 Change History 3.0 Installation and Setup Instructions 4.0 Configuration Information 5.0 Web Sites and Support Phone Number 6.0 Trademarks and Notices 7.0 Disclaimer 1.0 Overview ------------- This README.TXT file is associated with the following RPM file: - ibmasm-3.0.-x.i586.rpm (where x indicates the revision number of the package.) This RPM file will build Linux device drivers for the following IBM hardware: - Remote Supervisor Adapter, which is an option on specific models of xSeries servers (Remote Mouse / Keyboard available if the Adapter firmware supports those functions) The RPM only supports SUSE Linux Enterprise Server, version 9 (SLES9). The Linux kernel version used with this driver must 2.6.5 or greater. 2.0 Change History ------------------- 2.1 Driver version 3.0 - The driver code has been redesigned for the 2.6 Linux kernel. - Fixed incorrect file permissions (Defect #254653) - The DeregisterForEvents function now works correctly (Defect #254897) - The API shared library now also works correctly when the primary service processor is not on PCI bus 0 (Defect #258791) - IBM Director can now open the driver (Defect 260776f_1) - Redesigned remote control support in the driver. The ibmasm driver now directly forwards remote mouse and keyboard events to the kernel's input subsystem. They are then picked up by an X input driver. 3.0 Installation and Setup Instructions -------------------------------------------------------------- 3.1 Installing the driver The driver is installed with the following command: (1) rpm -ivh ibmasm-3.0.-x.i586.rpm Note that the driver must not installed in run level 5 when X is running. You may have to use: init 3 rpm -ivh ibmasm-3.0.-x.i586.rpm init 5 3.2 Removing the driver The command rpm -e ibmasm will remove the ibmasm driver and the associated user space utilities from the system. 3.3 Utilities provided the ibmasm package Upon installation the command rpm -ql ibmasm will list the installed components of the ibmasm package. These are: (1) the service processor API shared object /lib/libsysSp.so (2) the ibmsphalt executable that allows a clean OS shutdown intiated by the service processor. It executes /sbin/halt when it receives a poweroff event from the service processor. /sbin/ibmsphalt (3) X input driver that facilitates the remote video redirection. /usr/X11R6/lib/modules/input/ibmasm_drv.o (4) start and stop utilities /etc/init.d/ibmasm /sbin/ibmspdown /sbin/ibmspup /usr/sbin/rcibmasm (5) this README file /usr/share/doc/packages/ibmasm/README (6) the mount point for the ibmasmfs file system /var/lib/ibmasm 4.0 Configuration Information ------------------------------ 4.1 Manually starting and stopping the ibmasm utilities The command /etc/init.d/ibmasm/start will start the ibmasm utilities. This command cannot be executed when X is running (run level 5). /etc/init.d/ibmasm/stop will stop them. When started - the ibmasm module is loaded - the ibmasmfs filesytem is mounted on /var/lib/ibmasm - the ibmsphalt and ibmspremote commands are running Note: After loading the driver you may notice a message: "ibmasm: unsupported module, tainting kernel" in the /var/log/messages file. This message can be ignored. Note: the ibmasmfs filesystem is for internal use with the Service Processor API shared library and ibmspremote command. It is not necessary to access it directly nor need its details be known. 4.2 Automatically starting and stopping the ibmasm utilities Upon installation the ibmasm utilities are started and configured to be started in run levels 3 and 5, and stopped in all other run levels. To change this configuration standard Linux commands such as chkconfig(8) or insserv(8) can be used (insserv is a SUSE specific commmand). 4.3 Configuring the serial line support The ibmasm module contains support for the UART on the service processor board, i.e. it allows the Linux OS to make use of the UART as a serial line. This feature requires the UART on the service processor board to be dedicated to the OS before the ibmasm driver is loaded. If the driver is loaded when the UART is not dedicated to the OS it will not be able to detect a possible later change in UART ownership and will not be able to make use of the UART. The ibmasm driver dynamically registers a serial line in the kernel's tty subsystem. The serial line number can be read from the /var/log/messages log or from the dmesg(8) command. You will see a set of messages like: ibmasm 0000:01:07.0: IBM SP UART not registered, owned by service proc. ibmasm: IBM ASM Service Processor Driver version 1.0 loaded or: ttyS14 at MMIO 0x0 (irq = 18) is a 16550A ibmasm: IBM ASM Service Processor Driver version 1.0 loaded The numbers appearing are examples and will vary. In the former case the UART is not dedicated to the OS and no serial support is registered. In the latter case the ibmasm registers ttyS14 which can be accessed as /dev/ttyS14 from user programs (such as getty). The specific number depends in the sytem, but it will be same every time the driver is loaded as long as the system configuration doesn't change. Note: The service processor may retake ownership of the UART under certain circumstances, e.g. for dialout. In that case the OS using the UART may interfere with the service processor's use of the UART. 4.4 Notes on Remote Control This driver supports remote server screen redirection via VNC window in service processor's web interface. A few limitations apply: - 24 bit color depth is not supported. Note that this may be the default on some installations, therefore care needs to be taken to set this value to 8, 16 or 32 bits if remote control is to be used. - Only framebuffer mode is supported for the text console. To turn on framebuffer mode specify vga=, e.g. vga=791 as a kernel boot parameter. can be one of the following: Color depth | 640x480 800x600 1024x768 1280x1024 256 (8bit)| 769 771 773 775 32000 (15bit)| 784 787 790 793 65000 (16bit)| 785 788 791 794 The codes below are not supported since they have 24 bit color depth. 16.7 Mill.(24bit)| 786 789 792 795 - The VNC client may not always be able to handle screen resolution changes. In these cases closing the remote control window and restarting it will remedy the situation. - You may experience repeated characters when none are desired. These are caused by a lag in transmission of key events from the VNC client to the server. A workaround is to disable key repeat in the KDE: * use the KDE Control Center * open Peripherals * select Keyboard * uncheck "Keyboard repeat" 5.0 WEB Sites and Support Phone Number --------------------------------------- 5.1 IBM Support Web Site: http://www.pc.ibm.com/support 5.2 IBM Marketing eServer xSeries Web Site: http://www.pc.ibm.com/us/eserver/xseries 5.3 If you have any questions about this update, or problems applying the update go to the following Help Center World Telephone Numbers URL: http://www.pc.ibm.com/qtechinfo/YAST-3P2QYL.html 6.0 Trademarks and Notices --------------------------- The following terms are trademarks of Novell, Inc. in the United States or other countries or both: SUSE The following terms are trademarks of Linus Torvalds in the United States or other countries or both: Linux 7.0 Disclaimer --------------- 7.1 THIS DOCUMENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IBM DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY WITH RESPECT TO THE INFORMATION IN THIS DOCUMENT. BY FURNISHING THIS DOCUMENT, IBM GRANTS NO LICENSES TO ANY PATENTS OR COPYRIGHTS. 7.2 Note to Government Users Documentation related to restricted rights -- Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corporation. ibmasm-utils-3.0/src/xinput/0000755000175000017500000000000010251441305015047 5ustar chuckchuckibmasm-utils-3.0/src/xinput/ibmasm.c0000600000175000017500000001770610251441305016466 0ustar chuckchuck/* * Copyright 2005 IBM * Authors: * Vernon Mauery */ /* Input device for the IBM ASM (RSA I Service Processor) */ #include #define NEED_XF86_TYPES #include #include #include #include #ifdef XFree86LOADER #include #endif #define IBMASM_DEBUG #ifdef IBMASM_DEBUG #define ibmasm_debug(level, ...) xf86ErrorFVerb(level, __VA_ARGS__) #else #define ibmasm_debug(level, ...) #endif /* we can get the 'struct input_event' from standard linux include files, * but I don't think we can use those here... * plus, we don't really care about the timestamp, * so we can define our own simple version */ struct input_event { struct { long _sec; long _usec; } _unused; unsigned short type; unsigned short code; int value; }; /* Event types */ #define EV_SYN 0x00 #define EV_KEY 0x01 #define EV_REL 0x02 #define EV_ABS 0x03 /* Event Codes */ #define ABS_X 0x00 #define ABS_Y 0x01 #define BTN_LEFT 0x110 #define BTN_RIGHT 0x111 #define BTN_MIDDLE 0x112 typedef struct { int x, y; int new_x, new_y; int button_code; int button_value; int swap_x, swap_y; LocalDevicePtr local; } ibmasm_info; static const char *default_options[] = { NULL }; static LocalDevicePtr ibmasm_driver_setup(InputDriverPtr drv, IDevPtr dev, int flags); static void ibmasm_driver_cleanup(InputDriverPtr drv, LocalDevicePtr local, int flags); InputDriverRec IBMASM = { /* .driverVersion = */ 1, /* .driverName = */ "ibmasm", /* .Identify = */ NULL, /* .PreInit = */ ibmasm_driver_setup, /* .UnInit = */ ibmasm_driver_cleanup, /* .module = */ NULL, /* .refCount = */ 0, }; #ifdef XFree86LOADER ModuleInfoRec ibmasm_module_info = { /* .moduleVersion = */ 1, /* .moduleName = */ "IBMASM", /* .module = */ NULL, /* .refCount = */ 0, /* .AvailableOptions = */ NULL, }; static XF86ModuleVersionInfo VersionRec = { "ibmasm", "Vernon Mauery ", MODINFOSTRING1, MODINFOSTRING2, XF86_VERSION_CURRENT, 0, 6, 1, ABI_CLASS_XINPUT, ABI_XINPUT_VERSION, MOD_CLASS_XINPUT, {0, 0, 0, 0} }; static pointer plug(pointer module, pointer options, int *error_major, int *error_minor) { ibmasm_debug(1,"enter %s:%d\n", __FUNCTION__, __LINE__); xf86AddModuleInfo(&ibmasm_module_info, module); xf86AddInputDriver(&IBMASM, module, 0); ibmasm_debug(1,"leave %s:%d\n", __FUNCTION__, __LINE__); return module; } static void unplug(pointer p) { ibmasm_debug(1,"%s:%d\n", __FUNCTION__, __LINE__); } XF86ModuleData ibmasmModuleData = {&VersionRec, plug, unplug }; #endif /* XFree86LOADER */ static Bool ibmasm_conversion(LocalDevicePtr local, int first, int num, int v0, int v1, int v2, int v3, int v4, int v5, int *x, int *y) { ibmasm_info *private; int width = screenInfo.screens[0]->width; int height = screenInfo.screens[0]->height; if (first != 0 || num == 1) return FALSE; private = (ibmasm_info*)local->private; *x = v0; *y = v1; if (*x < 0) *x = 0; if (*y < 0) *y = 0; if (*x > width-1) *x = width-1; if (*y > height-1) *y = height-1; /* now that we are in bounds, we can do a swap if needed */ if (private->swap_x) *x = width - 1 - *x; if (private->swap_y) *y = height - 1 - *y; ibmasm_debug(1,"%s: (%d, %d) -> (%d, %d)\n", __FUNCTION__, v0, v1, *x, *y); return TRUE; } static void ibmasm_read_input(LocalDevicePtr local) { struct input_event event; ibmasm_info *private = (ibmasm_info *)local->private; ibmasm_debug(1, "enter %s:%d\n", __FUNCTION__, __LINE__); xf86memset(&event, 0, sizeof(struct input_event)); while (xf86ReadSerial(local->fd, &event, sizeof(struct input_event)) == sizeof(struct input_event)) { switch (event.type) { case EV_ABS: ibmasm_debug(1, "abs event: %s = %d\n", (event.code == ABS_X ? "ABS_X":"ABS_Y"), event.value); switch (event.code) { case ABS_X: private->new_x = event.value; break; case ABS_Y: private->new_y = event.value; break; } break; case EV_KEY: ibmasm_debug(1, "key event: %d %s\n", event.code, (event.value ? "pressed":"released")); private->button_code = event.code; private->button_value = event.value; break; case EV_SYN: /* do something with the data we have */ ibmasm_debug(1, "sync event\n"); private->x = private->new_x; private->y = private->new_y; ibmasm_debug(1, "xf86PostMotionEvent(local->dev = 0x%x, TRUE, 0, 2, %d, %d);\n", (int)local->dev, private->x, private->y); xf86PostMotionEvent(local->dev, TRUE, 0, 2, private->x, private->y); if (private->button_code) { xf86PostButtonEvent(local->dev, TRUE, private->button_code, private->button_value, 0, 2, private->x, private->y); private->button_code = 0; } break; } xf86memset(&event, 0, sizeof(struct input_event)); } ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); } static Bool ibmasm_device_control(DeviceIntPtr dev, int what) { Bool ret = BadValue; LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); switch (what) { case DEVICE_ON: ibmasm_debug(1, "%s:%d -- DEVICE_ON\n", __FUNCTION__, __LINE__); ret = Success; local->fd = xf86OpenSerial(local->options); if (local->fd < 0) { ret = !Success; break; } xf86FlushInput(local->fd); xf86AddEnabledDevice(local); break; case DEVICE_INIT: ibmasm_debug(1, "%s:%d -- DEVICE_INIT\n", __FUNCTION__, __LINE__); { unsigned char map[] = {0, 1, 2, 3}; if (!InitButtonClassDeviceStruct(dev, 3, map)) { ErrorF("ibmasm: failed to initialize ButtonClassDeviceStruct\n"); return !Success; } if (!InitFocusClassDeviceStruct(dev)) { ErrorF("ibmasm: failed to initialize FocusClassDeviceStruct\n"); return !Success; } if (!InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents, local->history_size, Absolute)) { ErrorF ("ibmasm: failed to initialize ValuatorClassDeviceStruct\n"); return !Success; } xf86MotionHistoryAllocate (local); InitValuatorAxisStruct (dev, 0, 0, 1600, 1, 1, 1); InitValuatorAxisStruct (dev, 1, 0, 1200, 1, 1, 1); } ret = Success; break; case DEVICE_OFF: case DEVICE_CLOSE: ibmasm_debug(1, "%s:%d -- DEVICE_OFF\n", __FUNCTION__, __LINE__); xf86RemoveEnabledDevice(local); xf86CloseSerial(local->fd); ret = Success; break; } ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); return ret; } static LocalDevicePtr ibmasm_driver_setup(InputDriverPtr drv, IDevPtr dev, int flags) { LocalDevicePtr local; ibmasm_info *priv; ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); priv = xcalloc(1, sizeof(ibmasm_info)); if (!priv) return NULL; local = xf86AllocateInput(drv, flags); if (!local) { xfree(priv); return NULL; } priv->local = local; local->name = dev->identifier; local->device_control = ibmasm_device_control; local->read_input = ibmasm_read_input; local->control_proc = NULL; local->close_proc = NULL; local->conversion_proc = ibmasm_conversion; local->reverse_conversion_proc = NULL; local->switch_mode = NULL; local->flags = XI86_POINTER_CAPABLE; local->fd = -1; local->private = priv; local->private_flags = 0; local->history_size = 0; local->type_name = XI_TOUCHSCREEN; local->conf_idev = dev; local->dev = NULL; xf86CollectInputOptions(local, default_options, NULL); xf86OptionListReport(local->options); priv->swap_y = xf86SetBoolOption(local->options, "SwapY", FALSE); priv->swap_x = xf86SetBoolOption(local->options, "SwapX", FALSE); xf86ProcessCommonOptions(local, local->options); local->flags |= XI86_CONFIGURED; ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); return local; } static void ibmasm_driver_cleanup(InputDriverPtr drv, LocalDevicePtr local, int flags) { ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); if (local->private) xfree(local->private); xf86DeleteInput(local, flags); ibmasm_debug(1, "%s:%d\n", __FUNCTION__, __LINE__); } ibmasm-utils-3.0/src/api/0000755000175000017500000000000010251440601014267 5ustar chuckchuckibmasm-utils-3.0/src/api/libibmasm.h0000644000175000017500000000403610017215655016413 0ustar chuckchuck /* * This software may be used and distributed according to the terms * of the Lesser GNU Public License, incorporated herein by reference * * Copyright (C) IBM Corporation, 2004 * * Author: Max Asböck */ #ifndef __ibmasm_h__ #define __ibmasm_h__ #define RC_SUCCESS 0 #define RC_INVALID_HANDLE 1 #define RC_TIMEOUT 2 #define RC_NOT_OPEN 3 #define RC_OPEN_FAILED 4 #define RC_CLOSE_FAILED 5 #define RC_ALREADY_REGISTERED 6 #define RC_EVENT_NOT_REGISTERED 7 #define RC_SYSTEM_ERROR 8 #define RC_INVALID_BUFFER 9 #define RC_EVENT_CANCELLED 10 #define RC_DRIVER_CLOSED 11 #define RC_NO_EVENT_BFRS 13 #define RC_ALREADY_OPEN 14 #define RC_REVERSE_HB_ALREADY_REGISTERED 15 #define RC_REVERSE_HEARTBEAT_HAS_FAILED 17 #define RC_REVERSE_HB_ALREADY_STOPPED 18 /* dot command types */ #define dotcmd_write 0 #define dotcmd_write_next 1 #define dotcmd_read 2 #define dotcmd_read_next 3 #define dotcmd_command_response 4 #define dotcmd_event 5 #define dotcmd_heartbeat 6 /* dot command header */ #pragma pack(1) struct dot_command { unsigned char type; unsigned char command_size; unsigned short data_size; unsigned char status; unsigned char reserved; }; #pragma pack() extern unsigned int OpenSPDriverNode(int *handle, unsigned int io_buffer_length, unsigned int node, unsigned int *num, unsigned long reserved); extern unsigned int OpenSPDriver(int *handle, unsigned int io_buffer_length, unsigned long reserved); extern unsigned int CloseSPDriver(int handle, unsigned long reserved); extern unsigned int SystemDataIO(int handle, void *command, unsigned long reserved); extern unsigned int RegisterForEvents(int handle, void *buffer, short ignore_count, unsigned char **ignore_list, unsigned long reserved); extern unsigned int DeregisterForEvents(int handle, unsigned long reserved); extern unsigned int RegisterForReverseHB(int handle, unsigned long reserved); extern unsigned int DeRegisterForReverseHB(int handle, unsigned long reserved); #endif /* __ibmasm_h__ */ ibmasm-utils-3.0/src/api/rsa.h0000644000175000017500000000102410251425604015230 0ustar chuckchuck /* * This software may be used and distributed according to the terms * of the Lesser GNU Public License, incorporated herein by reference * * Copyright (C) IBM Corporation, 2004 * * Author: Max Asböck */ #ifndef __ibmrsa_h__ #define __ibmrsa_h__ /* File names provided by the ibmasmfs file system */ #define RSA_NAME_SIZE 1024 #define RSA_COMMAND "command" #define RSA_EVENT "event" #define RSA_HEARTBEAT "reverse_heartbeat" #define IBMASM_EVENT_MAX_SIZE 2048u #endif /* __ibmrsa_h__ */ ibmasm-utils-3.0/src/api/libibmasm.c0000644000175000017500000002251210251425604016402 0ustar chuckchuck /* * This software may be used and distributed according to the terms * of the Lesser GNU Public License, incorporated herein by reference * * Copyright (C) IBM Corporation, 2004 * * Author: Max Asböck */ #include #include #include #include #include #include #include #include #include #include #include "libibmasm.h" #include "rsa.h" struct spnode { unsigned int opened; int event_fd; int heartbeat_fd; unsigned int io_buffer_length; char command_path[RSA_NAME_SIZE]; char event_path[RSA_NAME_SIZE]; char heartbeat_path[RSA_NAME_SIZE]; }; #define MAX_SP_NODES 16 static struct spnode *node_array[MAX_SP_NODES]; static unsigned int num_nodes = 0; static int api_initialized = 0; #define HANDLE_ADD 1 // handles must not be 0, so we always add 1 #define handle2node(h) h - HANDLE_ADD #define node2handle(n) n + HANDLE_ADD static inline struct spnode *get_spnode(int node) { if (node < 0 || node >= num_nodes) return NULL; return node_array[node]; } #define get_spnode_from_handle(h) get_spnode(handle2node(h)) static int get_ibmasmfs_mount_point(char *mount_point) { FILE *f; char line[RSA_NAME_SIZE]; char *first, *mount, *type; f = fopen("/proc/mounts", "r"); if (f == NULL) return 1; while(fgets(line, 1024, f)) { first = strtok(line, " "); mount = strtok(NULL, " "); type = strtok(NULL, " "); if (!strcmp(type, "ibmasmfs")) { strncpy(mount_point, mount, RSA_NAME_SIZE - 1); fclose(f); return 0; } } fclose(f); return 1; } static unsigned int api_init() { DIR *dir; struct dirent *dirent; char mount_point[RSA_NAME_SIZE]; struct spnode *nodes[MAX_SP_NODES]; int n = 0; int i; // find out where ibmasmfs is mounted if (get_ibmasmfs_mount_point(mount_point) != 0) return 1; dir = opendir(mount_point); if (dir == NULL) return 1; // the ibmasmfs root directory contains a directory // entry for each service processor. Look them up // and allocate a data structure to save away // path names and state information for each service // processor node. while ((dirent = readdir(dir))) { struct spnode *node; if (!strcmp(dirent->d_name, ".")) continue; if (!strcmp(dirent->d_name, "..")) continue; // allocate memory: if we fail on one node // back out completely node = malloc(sizeof(struct spnode)); if (node == NULL) { for (i=0; icommand_path, RSA_NAME_SIZE, "%s/%s/%s", mount_point, dirent->d_name, RSA_COMMAND); snprintf(node->event_path, RSA_NAME_SIZE, "%s/%s/%s", mount_point, dirent->d_name, RSA_EVENT); snprintf(node->heartbeat_path, RSA_NAME_SIZE, "%s/%s/%s", mount_point, dirent->d_name, RSA_HEARTBEAT); node->opened = 0; nodes[n] = node; n++; if (n >= MAX_SP_NODES) break; } closedir(dir); // we didn't find any nodes or malloc failed if (n == 0) return 1; // we found at least one service processor node. // initialize the global node array and node number for (i=0; i 32)) return RC_INVALID_BUFFER; if (!api_initialized) { api_initialized = 1; if (api_init() == 1) { api_initialized = 0; return RC_SYSTEM_ERROR; } } if (num != NULL) *num = num_nodes; if (handle == NULL) return RC_SUCCESS; spnode = get_spnode(node); if (spnode == NULL) return RC_OPEN_FAILED; if (spnode->opened) return RC_ALREADY_OPEN; spnode->event_fd = open(spnode->event_path, O_RDWR); if (spnode->event_fd < 0) goto event_open_failed; spnode->heartbeat_fd = open(spnode->heartbeat_path, O_RDWR); if (spnode->heartbeat_fd < 0) goto heartbeat_open_failed; spnode->io_buffer_length = io_buffer_length * 1024; spnode->opened = 1; *handle = node2handle(node); return RC_SUCCESS; heartbeat_open_failed: close(spnode->event_fd); event_open_failed: return RC_OPEN_FAILED; } /** * OpenSPDriver * for backwards compatibility */ unsigned int OpenSPDriver(int *handle, unsigned int io_buffer_length, unsigned long reserved) { return OpenSPDriverNode(handle, io_buffer_length, 0, NULL, reserved); } static void io_cancel(int fd) { char c = 0; write(fd, &c, 1); } /** * CloseSPDriver * must be called when an application closes. * * Return values: * RC_INVALID_HANDLE * RC_ALREADY_CLOSED * RC_SUCCESS */ unsigned int CloseSPDriver(int handle, unsigned long reserved) { struct spnode *node; node = get_spnode_from_handle(handle); if (node == NULL || !node->opened) return RC_INVALID_HANDLE; node->opened = 0; io_cancel(node->event_fd); io_cancel(node->heartbeat_fd); close(node->event_fd); close(node->heartbeat_fd); return RC_SUCCESS; } static int send_command(struct spnode *node, void *command) { int fd; int len = node->io_buffer_length; int result; fd = open(node->command_path, O_RDWR); if (fd < 0) return RC_SYSTEM_ERROR; result = write(fd, command, len); if (result <= 0) { close(fd); return RC_SYSTEM_ERROR; } result = read(fd, command, len); if (result <= 0) { close(fd); return RC_SYSTEM_ERROR; } close(fd); return 0; } /** * SystemDataIO * Send a command to the service processor * * Return values: * RC_INVALID_HANDLE * RC_INVALID_BUFFER * RC_SYSTEM_ERROR * RC_TIMEOUT */ unsigned int SystemDataIO(int handle, void *command, unsigned long reserved) { struct dot_command *dot_command = (struct dot_command *)command; struct spnode *node = get_spnode_from_handle(handle); if (node == NULL || !node->opened) return RC_INVALID_HANDLE; if (command == NULL) return RC_INVALID_BUFFER; switch(dot_command->type) { case dotcmd_write: case dotcmd_write_next: case dotcmd_read: case dotcmd_read_next: return send_command(node, command); default: dot_command->type = dotcmd_command_response; return RC_SUCCESS; } } static int wait_for_event(struct spnode *node, void *buffer) { int ret; unsigned int size; if (node->io_buffer_length > IBMASM_EVENT_MAX_SIZE) size = IBMASM_EVENT_MAX_SIZE; else size = node->io_buffer_length; ret = read(node->event_fd, buffer, size); if (ret == 0) return RC_EVENT_CANCELLED; else if (ret < 0) { switch(errno) { case EBUSY: return RC_ALREADY_REGISTERED; case EINTR: return RC_SUCCESS; default: return RC_SYSTEM_ERROR; } } return RC_SUCCESS; } static int event_ignored(void *buffer, unsigned char **ignore_list, short ignore_count) { int i; char *event = (char *)buffer + sizeof(struct dot_command); int size = ((struct dot_command *)buffer)->command_size; for (i=0; iopened) return RC_INVALID_HANDLE; if (buffer == NULL) return RC_INVALID_BUFFER; if (ignore_count && ignore_list == NULL) return RC_INVALID_BUFFER; for(i=0; iopened) return RC_INVALID_HANDLE; io_cancel(node->event_fd); return RC_SUCCESS; } unsigned int RegisterForReverseHB(int handle, unsigned long reserved) { struct spnode *node = get_spnode_from_handle(handle); unsigned char c = 0; int ret; if (node == NULL || !node->opened) return RC_INVALID_HANDLE; ret = read(node->heartbeat_fd, &c, 1); if (ret == 1) return RC_REVERSE_HEARTBEAT_HAS_FAILED; switch(errno) { case EBUSY: return RC_REVERSE_HB_ALREADY_REGISTERED; case EINTR: return RC_SUCCESS; default: return RC_SYSTEM_ERROR; } } unsigned int DeRegisterForReverseHB(int handle, unsigned long reserved) { struct spnode *node = get_spnode_from_handle(handle); if (node == NULL || !node->opened) return RC_INVALID_HANDLE; io_cancel(node->heartbeat_fd); return RC_SUCCESS; } ibmasm-utils-3.0/src/api/Makefile0000644000175000017500000000046610104243354015740 0ustar chuckchuck api_object = libibmasm.o api_lib = libsysSp.so CFLAGS = -g -Wall -fPIC all: $(api_lib) install: install -d $(ROOT)/$(_LIB) install $(api_lib) $(ROOT)/$(_LIB) $(api_lib): $(api_object) $(LD) -shared -soname,libsysSp.so -o $@ $(api_object) clean: rm -f $(api_object) clobber: clean rm -f $(api_lib) ibmasm-utils-3.0/src/bin/0000755000175000017500000000000010017160170014266 5ustar chuckchuckibmasm-utils-3.0/src/bin/halt/0000755000175000017500000000000010017215716015225 5ustar chuckchuckibmasm-utils-3.0/src/bin/halt/ibmsphalt.c0000644000175000017500000001062310017215716017356 0ustar chuckchuck /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) IBM Corporation, 2004 * * Author: Max Asböck * */ // ibmsphalt.c // Register for event notification with RSA service processor driver. // If a poweroff event is received issue the /sbin/halt command to // shutdown the OS before the service processor powers down the system. #include #include #define N_IGNORE 13 static unsigned char *ignore[N_IGNORE] = { "\x5\x2\x1", "\x5\x2\x2", "\x5\x2\x3", // ignore all events but 5.2.4, i.e. poweroff event "\x5\x2\x5", "\x5\x2\x6", "\x5\x2\x7", "\x5\x2\x8", "\x5\x2\x9", "\x5\x2\xa", "\x5\x2\xb", "\x5\x2\xc", "\x5\x2\xd", "\x5\x2\xe", }; #define BUF_LENGTH 1 static char buffer[BUF_LENGTH * 1024]; // to allow the OS to be shutdown before the service processor powers // the system off, attempt to set the poweroff delay to at least // 45 seconds. void set_poweroff_delay(int handle) { int ret; int delay; // set the bytes in the poweroff delay command buffer[0] = 0x02; // type = read buffer[1] = 0x03; // command length buffer[2] = 0x00; // data length LSB buffer[3] = 0x00; // data length MSB buffer[4] = 0x00; // status buffer[5] = 0x00; // reserved buffer[6] = 0x06; // 1st command byte - command 6.2.1 buffer[7] = 0x02; // 2nd cmd byte buffer[8] = 0x01; // 3rd cmd byte buffer[9] = 0x00; ret = SystemDataIO(handle, buffer, 0); if ( (ret != RC_SUCCESS) || (buffer[0] != 4) // type != command response || (buffer[1] != 3) // command length != 3 || (buffer[4] != 0) // status != 0 || (buffer[6] != 6) // command 6.2.1 || (buffer[7] != 2) || (buffer[8] != 1) ) return; delay = buffer[9] + buffer[10] << 8; if (delay >= 45) return; // set the poweroff delay to 45 seconds buffer[0] = 0x00; // type = write buffer[1] = 0x03; // command length buffer[2] = 0x02; // data length LSB buffer[3] = 0x00; // data length MSB buffer[4] = 0x00; // status buffer[5] = 0x00; // reserved buffer[6] = 0x06; // 1st command byte - command 6.2.1 buffer[7] = 0x02; // 2nd cmd byte buffer[8] = 0x01; // 3rd cmd byte buffer[9] = 0x2D; // 1st data byte 45 buffer[10] = 0x00; // 2nd data byte SystemDataIO(handle, buffer, 0); } // to be able to receive the poweroff event from the service processor // we have to enable it by writing 1 in the event's data bit. static int enable_poweroff_event(int handle) { int ret; // enable the 5.2.4 event buffer[0] = 0x00; // type = write buffer[1] = 0x03; // command length buffer[2] = 0x01; // data length LSB buffer[3] = 0x00; // data length MSB buffer[4] = 0x00; // status buffer[5] = 0x00; // reserved buffer[6] = 0x05; // 1st command byte - event 5.2.1 buffer[7] = 0x02; // 2nd command byte buffer[8] = 0x04; // 3rd command byte buffer[9] = 0x01; // 1st data byte buffer[10] = 0x00; // 2nd data byte ret = SystemDataIO(handle, buffer, 0); if ( (ret != RC_SUCCESS) || (buffer[4] != 0) ) return 0; return 1; } int main() { int ret; int handle; ret = OpenSPDriver(&handle, BUF_LENGTH, 0); if (ret != RC_SUCCESS) return 1; set_poweroff_delay(handle); if (!enable_poweroff_event(handle)) return 2; // wait for a poweroff event while (1) { memset(buffer, 0, 10); ret = RegisterForEvents(handle, buffer, N_IGNORE, ignore, 0); if (ret != RC_SUCCESS) break; // make sure we received a valid poweroff event if ( (buffer[0] == 5) // type = event && (buffer[1] == 3) // length = 3 && (buffer[4] == 0) // status = 0 && (buffer[6] == 5) // command = 5.2.4, i.e poweroff && (buffer[7] == 2) && (buffer[8] == 4) ) { syslog(LOG_CRIT, "Received Power Off notification " "from RSA adapter - Halting system\n"); system("/sbin/halt"); } } CloseSPDriver(handle, 0); return 0; } ibmasm-utils-3.0/src/bin/halt/Makefile0000644000175000017500000000044710104243354016666 0ustar chuckchuck SPHALT = ibmsphalt IBMASM_INC = -I../../api IBMASM_LIB = -L../../api -lsysSp all: $(SPHALT) install: install -d $(ROOT)/sbin install -m 700 $(SPHALT) $(ROOT)/sbin $(SPHALT): $(SPHALT).c $(CC) -o $@ $(IBMASM_INC) $(IBMASM_LIB) $@.c clean: rm -f *.o clobber: clean rm -f $(SPHALT) ibmasm-utils-3.0/src/bin/remote/0000755000175000017500000000000010251425604015567 5ustar chuckchuckibmasm-utils-3.0/src/bin/remote/evnode.c0000644000175000017500000000644610251425604017225 0ustar chuckchuck/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) IBM Corporation, 2005 * * Author: Vernon Mauery * */ #include #include #include #include #include #include #include #include #include int getopt(int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt; char *event_name(char *filename, int err) { int fd = open(filename, O_RDWR); if (fd < 0) return NULL; char name[256]= "Unknown"; if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) { if (err) perror("evdev ioctl"); } close(fd); return strdup(name); } void usage(char *name, int err) { fprintf(stderr, "%s [-h] [-v] [-v] [-p path/to/device | -n \"string name of device\"]\n" "Find either the device node for a string or the string for a node.\n" "It works by searching /dev/input for a device that reports the correct\n" "name via ioctl EVIOCGNAME. When it finds the device, it prints the path\n" "to the device to stdout while all other messages are printed to stderr.\n" "You can print the device name for a specific device, e.g.\n" "/dev/input/event3 by specifying the path to the device with the -p option.\n" "\t-p\tprint out string for this device node\n" "\t-n\tprint out device node that matches this string name\n" "\t-v\tadd a level of verbosity\n" "\t-h\tprint this help message\n", name); exit(err); } int main(int argc, char *argv[]) { int verbose = 0; char c; int xor = 0; char *nodefile = NULL, *nodename = NULL; while ((c = getopt (argc, argv, "p:n:vh")) != -1) { switch (c) { case 'v': verbose++; break; case 'h': usage(argv[0], 0); break; case 'p': if (xor) usage(argv[0], 2); nodefile = optarg; xor = 1; break; case 'n': if (xor) usage(argv[0], 2); nodename = optarg; xor = 1; break; default: usage(argv[0], 1); break; } } if (!xor) usage(argv[0], 3); if (nodefile) { char *name = event_name(nodefile, verbose >= 1); printf("%s\n", name); if (verbose >= 1) fprintf(stderr, "%s -> %s\n", nodefile, name); free(name); return 0; } char dirname[] = "/dev/input"; DIR *dir = opendir(dirname); struct dirent *de; char filename[256]; while ((de = readdir(dir)) != NULL) { sprintf(filename, "%s/%s", dirname, de->d_name); char *name = event_name(filename, verbose >= 2); if (!name) continue; if (strcmp(name, nodename) == 0) { printf("%s\n", filename); } if (verbose >= 1) fprintf(stderr, "%s -> %s\n", de->d_name, name); free(name); } closedir(dir); return 0; } ibmasm-utils-3.0/src/bin/remote/Makefile0000644000175000017500000000020110251425604017220 0ustar chuckchuck all: evnode install: install -D evnode $(ROOT)/usr/bin/evnode evnode: evnode.c $(CC) -o evnode evnode.c clean: rm -f *.o ibmasm-utils-3.0/src/bin/Makefile0000644000175000017500000000015410017160010015717 0ustar chuckchuck all: cd halt; $(MAKE) cd remote; $(MAKE) install: cd halt; $(MAKE) install cd remote; $(MAKE) install ibmasm-utils-3.0/src/Makefile0000644000175000017500000000023510017160075015162 0ustar chuckchuck export ROOT all: cd api; $(MAKE) cd bin; $(MAKE) cd init; $(MAKE) install: cd api; $(MAKE) install cd bin; $(MAKE) install cd init; $(MAKE) install ibmasm-utils-3.0/src/init/0000755000175000017500000000000010251441351014464 5ustar chuckchuckibmasm-utils-3.0/src/init/Makefile0000755000175000017500000000027610104245432016133 0ustar chuckchuck UPDOWN_SCRIPTS = ibmspup ibmspdown all: install: install -d $(ROOT)/var/lib/ibmasm install -d $(ROOT)/sbin install -d $(ROOT)/etc/init.d install -m 744 $(UPDOWN_SCRIPTS) $(ROOT)/sbin ibmasm-utils-3.0/src/init/ibmspup0000755000175000017500000000416010251425604016075 0ustar chuckchuck#!/bin/bash if ps -e | grep -qe "X\|kdm"; then echo "X must not be running while loading the ibmasm driver" echo "Kill X and try again." exit 1 fi if grep -v -q ibmasmfs /proc/filesystems; then modprobe ibmasm || exit 1 fi echo -en "\nWaiting for ibmasm device to appear " TIMEOUT=10 for ((i=0; i<$TIMEOUT; i++)); do DEVICE=`evnode -n "ibmasm RSA I remote mouse"` if [ ! -z $DEVICE ]; then break; fi echo -n ". " sleep 1 done echo DEVICE=`evnode -n "ibmasm RSA I remote mouse"` XCONFIG="/etc/X11/XF86Config" if [ -e $XCONFIG ]; then TMPFILE=`mktemp /tmp/ibmspupX.XXXXXXXXXX` || exit 1 AWKFILE=`mktemp /tmp/ibmspupAWK.XXXXXXXXXX` || exit 1 cat > $AWKFILE <<-ENDAWK BEGIN{ RS="" found_ibmasm=0 started_input=0 } { if (\$1=="Section" && index(\$2, "InputDevice") != 0 && found_ibmasm == 0) { started_input = 1 if (found_ibmasm == 0 && \$0 ~ /Identifier[ \t]*"ibmasm_remote"/) { sub(/Option[\t ]*"Device"[\t ]*"[^"]*"/,"Option \"Device\" \"$DEVICE\"", \$0) found_ibmasm = 1 } } else if (\$1 == "Section" && index(\$2, "ServerLayout") != 0) { if (index(\$0, "ibmasm_remote") == 0) { sub(/[ \t]*Screen/, " InputDevice \"ibmasm_remote\"\n&", \$0) } } else if (started_input == 1 && found_ibmasm == 0) { print "Section \"InputDevice\"" print " Driver \"ibmasm\"" print " Identifier \"ibmasm_remote\"" print " Option \"Device\" \"$DEVICE\"" print " Option \"XScale\" \"1024\"" print " Option \"YScale\" \"768\"" print " Option \"SendCoreEvents\" \"True\"" print "EndSection\n" found_ibmasm = 1 } printf "%s\n\n", \$0 } ENDAWK awk -f $AWKFILE $XCONFIG > $TMPFILE mv $XCONFIG ${XCONFIG}.ibmspupsave mv $TMPFILE $XCONFIG rm -f $AWKFILE fi mount -t ibmasmfs ibmasm /var/lib/ibmasm /sbin/ibmsphalt > /dev/null 2>&1 & ibmasm-utils-3.0/src/init/ibmspdown0000755000175000017500000000016110251425604016415 0ustar chuckchuck#!/bin/bash /sbin/killproc /sbin/ibmsphalt /bin/umount /var/lib/ibmasm 2>/dev/null /sbin/modprobe -q -r ibmasm