lowlevel.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. #include "ibmasm.h"
  10. #include "lowlevel.h"
  11. #include "i2o.h"
  12. #include "dot_command.h"
  13. #include "remote.h"
  14. static struct i2o_header header = I2O_HEADER_TEMPLATE;
  15. int ibmasm_send_i2o_message(struct service_processor *sp)
  16. {
  17. u32 mfa;
  18. unsigned int command_size;
  19. struct i2o_message *message;
  20. struct command *command = sp->current_command;
  21. mfa = get_mfa_inbound(sp->base_address);
  22. if (!mfa)
  23. return 1;
  24. command_size = get_dot_command_size(command->buffer);
  25. header.message_size = outgoing_message_size(command_size);
  26. message = get_i2o_message(sp->base_address, mfa);
  27. memcpy_toio(&message->header, &header, sizeof(struct i2o_header));
  28. memcpy_toio(&message->data, command->buffer, command_size);
  29. set_mfa_inbound(sp->base_address, mfa);
  30. return 0;
  31. }
  32. irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id)
  33. {
  34. u32 mfa;
  35. struct service_processor *sp = (struct service_processor *)dev_id;
  36. void __iomem *base_address = sp->base_address;
  37. char tsbuf[32];
  38. if (!sp_interrupt_pending(base_address))
  39. return IRQ_NONE;
  40. dbg("respond to interrupt at %s\n", get_timestamp(tsbuf));
  41. if (mouse_interrupt_pending(sp)) {
  42. ibmasm_handle_mouse_interrupt(sp);
  43. clear_mouse_interrupt(sp);
  44. }
  45. mfa = get_mfa_outbound(base_address);
  46. if (valid_mfa(mfa)) {
  47. struct i2o_message *msg = get_i2o_message(base_address, mfa);
  48. ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg));
  49. } else
  50. dbg("didn't get a valid MFA\n");
  51. set_mfa_outbound(base_address, mfa);
  52. dbg("finished interrupt at %s\n", get_timestamp(tsbuf));
  53. return IRQ_HANDLED;
  54. }