struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
                                          int flags);
+struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
+                                         int flags);
 
                                buf += 3;
                                while (isspace(*buf))
                                        ++buf;
-                               pnp_res = pnp_get_pnp_resource(dev,
-                                               IORESOURCE_DMA, ndma);
-                               if (!pnp_res)
-                                       break;
-                               pnp_res->index = ndma;
-                               res = &pnp_res->res;
-                               res->start = res->end =
-                                   simple_strtoul(buf, &buf, 0);
-                               res->flags = IORESOURCE_DMA;
-                               ndma++;
+                               start = simple_strtoul(buf, &buf, 0);
+                               pnp_res = pnp_add_dma_resource(dev, start, 0);
+                               if (pnp_res)
+                                       pnp_res->index = ndma++;
                                continue;
                        }
                        break;
 
                        ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
                        if (ret == 4)
                                continue;
-                       pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA,
-                                                      tmp);
-                       pnp_res->index = tmp;
-                       res = &pnp_res->res;
-                       res->start = res->end = ret;
-                       res->flags = IORESOURCE_DMA;
+                       pnp_res = pnp_add_dma_resource(dev, ret, 0);
+                       if  (pnp_res)
+                               pnp_res->index = tmp;
                }
        }
        return 0;
 
        return flags;
 }
 
-static void pnpacpi_parse_allocated_dmaresource(struct pnp_dev *dev,
-                                               u32 dma, int flags)
-{
-       struct resource *res;
-       int i;
-       static unsigned char warned;
-
-       for (i = 0; i < PNP_MAX_DMA; i++) {
-               res = pnp_get_resource(dev, IORESOURCE_DMA, i);
-               if (!pnp_resource_valid(res))
-                       break;
-       }
-       if (i < PNP_MAX_DMA) {
-               res->flags = IORESOURCE_DMA;    // Also clears _UNSET flag
-               res->flags |= flags;
-               if (dma == -1) {
-                       res->flags |= IORESOURCE_DISABLED;
-                       return;
-               }
-               res->start = dma;
-               res->end = dma;
-       } else if (!warned) {
-               printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA "
-                               "resources: %d \n", PNP_MAX_DMA);
-               warned = 1;
-       }
-}
-
 static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev,
                                               u64 io, u64 len, int io_decode)
 {
        struct acpi_resource_memory32 *memory32;
        struct acpi_resource_fixed_memory32 *fixed_memory32;
        struct acpi_resource_extended_irq *extended_irq;
-       int i;
+       int i, flags;
 
        switch (res->type) {
        case ACPI_RESOURCE_TYPE_IRQ:
 
        case ACPI_RESOURCE_TYPE_DMA:
                dma = &res->data.dma;
-               if (dma->channel_count > 0)
-                       pnpacpi_parse_allocated_dmaresource(dev,
-                               dma->channels[0],
-                               dma_flags(dma->type, dma->bus_master,
-                                         dma->transfer));
+               if (dma->channel_count > 0) {
+                       flags = dma_flags(dma->type, dma->bus_master,
+                                         dma->transfer);
+                       if (dma->channels[0] == (u8) -1)
+                               flags |= IORESOURCE_DISABLED;
+                       pnp_add_dma_resource(dev, dma->channels[0], flags);
+               }
                break;
 
        case ACPI_RESOURCE_TYPE_IO:
 
  * Allocated Resources
  */
 
-static void pnpbios_parse_allocated_dmaresource(struct pnp_dev *dev, int dma)
-{
-       struct resource *res;
-       int i;
-
-       for (i = 0; i < PNP_MAX_DMA; i++) {
-               res = pnp_get_resource(dev, IORESOURCE_DMA, i);
-               if (!pnp_resource_valid(res))
-                       break;
-       }
-
-       if (i < PNP_MAX_DMA) {
-               res->flags = IORESOURCE_DMA;    // Also clears _UNSET flag
-               if (dma == -1) {
-                       res->flags |= IORESOURCE_DISABLED;
-                       return;
-               }
-               res->start = res->end = (unsigned long)dma;
-       }
-}
-
 static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev,
                                               int io, int len)
 {
                case SMALL_TAG_DMA:
                        if (len != 2)
                                goto len_err;
+                       flags = 0;
                        io = -1;
                        mask = p[1];
                        for (i = 0; i < 8; i++, mask = mask >> 1)
                                if (mask & 0x01)
                                        io = i;
-                       pnpbios_parse_allocated_dmaresource(dev, io);
+                       if (io == -1)
+                               flags = IORESOURCE_DISABLED;
+                       pnp_add_dma_resource(dev, io, flags);
                        break;
 
                case SMALL_TAG_PORT:
 
        return pnp_res;
 }
 
+struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
+                                         int flags)
+{
+       struct pnp_resource *pnp_res;
+       struct resource *res;
+       static unsigned char warned;
+
+       pnp_res = pnp_new_resource(dev, IORESOURCE_DMA);
+       if (!pnp_res) {
+               if (!warned) {
+                       dev_err(&dev->dev, "can't add resource for DMA %d\n",
+                               dma);
+                       warned = 1;
+               }
+               return NULL;
+       }
+
+       res = &pnp_res->res;
+       res->flags = IORESOURCE_DMA | flags;
+       res->start = dma;
+       res->end = dma;
+
+       dev_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
+       return pnp_res;
+}
+
 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
 static int __init pnp_setup_reserve_irq(char *str)
 {