static void create_hard_drive_service (ata_drive_type *ata_drive) { /* Create the service. */ if (ipc_service_create ("block", &ipc_structure, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't create block service."); return -1; } /* Main loop. */ system_thread_name_set ("Service handler"); while (TRUE) { mailbox_id_type reply_mailbox_id; ipc_service_connection_wait (&ipc_structure); reply_mailbox_id = ipc_structure.output_mailbox_id; if (system_thread_create () == SYSTEM_RETURN_THREAD_NEW) { system_call_thread_name_set ("Handling connection"); hard_drive_handle_connection (ata_drive, reply_mailbox_id); } } }
int main (void) { ipc_structure_type ipc_structure; ata_drive_type *ata_drive; unsigned int drive_number; /* Set the name of the server. */ system_process_name_set (PACKAGE_NAME); system_thread_name_set ("Initialising"); log_init (&log_structure, PACKAGE_NAME, &empty_tag); for ( drive_number = 0 ; drive_number < number_of_probe ; drive_number++ ) { if (!register_ports (ata_probe_drives[drive_number])) { continue; } ata_drive = ata_probe (ata_probe_drives[drive_number]); if (ata_drive != NULL) { switch (ata_drive->type) { case ATA_HARD_DRIVE : { create_hard_drive_service (ata_drive); break; } case ATA_CDROM : { create_cdrom_service (ata_drive); break; } /* FIXME: what we must do there ? */ default : { } } ata_drivers[number_of_drives] = ata_drive; number_of_drives++; } else { unregister_ports (ata_probe_drives[drive_number]); } } system_call_process_parent_unblock (); return 0; }
int main (void) { pci_device_info_type *device_info; unsigned int number_of_devices; unsigned int counter; unsigned int probe_counter; system_process_name_set (PACKAGE_NAME); system_thread_name_set ("Initialising"); if (log_init (&log_structure, PACKAGE_NAME, &empty_tag) != LOG_RETURN_SUCCESS) { return -1; } if (pci_init (&pci_structure, &empty_tag) != PCI_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't create connection to PCI service."); return -1; } system_call_process_parent_unblock (); for (probe_counter = 0; pci_device_probe[probe_counter].vendor_id != 0xFFFF; probe_counter++) { pci_device_exists (&pci_structure, &pci_device_probe[probe_counter], &device_info, &number_of_devices); if (number_of_devices != 0) { for (counter = 0; counter < number_of_devices; counter++) { if (system_thread_create () == SYSTEM_RETURN_THREAD_NEW) { handle_8139 (&device_info[counter]); } } } } return 0; }
int main (void) { ipc_structure_type ipc_structure; mailbox_id_type mailbox_id[10]; unsigned int services = 10; system_process_name_set (PACKAGE_NAME); system_thread_name_set ("Initialising"); if (log_init (&log_structure, PACKAGE_NAME, &empty_tag) != LOG_RETURN_SUCCESS) { return -1; } /* Create our service. */ if (ipc_service_create ("file_system", &ipc_structure, &empty_tag) != STORM_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't create a file system service."); return -1; } system_call_process_parent_unblock (); if (ipc_service_resolve ("virtual_file_system", mailbox_id, &services, 0, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't resolve VFS service."); return -1; } ipc_structure.output_mailbox_id = mailbox_id[0]; ipc_service_connection_request (&ipc_structure); handle_connection (&ipc_structure); return 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; } } } }
int main (void) { #if FALSE virtual_file_system_mount_type mount; mailbox_id_type mailbox_id[10]; ipc_structure_type vfs_structure; message_parameter_type message_parameter; file_read_type read; file_handle_type handle; file_verbose_directory_entry_type directory_entry; u8 *buffer; u8 *server_name_buffer; char *server[MAX_SERVERS]; unsigned int where, number_of_servers = 0, server_number; process_id_type process_id; unsigned int bytes_read; unsigned int services = 10; #endif /* Set our name. */ system_process_name_set (PACKAGE_NAME); system_thread_name_set ("Initialising"); if (log_init (&log_structure, PACKAGE_NAME, &empty_tag) != LOG_RETURN_SUCCESS) { return -1; } #if FALSE /* Mount the initial ramdisk as //ramdisk. To do this, we must first hook up a connection to the VFS service and resolve the first block service. */ if (ipc_service_resolve ("virtual_file_system", mailbox_id, &services, 5, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't resolve the VFS service."); return -1; } vfs_structure.output_mailbox_id = mailbox_id[0]; if (ipc_service_connection_request (&vfs_structure) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't connect to the VFS service."); return -1; } services = 1; if (ipc_service_resolve ("block", mailbox_id, &services, 5, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "No block services found."); return -1; } mount.mailbox_id = mailbox_id[0]; string_copy (mount.location, "ramdisk"); /* That's it. Send the message. */ message_parameter.protocol = IPC_PROTOCOL_VIRTUAL_FILE_SYSTEM; message_parameter.message_class = IPC_VIRTUAL_FILE_SYSTEM_MOUNT; message_parameter.data = &mount; message_parameter.length = sizeof (virtual_file_system_mount_type); message_parameter.block = TRUE; ipc_send (vfs_structure.output_mailbox_id, &message_parameter); log_print (&log_structure, LOG_URGENCY_DEBUG, "Mounted the first available block service as //ramdisk."); /* Now, read the list of servers to start from here. */ log_print (&log_structure, LOG_URGENCY_DEBUG, "Reading startup script..."); string_copy (directory_entry.path_name, STARTUP_FILE); if (file_get_info (&vfs_structure, &directory_entry) != FILE_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_ERROR, STARTUP_FILE " not found."); return -1; } memory_allocate ((void **) &server_name_buffer, directory_entry.size); file_open (&vfs_structure, STARTUP_FILE, FILE_MODE_READ, &handle); file_read (&vfs_structure, handle, directory_entry.size, &server_name_buffer); /* Parse the file. */ server[0] = &server_name_buffer[0]; number_of_servers++; for (where = 1; where < directory_entry.size; where++) { if (server_name_buffer[where] == '\n') { server_name_buffer[where] = '\0'; if (where + 1 < directory_entry.size) { server[number_of_servers] = &server_name_buffer[where + 1]; number_of_servers++; } } } log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Starting %u servers.", number_of_servers); for (server_number = 0; server_number < number_of_servers; server_number++) { log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "Starting %s.", server[server_number]); string_copy (directory_entry.path_name, server[server_number]); if (file_get_info (&vfs_structure, &directory_entry) != FILE_RETURN_SUCCESS) { log_print_formatted (&log_structure, LOG_URGENCY_ERROR, "'%s' could not be accessed!", server[server_number]); continue; } /* Open the file. */ file_open (&vfs_structure, server[server_number], FILE_MODE_READ, &handle); read.file_handle = handle; bytes_read = 0; log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Allocating %lu bytes for %s.", directory_entry.size, server[server_number]); memory_allocate ((void **) &buffer, directory_entry.size); log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Buffer is at %p.", buffer); while (bytes_read < directory_entry.size) { unsigned int bytes; /* Read the file. */ bytes = directory_entry.size - bytes_read; if (bytes > 32 * KB) { bytes = 32 * KB; } file_read (&vfs_structure, handle, bytes, &buffer[bytes_read]); bytes_read += bytes; } switch (execute_elf ((elf_header_type *) buffer, "", &process_id)) { case EXECUTE_ELF_RETURN_SUCCESS: { log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "New process ID %lu.", process_id); break; } case EXECUTE_ELF_RETURN_IMAGE_INVALID: { log_print (&log_structure, LOG_URGENCY_ERROR, "Invalid ELF image."); break; } case EXECUTE_ELF_RETURN_ELF_UNSUPPORTED: { log_print (&log_structure, LOG_URGENCY_ERROR, "Unsupported ELF."); break; } case EXECUTE_ELF_RETURN_FAILED: { log_print (&log_structure, LOG_URGENCY_ERROR, "system_process_create failed."); break; } } memory_deallocate ((void **) &buffer); } #endif system_call_process_parent_unblock (); log_print (&log_structure, LOG_URGENCY_DEBUG, "surf"); return 0; }
static void handle_8139 (pci_device_info_type *device_info) { unsigned int counter; u16 port_base = MAX_U16; u16 ports = 0; realtek_device_type *device; unsigned int physical, physical_index; ipc_structure_type ipc_structure; system_thread_name_set ("Initialising"); for (counter = 0; counter < PCI_NUMBER_OF_RESOURCES; counter++) { if ((device_info->resource[counter].flags & PCI_RESOURCE_IO) != 0) { port_base = device_info->resource[counter].start; ports = (device_info->resource[counter].end - device_info->resource[counter].start + 1); } } if (port_base == MAX_U16) { log_print_formatted (&log_structure, LOG_URGENCY_ERROR, "No port range found -- hardware possibly broken or incompatible?"); return; } system_call_port_range_register (port_base, ports, "Realtek 8139"); memory_allocate ((void **) &device, sizeof (realtek_device_type)); device->port_base = port_base; device->irq = device_info->irq; /* Initialise the adapter. */ system_port_out_u8 (port_base + Config1, 0x00); if (read_eeprom (port_base, 0) != 0xFFFF) { for (counter = 0; counter < 3; counter++) { ((u16 *)(device->ethernet_address))[counter] = system_little_endian_to_native_u16 (read_eeprom (port_base, counter + 7)); } } else { for (counter = 0; counter < 6; counter++) { device->ethernet_address[counter] = system_port_in_u8 (port_base + MAC0 + counter); } } log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "Realtek 8139 at 0x%X, IRQ %d, ethernet address: %02X:%02X:%02X:%02X:%02X:%02X", port_base, device_info->irq, device->ethernet_address[0], device->ethernet_address[1], device->ethernet_address[2], device->ethernet_address[3], device->ethernet_address[4], device->ethernet_address[5]); /* Find the connected MII transceivers. */ for (physical = 0, physical_index = 0; physical < 32 && physical_index < sizeof (device->mii_address); physical++) { int mii_status = mdio_read (port_base, physical, 1); if (mii_status != 0xFFFF && mii_status != 0x0000) { device->mii_address[physical_index] = physical; physical_index++; log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "MII transceiver found at address %d.", physical); } } if (physical_index == 0) { if (realtek_debug > 1) { log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "No MII transceivers found! Assuming SYM " "transceiver."); } device->mii_address[0] = -1; } /* Soft reset the chip. */ system_port_out_u8 (port_base + ChipCommand, CommandReset); pci_allocate_buffer ((void **) &device->tx_buffers_dma, (void **) &device->tx_buffers, TX_BUFFER_SIZE * NUMBER_OF_TX_DESCRIPTORS); pci_allocate_buffer ((void **) &device->rx_ring_dma, (void **) &device->rx_ring, RX_BUFFER_LENGTH + 16); device->tx_full = FALSE; device->current_rx = 0; device->dirty_tx = device->current_tx = 0; for (counter = 0; counter < NUMBER_OF_TX_DESCRIPTORS; counter++) { device->tx_buffer[counter] = &device->tx_buffers[counter * TX_BUFFER_SIZE]; } /* Check that the chip has finished the reset. */ for (counter = 0; counter < 1000; counter++) { if ((system_port_in_u8 (port_base + ChipCommand) & CommandReset) == 0) { break; } } /* Must enable Tx/Rx before setting transfer thresholds! */ system_port_out_u8 (port_base + ChipCommand, CommandRxEnable | CommandTxEnable); system_port_out_u32 (port_base + RxConfig, (RX_FIFO_THRESHOLD << 13) | (RX_BUFFER_LENGTH_INDEX << 11) | (RX_DMA_BURST << 8)); system_port_out_u32 (port_base + TxConfig, (TX_DMA_BURST << 8) | 0x03000000); if (device->mii_address[0] >= 0) { u16 mii_reg5 = mdio_read (port_base, device->mii_address[0], 5); if (mii_reg5 == 0xffff) { } else if ((mii_reg5 & 0x0100) == 0x0100 || (mii_reg5 & 0x00C0) == 0x0040) { device->full_duplex = TRUE; } log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "Setting %s%s-duplex based on" " auto-negotiated partner ability %4.4x.\n", mii_reg5 == 0 ? "" : ((mii_reg5 & 0x0180) != 0) ? "100 Mbps " : "10 Mbps ", device->full_duplex ? "full" : "half", mii_reg5); } system_port_out_u8 (port_base + Config9346, 0xC0); system_port_out_u8 (port_base + Config1, device->full_duplex ? 0x60 : 0x20); system_port_out_u8 (port_base + Config9346, 0x00); system_port_out_u32 (port_base + RxBuffer, (u32) device->rx_ring_dma); /* Start the chip's Tx and Rx process. */ system_port_out_u32 (port_base + RxMissed, 0); set_rx_mode (device); system_port_out_u8 (port_base + ChipCommand, CommandRxEnable | CommandTxEnable); /* Enable all known interrupts by setting the interrupt mask. */ system_port_out_u16 (port_base + InterruptMask, PCIError | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOverrun | TxError | TxOK | RxError | RxOK); if (system_thread_create () == SYSTEM_RETURN_THREAD_NEW) { system_thread_name_set ("IRQ handler"); if (system_call_irq_register (device_info->irq, "Realtek 8139") != SYSTEM_RETURN_SUCCESS) { log_print_formatted (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't set up IRQ handler"); return; } /* Loop and handle interrupts. */ while (TRUE) { int bogus_count = max_interrupt_work; unsigned status, link_changed = 0; system_call_irq_wait (device->irq); do { status = system_port_in_u16 (port_base + InterruptStatus); /* Acknowledge all of the current interrupt sources ASAP, but an first get an additional status bit from CSCR. */ if ((status & RxUnderrun) && system_port_in_u16 (port_base + CSCR) & CSCR_LinkChangeBit) { link_changed = 1; } system_port_out_u16 (port_base + InterruptStatus, status); if ((status & (PCIError | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOverrun | TxError | TxOK | RxError | RxOK)) == 0) { break; } /* Rx interrupt. */ if ((status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOverrun)) != 0) { realtek_receive (device); } if ((status & (TxOK | TxError)) != 0) { unsigned int dirty_tx = device->dirty_tx; while (device->current_tx - dirty_tx > 0) { int entry = dirty_tx % NUMBER_OF_TX_DESCRIPTORS; int txstatus = system_port_in_u32 (port_base + TxStatus0 + entry * 4); if ((txstatus & (TxStatusOK | TxUnderrun | TxAborted)) == 0) { /* It still hasn't been transmitted. */ break; } /* Note: TxCarrierLost is always asserted at 100 Mbps. */ if ((txstatus & (TxOutOfWindow | TxAborted)) != 0) { /* There was an major error, log it. */ // device->stats.tx_errors++; if ((txstatus & TxAborted) != 0) { // tp->stats.tx_aborted_errors++; system_port_out_u32 (port_base + TxConfig, (TX_DMA_BURST << 8) | 0x03000001); } if ((txstatus & TxCarrierLost) != 0) { // tp->stats.tx_carrier_errors++; } if ((txstatus & TxOutOfWindow) != 0) { // tp->stats.tx_window_errors++; } } else { if ((txstatus & TxUnderrun) != 0) { /* Add 64 to the Tx FIFO threshold. */ if (device->tx_flag < 0x00300000) { device->tx_flag += 0x00020000; } // tp->stats.tx_fifo_errors++; } // tp->stats.collisions += (txstatus >> 24) & 15; // tp->stats.tx_bytes += txstatus & 0x7ff; // tp->stats.tx_packets++; } // if (tp->tx_info[entry].mapping != 0) // { // pci_unmap_single (tp->pdev, // tp->tx_info[entry].mapping, // tp->tx_info[entry].skb->len, // PCI_DMA_TODEVICE); // tp->tx_info[entry].mapping = 0; // } /* Free the original skb. */ // dev_kfree_skb_irq (tp->tx_info[entry].skb); // tp->tx_info[entry].skb = NULL; if (device->tx_full) { /* The ring is no longer full, wake the queue. */ device->tx_full = FALSE; // netif_wake_queue(dev); } dirty_tx++; } device->dirty_tx = dirty_tx; } /* Check uncommon events with one test. */ if ((status & (PCIError | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOverrun | TxError | RxError)) != 0) { if (realtek_debug > 2) { log_print_formatted (&log_structure, LOG_URGENCY_WARNING, "Abnormal interrupt, status %8.8x.\n", status); } if (status == 0xFFFFFFFF) { break; } /* Update the error count. */ // tp->stats.rx_missed_errors += inl(port_base + RxMissed); system_port_out_u32 (port_base + RxMissed, 0); if ((status & RxUnderrun) != 0 && link_changed) { /* Really link-change on new chips. */ int lpar = system_port_in_u16 (port_base + NWayLPAR); int duplex = (lpar & 0x0100) || (lpar & 0x01C0) == 0x0040; if (device->full_duplex != duplex) { device->full_duplex = duplex; system_port_out_u8 (port_base + Config9346, 0xC0); system_port_out_u8 (port_base + Config1, device->full_duplex ? 0x60 : 0x20); system_port_out_u8 (port_base + Config9346, 0x00); } status &= ~RxUnderrun; } if ((status & (RxUnderrun | RxOverflow | RxError | RxFIFOOverrun)) != 0) { // tp->stats.rx_errors++; } if ((status & (PCSTimeout)) != 0) { // tp->stats.rx_length_errors++; } if ((status & (RxUnderrun | RxFIFOOverrun)) != 0) { // tp->stats.rx_fifo_errors++; } if ((status & RxOverflow) != 0) { // tp->stats.rx_over_errors++; device->current_rx = (system_port_in_u16 (port_base + RxBufferAddress) % RX_BUFFER_LENGTH); system_port_out_u16 (port_base + RxBufferPointer, device->current_rx - 16); } if ((status & PCIError) != 0) { log_print (&log_structure, LOG_URGENCY_WARNING, "PCI Bus error."); } } if (--bogus_count < 0) { log_print_formatted (&log_structure, LOG_URGENCY_WARNING, "Too much work at interrupt, " "InterruptStatus = 0x%4.4x.", status); /* Clear all interrupt sources. */ system_port_out_u16 (port_base + InterruptStatus, 0xFFFF); break; } } while (TRUE); system_call_irq_acknowledge (device->irq); } } /* Now, use the remaining thread for the service handler. */ system_thread_name_set ("Service handler"); /* Create the service. */ if (ipc_service_create ("ethernet", &ipc_structure, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't create ethernet service."); return; } while (TRUE) { mailbox_id_type reply_mailbox_id; ipc_service_connection_wait (&ipc_structure); reply_mailbox_id = ipc_structure.output_mailbox_id; if (system_thread_create () == SYSTEM_RETURN_THREAD_NEW) { system_call_thread_name_set ("Handling connection"); handle_connection (reply_mailbox_id, device); } } }