1 2 /* 3 * IBM ASM Service Processor Device Driver 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * 19 * Copyright (C) IBM Corporation, 2004 20 * 21 * Author: Max Asb�ck <amax@us.ibm.com> 22 * 23 */ 24 25 #include <linux/sched.h> 26 #include <linux/slab.h> 27 #include "ibmasm.h" 28 #include "lowlevel.h" 29 30 static void exec_next_command(struct service_processor *sp); 31 32 static atomic_t command_count = ATOMIC_INIT(0); 33 34 struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size) 35 { 36 struct command *cmd; 37 38 if (buffer_size > IBMASM_CMD_MAX_BUFFER_SIZE) 39 return NULL; 40 41 cmd = kzalloc(sizeof(struct command), GFP_KERNEL); 42 if (cmd == NULL) 43 return NULL; 44 45 46 cmd->buffer = kzalloc(buffer_size, GFP_KERNEL); 47 if (cmd->buffer == NULL) { 48 kfree(cmd); 49 return NULL; 50 } 51 cmd->buffer_size = buffer_size; 52 53 kref_init(&cmd->kref); 54 cmd->lock = &sp->lock; 55 56 cmd->status = IBMASM_CMD_PENDING; 57 init_waitqueue_head(&cmd->wait); 58 INIT_LIST_HEAD(&cmd->queue_node); 59 60 atomic_inc(&command_count); 61 dbg("command count: %d\n", atomic_read(&command_count)); 62 63 return cmd; 64 } 65 66 void ibmasm_free_command(struct kref *kref) 67 { 68 struct command *cmd = to_command(kref); 69 70 list_del(&cmd->queue_node); 71 atomic_dec(&command_count); 72 dbg("command count: %d\n", atomic_read(&command_count)); 73 kfree(cmd->buffer); 74 kfree(cmd); 75 } 76 77 static void enqueue_command(struct service_processor *sp, struct command *cmd) 78 { 79 list_add_tail(&cmd->queue_node, &sp->command_queue); 80 } 81 82 static struct command *dequeue_command(struct service_processor *sp) 83 { 84 struct command *cmd; 85 struct list_head *next; 86 87 if (list_empty(&sp->command_queue)) 88 return NULL; 89 90 next = sp->command_queue.next; 91 list_del_init(next); 92 cmd = list_entry(next, struct command, queue_node); 93 94 return cmd; 95 } 96 97 static inline void do_exec_command(struct service_processor *sp) 98 { 99 char tsbuf[32]; 100 101 dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf)); 102 103 if (ibmasm_send_i2o_message(sp)) { 104 sp->current_command->status = IBMASM_CMD_FAILED; 105 wake_up(&sp->current_command->wait); 106 command_put(sp->current_command); 107 exec_next_command(sp); 108 } 109 } 110 111 /** 112 * exec_command 113 * send a command to a service processor 114 * Commands are executed sequentially. One command (sp->current_command) 115 * is sent to the service processor. Once the interrupt handler gets a 116 * message of type command_response, the message is copied into 117 * the current commands buffer, 118 */ 119 void ibmasm_exec_command(struct service_processor *sp, struct command *cmd) 120 { 121 unsigned long flags; 122 char tsbuf[32]; 123 124 dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf)); 125 126 spin_lock_irqsave(&sp->lock, flags); 127 128 if (!sp->current_command) { 129 sp->current_command = cmd; 130 command_get(sp->current_command); 131 spin_unlock_irqrestore(&sp->lock, flags); 132 do_exec_command(sp); 133 } else { 134 enqueue_command(sp, cmd); 135 spin_unlock_irqrestore(&sp->lock, flags); 136 } 137 } 138 139 static void exec_next_command(struct service_processor *sp) 140 { 141 unsigned long flags; 142 char tsbuf[32]; 143 144 dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf)); 145 146 spin_lock_irqsave(&sp->lock, flags); 147 sp->current_command = dequeue_command(sp); 148 if (sp->current_command) { 149 command_get(sp->current_command); 150 spin_unlock_irqrestore(&sp->lock, flags); 151 do_exec_command(sp); 152 } else { 153 spin_unlock_irqrestore(&sp->lock, flags); 154 } 155 } 156 157 /** 158 * Sleep until a command has failed or a response has been received 159 * and the command status been updated by the interrupt handler. 160 * (see receive_response). 161 */ 162 void ibmasm_wait_for_response(struct command *cmd, int timeout) 163 { 164 wait_event_interruptible_timeout(cmd->wait, 165 cmd->status == IBMASM_CMD_COMPLETE || 166 cmd->status == IBMASM_CMD_FAILED, 167 timeout * HZ); 168 } 169 170 /** 171 * receive_command_response 172 * called by the interrupt handler when a dot command of type command_response 173 * was received. 174 */ 175 void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size) 176 { 177 struct command *cmd = sp->current_command; 178 179 if (!sp->current_command) 180 return; 181 182 memcpy_fromio(cmd->buffer, response, min(size, cmd->buffer_size)); 183 cmd->status = IBMASM_CMD_COMPLETE; 184 wake_up(&sp->current_command->wait); 185 command_put(sp->current_command); 186 exec_next_command(sp); 187 } 188