1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * IBM ASM Service Processor Device Driver |
4 | * |
5 | * Copyright (C) IBM Corporation, 2004 |
6 | * |
7 | * Author: Max Asböck <amax@us.ibm.com> |
8 | */ |
9 | |
10 | #include "ibmasm.h" |
11 | #include "lowlevel.h" |
12 | #include "i2o.h" |
13 | #include "dot_command.h" |
14 | #include "remote.h" |
15 | |
16 | static struct i2o_header = I2O_HEADER_TEMPLATE; |
17 | |
18 | |
19 | int ibmasm_send_i2o_message(struct service_processor *sp) |
20 | { |
21 | u32 mfa; |
22 | unsigned int command_size; |
23 | struct i2o_message *message; |
24 | struct command *command = sp->current_command; |
25 | |
26 | mfa = get_mfa_inbound(base_address: sp->base_address); |
27 | if (!mfa) |
28 | return 1; |
29 | |
30 | command_size = get_dot_command_size(buffer: command->buffer); |
31 | header.message_size = outgoing_message_size(data_size: command_size); |
32 | |
33 | message = get_i2o_message(base_address: sp->base_address, mfa); |
34 | |
35 | memcpy_toio(&message->header, &header, sizeof(struct i2o_header)); |
36 | memcpy_toio(&message->data, command->buffer, command_size); |
37 | |
38 | set_mfa_inbound(base_address: sp->base_address, mfa); |
39 | |
40 | return 0; |
41 | } |
42 | |
43 | irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id) |
44 | { |
45 | u32 mfa; |
46 | struct service_processor *sp = (struct service_processor *)dev_id; |
47 | void __iomem *base_address = sp->base_address; |
48 | char tsbuf[32]; |
49 | |
50 | if (!sp_interrupt_pending(base_address)) |
51 | return IRQ_NONE; |
52 | |
53 | dbg("respond to interrupt at %s\n" , get_timestamp(tsbuf)); |
54 | |
55 | if (mouse_interrupt_pending(sp)) { |
56 | ibmasm_handle_mouse_interrupt(sp); |
57 | clear_mouse_interrupt(sp); |
58 | } |
59 | |
60 | mfa = get_mfa_outbound(base_address); |
61 | if (valid_mfa(mfa)) { |
62 | struct i2o_message *msg = get_i2o_message(base_address, mfa); |
63 | ibmasm_receive_message(sp, data: &msg->data, data_size: incoming_data_size(i2o_message: msg)); |
64 | } else |
65 | dbg("didn't get a valid MFA\n" ); |
66 | |
67 | set_mfa_outbound(base_address, mfa); |
68 | dbg("finished interrupt at %s\n" , get_timestamp(tsbuf)); |
69 | |
70 | return IRQ_HANDLED; |
71 | } |
72 | |