diff options
author | Anton Kling <anton@kling.gg> | 2024-06-27 23:17:19 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-06-28 12:59:08 +0200 |
commit | be160327599887876684f8ec106bd943f44ff068 (patch) | |
tree | f128b38fea778a02a73b817b56830cdb4e3158dc | |
parent | 1a51d1d1158fc1b5367452eb0622ab1fd05e80bd (diff) |
RTL8139: Add out of memory conditions
-rw-r--r-- | kernel/drivers/rtl8139.c | 46 | ||||
-rw-r--r-- | kernel/kmalloc.c | 4 | ||||
-rw-r--r-- | kernel/socket.c | 1 |
3 files changed, 40 insertions, 11 deletions
diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c index 9c163e7..6214d73 100644 --- a/kernel/drivers/rtl8139.c +++ b/kernel/drivers/rtl8139.c @@ -16,8 +16,8 @@ // 1 - 16K // 2 - 32K // 3 - 64K -#define RTL8139_CHOSEN_BUFFER 3 -#define RTL8139_RXBUFFER_SIZE (8192 << (RTL8139_CHOSEN_BUFFER)) +unsigned int rtl8139_chosen_buffer = 3; +#define RTL8139_RXBUFFER_SIZE (u32)(8192 << rtl8139_chosen_buffer) #define TSD0 0x10 // transmit status #define TSAD0 0x20 // transmit start address @@ -151,10 +151,37 @@ u8 rtl8139_get_transmit_status(u32 base_address) { void rtl8139_init(void) { if (!pci_populate_device_struct(0x10EC, 0x8139, &rtl8139)) { - kprintf("RTL8139 not found :(\n"); return; } - kprintf("RTL8139 found at bus: %x slot: %x\n", rtl8139.bus, rtl8139.slot); + klog(LOG_NOTE, "RTL8139 found at bus: %x slot: %x\n", rtl8139.bus, + rtl8139.slot); + + for (int i = 0; i < 4; i++) { + send_buffers[i] = kmalloc_align(0x1000, NULL); + if (!send_buffers[i]) { + goto rtl8139_error_memory; + } + } + + // Try to chose the largest buffer possible without running out of + // memory. + // NOTE: This is so rare it should probably not even be here. I just + // thought it was a cool idea. + u32 rx_buffer; + for (;;) { + // NOTE: RTL8139_RXBUFFER_SIZE is a macro that contains + // "rtl8139_chosen_buffer" + device_buffer = + kmalloc_align(RTL8139_RXBUFFER_SIZE + 16, (void **)&rx_buffer); + if (!device_buffer) { + if (0 == rtl8139_chosen_buffer) { + goto rtl8139_error_memory; + } + rtl8139_chosen_buffer--; + continue; + } + break; + } u8 header_type = (pci_config_read32(&rtl8139, 0, 0xC) >> 16) & 0xFF; assert(0 == header_type); @@ -174,10 +201,7 @@ void rtl8139_init(void) { outb(base_address + CMD, 0x10); for (; 0 != (inb(base_address + CMD) & 0x10);) ; - device_buffer = ksbrk(RTL8139_RXBUFFER_SIZE + 16); - memset(device_buffer, 0, RTL8139_RXBUFFER_SIZE + 16); // Setupt the recieve buffer - u32 rx_buffer = (u32)virtual_to_physical(device_buffer, NULL); outl(base_address + RBSTART, rx_buffer); // Set IMR + ISR @@ -195,13 +219,15 @@ void rtl8139_init(void) { u8 packet_accept = 0xe; // 0xe is AB+AM+APM // Configure the recieve buffer - outl(base_address + 0x44, packet_accept | ((RTL8139_CHOSEN_BUFFER) << 11) | + outl(base_address + 0x44, packet_accept | (rtl8139_chosen_buffer << 11) | (fifo_threshold << 13) | (dma_burst << 8)); install_handler((interrupt_handler)rtl8139_handler, INT_32_INTERRUPT_GATE(0x3), 0x20 + interrupt_line); - + return; +rtl8139_error_memory: + klog(LOG_ERROR, "Failed to initalize RTL8139 driver: Out of memory"); for (int i = 0; i < 4; i++) { - send_buffers[i] = ksbrk(0x1000); + kmalloc_align_free(send_buffers[i], 0x1000); } } diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c index 5c399e6..939589d 100644 --- a/kernel/kmalloc.c +++ b/kernel/kmalloc.c @@ -25,6 +25,10 @@ void *kmalloc_align(size_t s, void **physical) { } void kmalloc_align_free(void *p, size_t s) { + if (!p) { + return; + } + for (size_t i = 0; i < s; i += 0x1000) { Page *page = get_page((char *)p + i, NULL, PAGE_NO_ALLOCATE, 0); if (!page) { diff --git a/kernel/socket.c b/kernel/socket.c index 54f7598..d4e86a9 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -303,7 +303,6 @@ void udp_close(vfs_fd_t *fd) { } int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - kprintf("CONNECT\n"); vfs_fd_t *fd = get_vfs_fd(sockfd, NULL); if (!fd) { return -EBADF; |