[BACK]Return to xen_bus_dma.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / xen / x86

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/xen/x86/xen_bus_dma.c between version 1.8.6.1 and 1.9

version 1.8.6.1, 2010/06/13 05:48:58 version 1.9, 2007/02/24 21:19:25
Line 69  static inline int get_order(unsigned lon
Line 69  static inline int get_order(unsigned lon
   
 static int  static int
 _xen_alloc_contig(bus_size_t size, bus_size_t alignment, bus_size_t boundary,  _xen_alloc_contig(bus_size_t size, bus_size_t alignment, bus_size_t boundary,
     struct pglist *mlistp, int flags)      struct pglist *mlistp, int flags, bus_addr_t low, bus_addr_t high)
 {  {
         int order, i;          int order, i;
         unsigned long npagesreq, npages, mfn;          unsigned long npagesreq, npages, mfn;
Line 106  _xen_alloc_contig(bus_size_t size, bus_s
Line 106  _xen_alloc_contig(bus_size_t size, bus_s
                 res.extent_start = &mfn;                  res.extent_start = &mfn;
                 res.nr_extents = 1;                  res.nr_extents = 1;
                 res.extent_order = 0;                  res.extent_order = 0;
                 res.address_bits = 0;  
                 res.domid = DOMID_SELF;                  res.domid = DOMID_SELF;
                 if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, &res)                  if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, &res)
                     < 0) {                      < 0) {
Line 139  _xen_alloc_contig(bus_size_t size, bus_s
Line 138  _xen_alloc_contig(bus_size_t size, bus_s
         res.extent_start = &mfn;          res.extent_start = &mfn;
         res.nr_extents = 1;          res.nr_extents = 1;
         res.extent_order = order;          res.extent_order = order;
         res.address_bits = 31;          res.address_bits = get_order(high) + PAGE_SHIFT;
         res.domid = DOMID_SELF;          res.domid = DOMID_SELF;
         if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res) < 0) {          if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res) < 0) {
 #ifdef DEBUG  #ifdef DEBUG
Line 206  failed:
Line 205  failed:
                 res.extent_start = &mfn;                  res.extent_start = &mfn;
                 res.nr_extents = 1;                  res.nr_extents = 1;
                 res.extent_order = 0;                  res.extent_order = 0;
                 res.address_bits = 31;                  res.address_bits = 32;
                 res.domid = DOMID_SELF;                  res.domid = DOMID_SELF;
                 if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res)                  if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res)
                     < 0) {                      < 0) {
Line 278  again:
Line 277  again:
          */           */
         m = mlist.tqh_first;          m = mlist.tqh_first;
         curseg = 0;          curseg = 0;
         lastaddr = segs[curseg].ds_addr = _BUS_VM_PAGE_TO_BUS(m);          curaddr = lastaddr = segs[curseg].ds_addr = _BUS_VM_PAGE_TO_BUS(m);
           if (curaddr < low || curaddr >= high)
                   goto badaddr;
         segs[curseg].ds_len = PAGE_SIZE;          segs[curseg].ds_len = PAGE_SIZE;
         m = m->pageq.tqe_next;          m = m->pageq.tqe_next;
         if ((segs[curseg].ds_addr & (alignment - 1)) != 0)          if ((segs[curseg].ds_addr & (alignment - 1)) != 0)
Line 286  again:
Line 287  again:
   
         for (; m != NULL; m = m->pageq.tqe_next) {          for (; m != NULL; m = m->pageq.tqe_next) {
                 curaddr = _BUS_VM_PAGE_TO_BUS(m);                  curaddr = _BUS_VM_PAGE_TO_BUS(m);
                 if ((lastaddr < low || lastaddr >= high) ||                  if (curaddr < low || curaddr >= high)
                     (curaddr < low || curaddr >= high)) {                          goto badaddr;
                         /*  
                          * If machine addresses are outside the allowed  
                          * range we have to bail. Xen2 doesn't offer an  
                          * interface to get memory in a specific address  
                          * range.  
                          */  
                         printf("_xen_bus_dmamem_alloc_range: no way to "  
                             "enforce address range\n");  
                         uvm_pglistfree(&mlist);  
                         return EINVAL;  
                 }  
                 if (curaddr == (lastaddr + PAGE_SIZE)) {                  if (curaddr == (lastaddr + PAGE_SIZE)) {
                         segs[curseg].ds_len += PAGE_SIZE;                          segs[curseg].ds_len += PAGE_SIZE;
                         if ((lastaddr & boundary) !=                          if ((lastaddr & boundary) != (curaddr & boundary))
                             (curaddr & boundary))  
                                 goto dorealloc;                                  goto dorealloc;
                 } else {                  } else {
                         curseg++;                          curseg++;
                         if (curseg >= nsegs ||                          if (curseg >= nsegs || (curaddr & (alignment - 1)) != 0)
                             (curaddr & (alignment - 1)) != 0) {                                  goto dorealloc;
 dorealloc:  
                                 if (doingrealloc == 1)  
                                         panic("_xen_bus_dmamem_alloc_range: "  
                                            "xen_alloc_contig returned "  
                                            "too much segments");  
                                 doingrealloc = 1;  
                                 /*  
                                  * Too much segments. Free this memory and  
                                  * get a contigous segment from the hypervisor.  
                                  */  
                                 uvm_pglistfree(&mlist);  
                                 for (curseg = 0; curseg < nsegs; curseg++) {  
                                         segs[curseg].ds_addr = 0;  
                                         segs[curseg].ds_len = 0;  
                                 }  
                                 error = _xen_alloc_contig(size, alignment,  
                                     boundary, &mlist, flags);  
                                 if (error)  
                                         return error;  
                                 goto again;  
                         }  
                         segs[curseg].ds_addr = curaddr;                          segs[curseg].ds_addr = curaddr;
                         segs[curseg].ds_len = PAGE_SIZE;                          segs[curseg].ds_len = PAGE_SIZE;
                 }                  }
Line 336  dorealloc:
Line 304  dorealloc:
         }          }
   
         *rsegs = curseg + 1;          *rsegs = curseg + 1;
   
         return (0);          return (0);
   
   badaddr:
   #ifdef XEN3
           if (doingrealloc == 0)
                   goto dorealloc;
           if (curaddr < low) {
                   /* no way to enforce this */
                   printf("_xen_bus_dmamem_alloc_range: no way to "
                       "enforce address range\n");
                   uvm_pglistfree(&mlist);
                   return EINVAL;
           }
           printf("xen_bus_dmamem_alloc_range: "
               "curraddr=0x%lx > high=0x%lx\n",
               (u_long)curaddr, (u_long)high);
           panic("xen_bus_dmamem_alloc_range 1");
   #else /* !XEN3 */
           /*
            * If machine addresses are outside the allowed
            * range we have to bail. Xen2 doesn't offer an
            * interface to get memory in a specific address
            * range.
            */
           printf("_xen_bus_dmamem_alloc_range: no way to "
               "enforce address range\n");
           uvm_pglistfree(&mlist);
           return EINVAL;
   #endif /* XEN3 */
   dorealloc:
           if (doingrealloc == 1)
                   panic("_xen_bus_dmamem_alloc_range: "
                      "xen_alloc_contig returned "
                      "too much segments");
           doingrealloc = 1;
           /*
            * Too much segments, or memory doesn't fit
            * constraints. Free this memory and
            * get a contigous segment from the hypervisor.
            */
           uvm_pglistfree(&mlist);
           for (curseg = 0; curseg < nsegs; curseg++) {
                   segs[curseg].ds_addr = 0;
                   segs[curseg].ds_len = 0;
           }
           error = _xen_alloc_contig(size, alignment,
               boundary, &mlist, flags, low, high);
           if (error)
                   return error;
           goto again;
 }  }

Legend:
Removed from v.1.8.6.1  
changed lines
  Added in v.1.9

CVSweb <webmaster@jp.NetBSD.org>