- struct page *page;
- int i, j;
- void *p;
-
- ctx->buffer_size = PAGE_ALIGN(size);
- if (size == 0)
- return 0;
-
- ctx->buffer = vmalloc_32_user(ctx->buffer_size);
- if (ctx->buffer == NULL)
- goto fail_buffer_alloc;
-
- ctx->page_count = ctx->buffer_size >> PAGE_SHIFT;
- ctx->pages =
- kzalloc(ctx->page_count * sizeof(ctx->pages[0]), GFP_KERNEL);
- if (ctx->pages == NULL)
- goto fail_pages_alloc;
-
- p = ctx->buffer;
- for (i = 0; i < ctx->page_count; i++, p += PAGE_SIZE) {
- page = vmalloc_to_page(p);
- ctx->pages[i] = dma_map_page(ctx->card->device,
- page, 0, PAGE_SIZE, direction);
- if (dma_mapping_error(ctx->pages[i]))
- goto fail_mapping;
+ int i, j, retval = -ENOMEM;
+ dma_addr_t address;
+
+ buffer->page_count = page_count;
+ buffer->direction = direction;
+
+ buffer->pages = kmalloc(page_count * sizeof(buffer->pages[0]),
+ GFP_KERNEL);
+ if (buffer->pages == NULL)
+ goto out;
+
+ for (i = 0; i < buffer->page_count; i++) {
+ buffer->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
+ if (buffer->pages[i] == NULL)
+ goto out_pages;
+
+ address = dma_map_page(card->device, buffer->pages[i],
+ 0, PAGE_SIZE, direction);
+ if (dma_mapping_error(address)) {
+ __free_page(buffer->pages[i]);
+ goto out_pages;
+ }
+ set_page_private(buffer->pages[i], address);