int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction) { unsigned int i; /* round up to page size */ n_bytes = PAGE_ALIGN(n_bytes); dma->n_pages = n_bytes >> PAGE_SHIFT; dma->kvirt = vmalloc_32(n_bytes); if (!dma->kvirt) { printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n"); goto err; } /* Clear the ram out, no junk to the user */ memset(dma->kvirt, 0, n_bytes); /* allocate scatter/gather list */ dma->sglist = vmalloc(dma->n_pages * sizeof(*dma->sglist)); if (!dma->sglist) { printk(KERN_ERR "dma_region_alloc: vmalloc(sglist) failed\n"); goto err; } /* just to be safe - this will become unnecessary once sglist->address goes away */ memset(dma->sglist, 0, dma->n_pages * sizeof(*dma->sglist)); /* fill scatter/gather list with pages */ for (i = 0; i < dma->n_pages; i++) { unsigned long va = (unsigned long)dma->kvirt + (i << PAGE_SHIFT); dma->sglist[i].page = vmalloc_to_page((void *)va); dma->sglist[i].length = PAGE_SIZE; } /* map sglist to the IOMMU */ dma->n_dma_pages = pci_map_sg(dev, dma->sglist, dma->n_pages, direction); if (dma->n_dma_pages == 0) { printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n"); goto err; } dma->dev = dev; dma->direction = direction; return 0; err: dma_region_free(dma); return -ENOMEM; }
void hpsb_iso_shutdown(struct hpsb_iso *iso) { if (iso->flags & HPSB_ISO_DRIVER_INIT) { hpsb_iso_stop(iso); iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ? XMIT_SHUTDOWN : RECV_SHUTDOWN, 0); iso->flags &= ~HPSB_ISO_DRIVER_INIT; } dma_region_free(&iso->data_buf); kfree(iso); }