예제 #1
0
파일: ata-main.c 프로젝트: vladsor/chaos
static void hard_drive_handle_connection (ata_drive_type *ata_drive, 
                                          mailbox_id_type reply_mailbox_id)
{
  message_parameter_type message_parameter;
  ipc_structure_type ipc_structure;
  bool done = FALSE;
  u32 *data;
  unsigned int data_size = 1024;

  memory_allocate ((void **) &data, data_size);

  /* Accept the connection. */ 

  ipc_structure.output_mailbox_id = reply_mailbox_id;
  ipc_connection_establish (&ipc_structure);

  message_parameter.block = TRUE;

  while (!done)
  {
    message_parameter.protocol = IPC_PROTOCOL_BLOCK;
    message_parameter.message_class = IPC_CLASS_NONE;
    message_parameter.length = data_size;
    message_parameter.data = data;
  
    if (ipc_receive (ipc_structure.input_mailbox_id, &message_parameter,
                     &data_size) != IPC_RETURN_SUCCESS)
    {
      continue;
    }
    
    switch (message_parameter.message_class)
    {
      case IPC_BLOCK_READ:
      {
        ipc_block_read_type *ipc_block_read = (ipc_block_read_type *) data;

        /* FIXME: Do some boundary checking. */
#ifdef DEBUG
        log_print_formatted (&log_structure, LOG_URGENCY_DEBUG,
                               "Reading blocks %u-%u data.", 
                               ipc_block_read->start_block_number,
                               ipc_block_read->start_block_number +
                               ipc_block_read->number_of_blocks);
#endif
        ata_read_block (ata_drive, ipc_block_read->start_block_number,
            message_parameter.data, ipc_block_read->number_of_blocks);
        message_parameter.length = ipc_block_read->number_of_blocks;
        message_parameter.block = TRUE;
        
        ipc_send (ipc_structure.output_mailbox_id, &message_parameter);
	
        break;
      }
      
      case IPC_BLOCK_WRITE:
      {
        break;
      }
      
      case IPC_BLOCK_GET_INFO:
      {
	break;
      }
    }
  }
}
예제 #2
0
void handle_connection(mailbox_id_type *reply_mailbox_id)
{
    system_thread_name_set("Handling connection");

    message_parameter_type message_parameter;
    bool done = FALSE;
    bool mounted = FALSE;
    fat_info_type fat_info;
    ipc_structure_type ipc_structure;
    uint8_t *data;
    uint8_t **data_pointer = &data;
    unsigned int data_size = 16384;

    memory_allocate((void **) data_pointer, data_size);

    // Accept the connection.
    ipc_structure.output_mailbox_id = *reply_mailbox_id;
    if (ipc_connection_establish(&ipc_structure) != IPC_RETURN_SUCCESS)
    {
        return;
    }

    message_parameter.block = TRUE;

    while (!done)
    {
        message_parameter.data = data;
        message_parameter.protocol = IPC_PROTOCOL_FILE;
        message_parameter.message_class = IPC_CLASS_NONE;
        message_parameter.length = data_size;

        if (ipc_receive(ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS)
        {
            continue;
        }

        switch (message_parameter.message_class)
        {
            // Read one or more directory entries.
            case IPC_FILE_DIRECTORY_ENTRY_READ:
            {
                if (mounted)
                {
                    file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data;

                    if (!fat_directory_entry_read(directory_entry_read, &fat_info))
                    {
                        directory_entry_read->entries = 0;
                    }
                    message_parameter.length =
                        sizeof(file_directory_entry_read_type) +
                        sizeof(file_directory_entry_type) *
                        directory_entry_read->entries ;
                    //          log_print_formatted (0, PACKAGE, "Successfully read %u entries",
                    //                               directory_entry_read->entries);
                    //          log_print_formatted (0, PACKAGE, "max: %u\n", directory_entry_read->entries);
                    ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                }
                break;
            }

            case IPC_FILE_GET_INFO:
            {
                if (mounted)
                {
                    file_verbose_directory_entry_type *directory_entry = (file_verbose_directory_entry_type *) data;

                    if (!fat_file_get_info(&fat_info, directory_entry))
                    {
                        return_type return_value = FILE_RETURN_FILE_ABSENT;

                        log_print_formatted(&log_structure, LOG_URGENCY_ERROR, "IPC_FILE_GET_INFO failed");
                        message_parameter.message_class = IPC_FILE_RETURN_VALUE;
                        message_parameter.data = &return_value;
                        message_parameter.length = sizeof(return_type);
                    }

                    ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                }
                break;
            }

            case IPC_FILE_MOUNT_VOLUME:
            {
                mailbox_id_type *mailbox = (mailbox_id_type *) data;

                fat_info.block_structure.output_mailbox_id = *mailbox;
                if (ipc_service_connection_request(&fat_info.block_structure) != IPC_RETURN_SUCCESS)
                {
                    break;
                }

                // Check if we have a FAT file system at this location.
                if (!detect_fat(&fat_info))
                {
                    log_print(&log_structure, LOG_URGENCY_ERROR, "No FAT filesystem detected.");
                    break;
                }

                mounted = TRUE;

                break;
            }

            case IPC_FILE_OPEN:
            {
                ipc_file_open_type *open = (ipc_file_open_type *) data;

                if (!fat_file_open(&fat_info, open))
                {
                    log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to open file.");
                }

                ipc_send(ipc_structure.output_mailbox_id, &message_parameter);

                break;
            }

            case IPC_FILE_READ:
            {
                file_read_type *read = (file_read_type *) data;
                uint8_t *read_buffer;
                uint8_t **read_buffer_pointer = &read_buffer;

                memory_allocate((void **) read_buffer_pointer, read->bytes);

                if (!fat_file_read(&fat_info, read->file_handle, read_buffer, read->bytes))
                {
                    log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to read from file.");
                }

                message_parameter.data = read_buffer;
                message_parameter.length = read->bytes;
#ifdef DEBUG
                log_print_formatted(&log_structure, LOG_URGENCY_DEBUG, "Sending %lu", read->bytes);
#endif
                ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                memory_deallocate((void **) read_buffer_pointer);
                break;
            }

            // Unsupported functions.
            case IPC_FILE_CLOSE:
            case IPC_FILE_SEEK:
            case IPC_FILE_WRITE:
            case IPC_FILE_ACL_READ:
            case IPC_FILE_ACL_WRITE:
            case IPC_FILE_UNMOUNT_VOLUME:
            default:
            {
                return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED;

                message_parameter.data = &return_value;
                message_parameter.length = sizeof(return_type);

                ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                break;
            }
        }
    }
}
예제 #3
0
파일: realtek-pci.c 프로젝트: vladsor/chaos
static void handle_connection (mailbox_id_type reply_mailbox_id, 
                               realtek_device_type *device)
{
  message_parameter_type message_parameter;
  ipc_structure_type ipc_structure;
  bool done = FALSE;
  unsigned int data_size = 1024;
  u32 *data;

  memory_allocate ((void **) &data, data_size);

  /* Accept the connection. */ 

  ipc_structure.output_mailbox_id = reply_mailbox_id;
  ipc_connection_establish (&ipc_structure);

  message_parameter.data = data;
  message_parameter.block = TRUE;
  message_parameter.protocol = IPC_PROTOCOL_ETHERNET;

  while (!done)
  {
    message_parameter.message_class = IPC_CLASS_NONE;
    message_parameter.length = data_size;
    
    if (ipc_receive (ipc_structure.input_mailbox_id, &message_parameter,
                     &data_size) !=
        STORM_RETURN_SUCCESS)
    {
      continue;
    }

    switch (message_parameter.message_class)
    {
      case IPC_ETHERNET_REGISTER_TARGET:
      {
        /* FIXME: Check if the protocol is already registered */

        device->target[device->number_of_targets].mailbox_id = 
          ipc_structure.output_mailbox_id;
        device->target[device->number_of_targets].protocol_type =
          system_byte_swap_u16 (data[0]);
        device->number_of_targets++;
        break;
      }

      case IPC_ETHERNET_PACKET_SEND:
      {
        if (!realtek_start_transmit ((u8 *) data,
                                    message_parameter.length, device))
        {
          log_print (&log_structure, LOG_URGENCY_ERROR,
                     "Failed to send an ethernet packet.");

          /* FIXME: Do something. */
        }
        break;
      }

      case IPC_ETHERNET_ADDRESS_GET:
      {
        memory_copy (data, &device->ethernet_address, 6);
        message_parameter.length = 6;
        system_call_mailbox_send (ipc_structure.output_mailbox_id,
                                  &message_parameter);
        break;
      }

      default:
      {
        log_print (&log_structure, LOG_URGENCY_ERROR,
                   "Unknown IPC command received.");
        break;
      }
    }
  }
}