static void imem_free(unsigned int phys_addr) { struct imem_list *imem, *imemp; imem = imemp = imem_list_head; while (imem) { if (phys_addr == imem->phys_start) { if (imem == imem_list_head) { imem_list_head = imem->next; } else { imemp->next = imem->next; } kfree(imem); break; } imemp = imem; imem = imem->next; } #ifdef DEBUG_IMEM dump_imem_list(); #endif }
static void imem_free_all(void) { struct imem_list *imem, *tmp; imem = imem_list_head; while (imem) { tmp = imem; imem = imem->next; kfree(tmp); } imem_list_head = NULL; allocated_phys_addr = 0; imem = imem1_list_head; while (imem) { tmp = imem; imem = imem->next; kfree(tmp); } imem1_list_head = NULL; allocated_phys_addr1 = 0; #ifdef DEBUG_IMEM dump_imem_list(); #endif }
/* allocate 2^order pages inside the 4MB memory */ static int imem_alloc(unsigned int order) { int alloc_ok = 0; unsigned int start, end; unsigned int size = (1 << order) * PAGE_SIZE; struct imem_list *imem, *imemn, *imemp; allocated_phys_addr = 0; start = jz_imem_base; end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE; imem = imem_list_head; while (imem) { if ((imem->phys_start - start) >= size) { /* we got a valid address range */ alloc_ok = 1; break; } start = imem->phys_end + 1; imem = imem->next; } if (!alloc_ok) { if ((end - start) >= size) alloc_ok = 1; } if (alloc_ok) { end = start + size - 1; allocated_phys_addr = start; /* add to imem_list, up sorted by phys_start */ imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL); if (!imemn) { return -ENOMEM; } imemn->phys_start = start; imemn->phys_end = end; imemn->next = NULL; if (!imem_list_head) imem_list_head = imemn; else { imem = imemp = imem_list_head; while (imem) { if (start < imem->phys_start) { break; } imemp = imem; imem = imem->next; } if (imem == imem_list_head) { imem_list_head = imemn; imemn->next = imem; } else { imemn->next = imemp->next; imemp->next = imemn; } } } #ifdef DEBUG_IMEM dump_imem_list(); #endif return 0; }