command.c (1da177e4c3f41524e886b7f1b8a0c1fc7321cac2) | command.c (8818760512424f60ad9fafb7a087b007a9274eb3) |
---|---|
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 unchanged lines hidden (view full) --- 18 * 19 * Copyright (C) IBM Corporation, 2004 20 * 21 * Author: Max Asb�ck <amax@us.ibm.com> 22 * 23 */ 24 25#include "ibmasm.h" | 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 unchanged lines hidden (view full) --- 18 * 19 * Copyright (C) IBM Corporation, 2004 20 * 21 * Author: Max Asb�ck <amax@us.ibm.com> 22 * 23 */ 24 25#include "ibmasm.h" |
26#include "lowlevel.h" |
|
26 27static void exec_next_command(struct service_processor *sp); 28static void free_command(struct kobject *kobj); 29 30static struct kobj_type ibmasm_cmd_kobj_type = { 31 .release = free_command, 32}; 33 | 27 28static void exec_next_command(struct service_processor *sp); 29static void free_command(struct kobject *kobj); 30 31static struct kobj_type ibmasm_cmd_kobj_type = { 32 .release = free_command, 33}; 34 |
35static atomic_t command_count = ATOMIC_INIT(0); |
|
34 | 36 |
35struct command *ibmasm_new_command(size_t buffer_size) | 37struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size) |
36{ 37 struct command *cmd; 38 39 if (buffer_size > IBMASM_CMD_MAX_BUFFER_SIZE) 40 return NULL; 41 42 cmd = kmalloc(sizeof(struct command), GFP_KERNEL); 43 if (cmd == NULL) --- 6 unchanged lines hidden (view full) --- 50 kfree(cmd); 51 return NULL; 52 } 53 memset(cmd->buffer, 0, buffer_size); 54 cmd->buffer_size = buffer_size; 55 56 kobject_init(&cmd->kobj); 57 cmd->kobj.ktype = &ibmasm_cmd_kobj_type; | 38{ 39 struct command *cmd; 40 41 if (buffer_size > IBMASM_CMD_MAX_BUFFER_SIZE) 42 return NULL; 43 44 cmd = kmalloc(sizeof(struct command), GFP_KERNEL); 45 if (cmd == NULL) --- 6 unchanged lines hidden (view full) --- 52 kfree(cmd); 53 return NULL; 54 } 55 memset(cmd->buffer, 0, buffer_size); 56 cmd->buffer_size = buffer_size; 57 58 kobject_init(&cmd->kobj); 59 cmd->kobj.ktype = &ibmasm_cmd_kobj_type; |
60 cmd->lock = &sp->lock; |
|
58 59 cmd->status = IBMASM_CMD_PENDING; 60 init_waitqueue_head(&cmd->wait); 61 INIT_LIST_HEAD(&cmd->queue_node); 62 | 61 62 cmd->status = IBMASM_CMD_PENDING; 63 init_waitqueue_head(&cmd->wait); 64 INIT_LIST_HEAD(&cmd->queue_node); 65 |
66 atomic_inc(&command_count); 67 dbg("command count: %d\n", atomic_read(&command_count)); 68 |
|
63 return cmd; 64} 65 66static void free_command(struct kobject *kobj) 67{ 68 struct command *cmd = to_command(kobj); 69 70 list_del(&cmd->queue_node); | 69 return cmd; 70} 71 72static void free_command(struct kobject *kobj) 73{ 74 struct command *cmd = to_command(kobj); 75 76 list_del(&cmd->queue_node); |
77 atomic_dec(&command_count); 78 dbg("command count: %d\n", atomic_read(&command_count)); |
|
71 kfree(cmd->buffer); 72 kfree(cmd); 73} 74 75static void enqueue_command(struct service_processor *sp, struct command *cmd) 76{ 77 list_add_tail(&cmd->queue_node, &sp->command_queue); 78} --- 10 unchanged lines hidden (view full) --- 89 list_del_init(next); 90 cmd = list_entry(next, struct command, queue_node); 91 92 return cmd; 93} 94 95static inline void do_exec_command(struct service_processor *sp) 96{ | 79 kfree(cmd->buffer); 80 kfree(cmd); 81} 82 83static void enqueue_command(struct service_processor *sp, struct command *cmd) 84{ 85 list_add_tail(&cmd->queue_node, &sp->command_queue); 86} --- 10 unchanged lines hidden (view full) --- 97 list_del_init(next); 98 cmd = list_entry(next, struct command, queue_node); 99 100 return cmd; 101} 102 103static inline void do_exec_command(struct service_processor *sp) 104{ |
105 char tsbuf[32]; 106 107 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); 108 |
|
97 if (ibmasm_send_i2o_message(sp)) { 98 sp->current_command->status = IBMASM_CMD_FAILED; | 109 if (ibmasm_send_i2o_message(sp)) { 110 sp->current_command->status = IBMASM_CMD_FAILED; |
111 wake_up(&sp->current_command->wait); 112 command_put(sp->current_command); |
|
99 exec_next_command(sp); 100 } 101} 102 103/** 104 * exec_command 105 * send a command to a service processor 106 * Commands are executed sequentially. One command (sp->current_command) 107 * is sent to the service processor. Once the interrupt handler gets a 108 * message of type command_response, the message is copied into 109 * the current commands buffer, 110 */ 111void ibmasm_exec_command(struct service_processor *sp, struct command *cmd) 112{ 113 unsigned long flags; | 113 exec_next_command(sp); 114 } 115} 116 117/** 118 * exec_command 119 * send a command to a service processor 120 * Commands are executed sequentially. One command (sp->current_command) 121 * is sent to the service processor. Once the interrupt handler gets a 122 * message of type command_response, the message is copied into 123 * the current commands buffer, 124 */ 125void ibmasm_exec_command(struct service_processor *sp, struct command *cmd) 126{ 127 unsigned long flags; |
128 char tsbuf[32]; |
|
114 | 129 |
130 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); 131 |
|
115 spin_lock_irqsave(&sp->lock, flags); 116 117 if (!sp->current_command) { | 132 spin_lock_irqsave(&sp->lock, flags); 133 134 if (!sp->current_command) { |
118 command_get(cmd); | |
119 sp->current_command = cmd; | 135 sp->current_command = cmd; |
136 command_get(sp->current_command); |
|
120 spin_unlock_irqrestore(&sp->lock, flags); | 137 spin_unlock_irqrestore(&sp->lock, flags); |
121 | |
122 do_exec_command(sp); 123 } else { 124 enqueue_command(sp, cmd); 125 spin_unlock_irqrestore(&sp->lock, flags); 126 } 127} 128 129static void exec_next_command(struct service_processor *sp) 130{ 131 unsigned long flags; | 138 do_exec_command(sp); 139 } else { 140 enqueue_command(sp, cmd); 141 spin_unlock_irqrestore(&sp->lock, flags); 142 } 143} 144 145static void exec_next_command(struct service_processor *sp) 146{ 147 unsigned long flags; |
148 char tsbuf[32]; |
|
132 | 149 |
133 wake_up(&sp->current_command->wait); 134 command_put(sp->current_command); | 150 dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); |
135 136 spin_lock_irqsave(&sp->lock, flags); 137 sp->current_command = dequeue_command(sp); 138 if (sp->current_command) { 139 command_get(sp->current_command); 140 spin_unlock_irqrestore(&sp->lock, flags); 141 do_exec_command(sp); 142 } else { --- 21 unchanged lines hidden (view full) --- 164 */ 165void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size) 166{ 167 struct command *cmd = sp->current_command; 168 169 if (!sp->current_command) 170 return; 171 | 151 152 spin_lock_irqsave(&sp->lock, flags); 153 sp->current_command = dequeue_command(sp); 154 if (sp->current_command) { 155 command_get(sp->current_command); 156 spin_unlock_irqrestore(&sp->lock, flags); 157 do_exec_command(sp); 158 } else { --- 21 unchanged lines hidden (view full) --- 180 */ 181void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size) 182{ 183 struct command *cmd = sp->current_command; 184 185 if (!sp->current_command) 186 return; 187 |
172 memcpy(cmd->buffer, response, min(size, cmd->buffer_size)); | 188 memcpy_fromio(cmd->buffer, response, min(size, cmd->buffer_size)); |
173 cmd->status = IBMASM_CMD_COMPLETE; | 189 cmd->status = IBMASM_CMD_COMPLETE; |
190 wake_up(&sp->current_command->wait); 191 command_put(sp->current_command); |
|
174 exec_next_command(sp); 175} | 192 exec_next_command(sp); 193} |