Commit ccc4c7bb authored by Vojtech Pavlik's avatar Vojtech Pavlik Committed by Greg Kroah-Hartman

Fix DMA resource allocation in ACPIPnP

The ACPIPnP implementation had the understanding of Linux resource flags very
wrong, resulting in a nonfunctional implementation of DMA resource
allocation.

This was usually not a problem, since almost no on-board PnP devices use ISA
DMA, with the exception of ECP parallel ports. Even with that, parallel port
DMA is preconfigured by the BIOS, so this routine isn't normally called.

Except in the case where somebody does 'rmmod parport_pc; modprobe
parport_pc', where the rmmod case disables the ECP parallel port resources,
and they need to be enabled again to initialize the module. This didn't
work, resulting in a non-printing printer.

The application doing exactly the above to force reprobing of printers is
the YaST printer module. Thus without this fix YaST wedged the printer when
configuring it, and was not able to print a test page.
Reported-by: default avatarRalf Flaxa <rf@suse.de>
Reproduced-by: default avatarJiri Dluhos <jdluhos@suse.cz>
Signed-off-by: default avatarVojtech Pavlik <vojtech@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b5e4efe7
......@@ -776,21 +776,32 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource,
struct resource *p)
{
/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
if (p->flags & IORESOURCE_DMA_COMPATIBLE)
resource->data.dma.type = ACPI_COMPATIBILITY;
else if (p->flags & IORESOURCE_DMA_TYPEA)
switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
case IORESOURCE_DMA_TYPEA:
resource->data.dma.type = ACPI_TYPE_A;
else if (p->flags & IORESOURCE_DMA_TYPEB)
break;
case IORESOURCE_DMA_TYPEB:
resource->data.dma.type = ACPI_TYPE_B;
else if (p->flags & IORESOURCE_DMA_TYPEF)
break;
case IORESOURCE_DMA_TYPEF:
resource->data.dma.type = ACPI_TYPE_F;
if (p->flags & IORESOURCE_DMA_8BIT)
break;
default:
resource->data.dma.type = ACPI_COMPATIBILITY;
}
switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
case IORESOURCE_DMA_8BIT:
resource->data.dma.transfer = ACPI_TRANSFER_8;
else if (p->flags & IORESOURCE_DMA_8AND16BIT)
break;
case IORESOURCE_DMA_8AND16BIT:
resource->data.dma.transfer = ACPI_TRANSFER_8_16;
else if (p->flags & IORESOURCE_DMA_16BIT)
break;
default:
resource->data.dma.transfer = ACPI_TRANSFER_16;
resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER;
}
resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
resource->data.dma.channel_count = 1;
resource->data.dma.channels[0] = p->start;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment