rsparser.c 26.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/*
 * pnpacpi -- PnP ACPI driver
 *
 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
B
Bob Moore 已提交
6
 *
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include "pnpacpi.h"

#ifdef CONFIG_IA64
#define valid_IRQ(i) (1)
#else
#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
#endif

/*
 * Allocated Resources
 */
B
Bob Moore 已提交
35
static int irq_flags(int triggering, int polarity)
L
Linus Torvalds 已提交
36
{
B
Bob Moore 已提交
37
	if (triggering == ACPI_LEVEL_SENSITIVE) {
B
Bjorn Helgaas 已提交
38
		if (polarity == ACPI_ACTIVE_LOW)
B
Bjorn Helgaas 已提交
39
			return IORESOURCE_IRQ_LOWLEVEL;
L
Linus Torvalds 已提交
40
		else
B
Bjorn Helgaas 已提交
41
			return IORESOURCE_IRQ_HIGHLEVEL;
B
Bjorn Helgaas 已提交
42
	} else {
B
Bjorn Helgaas 已提交
43
		if (polarity == ACPI_ACTIVE_LOW)
B
Bjorn Helgaas 已提交
44
			return IORESOURCE_IRQ_LOWEDGE;
L
Linus Torvalds 已提交
45
		else
B
Bjorn Helgaas 已提交
46
			return IORESOURCE_IRQ_HIGHEDGE;
L
Linus Torvalds 已提交
47 48 49
	}
}

B
Bob Moore 已提交
50
static void decode_irq_flags(int flag, int *triggering, int *polarity)
L
Linus Torvalds 已提交
51 52 53
{
	switch (flag) {
	case IORESOURCE_IRQ_LOWLEVEL:
B
Bob Moore 已提交
54 55
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
56
		break;
B
Bjorn Helgaas 已提交
57
	case IORESOURCE_IRQ_HIGHLEVEL:
B
Bob Moore 已提交
58 59
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
60 61
		break;
	case IORESOURCE_IRQ_LOWEDGE:
B
Bob Moore 已提交
62 63
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
64 65
		break;
	case IORESOURCE_IRQ_HIGHEDGE:
B
Bob Moore 已提交
66 67
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
68 69 70 71
		break;
	}
}

B
Bjorn Helgaas 已提交
72 73 74
static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
						u32 gsi, int triggering,
						int polarity, int shareable)
L
Linus Torvalds 已提交
75 76
{
	int i = 0;
77
	int irq;
78
	int p, t;
79
	static unsigned char warned;
80 81 82 83

	if (!valid_IRQ(gsi))
		return;

L
Linus Torvalds 已提交
84
	while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
85
	       i < PNP_MAX_IRQ)
L
Linus Torvalds 已提交
86
		i++;
87
	if (i >= PNP_MAX_IRQ && !warned) {
88 89
		printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ "
				"resources: %d \n", PNP_MAX_IRQ);
90
		warned = 1;
91
		return;
92
	}
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
	/*
	 * in IO-APIC mode, use overrided attribute. Two reasons:
	 * 1. BIOS bug in DSDT
	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
	 */
	if (!acpi_get_override_irq(gsi, &t, &p)) {
		t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
		p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;

		if (triggering != t || polarity != p) {
			pnp_warn("IRQ %d override to %s, %s",
				gsi, t ? "edge":"level", p ? "low":"high");
			triggering = t;
			polarity = p;
		}
	}

B
Bjorn Helgaas 已提交
110
	res->irq_resource[i].flags = IORESOURCE_IRQ;	// Also clears _UNSET flag
111
	res->irq_resource[i].flags |= irq_flags(triggering, polarity);
B
Bob Moore 已提交
112
	irq = acpi_register_gsi(gsi, triggering, polarity);
113 114 115
	if (irq < 0) {
		res->irq_resource[i].flags |= IORESOURCE_DISABLED;
		return;
L
Linus Torvalds 已提交
116
	}
117

118 119 120
	if (shareable)
		res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;

121 122 123
	res->irq_resource[i].start = irq;
	res->irq_resource[i].end = irq;
	pcibios_penalize_isa_irq(irq, 1);
L
Linus Torvalds 已提交
124 125
}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
static int dma_flags(int type, int bus_master, int transfer)
{
	int flags = 0;

	if (bus_master)
		flags |= IORESOURCE_DMA_MASTER;
	switch (type) {
	case ACPI_COMPATIBILITY:
		flags |= IORESOURCE_DMA_COMPATIBLE;
		break;
	case ACPI_TYPE_A:
		flags |= IORESOURCE_DMA_TYPEA;
		break;
	case ACPI_TYPE_B:
		flags |= IORESOURCE_DMA_TYPEB;
		break;
	case ACPI_TYPE_F:
		flags |= IORESOURCE_DMA_TYPEF;
		break;
	default:
		/* Set a default value ? */
		flags |= IORESOURCE_DMA_COMPATIBLE;
		pnp_err("Invalid DMA type");
	}
	switch (transfer) {
	case ACPI_TRANSFER_8:
		flags |= IORESOURCE_DMA_8BIT;
		break;
	case ACPI_TRANSFER_8_16:
		flags |= IORESOURCE_DMA_8AND16BIT;
		break;
	case ACPI_TRANSFER_16:
		flags |= IORESOURCE_DMA_16BIT;
		break;
	default:
		/* Set a default value ? */
		flags |= IORESOURCE_DMA_8AND16BIT;
		pnp_err("Invalid DMA transfer type");
	}

	return flags;
}

B
Bjorn Helgaas 已提交
169 170 171
static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
						u32 dma, int type,
						int bus_master, int transfer)
L
Linus Torvalds 已提交
172 173
{
	int i = 0;
174
	static unsigned char warned;
B
Bjorn Helgaas 已提交
175

176
	while (i < PNP_MAX_DMA &&
B
Bjorn Helgaas 已提交
177
	       !(res->dma_resource[i].flags & IORESOURCE_UNSET))
L
Linus Torvalds 已提交
178 179
		i++;
	if (i < PNP_MAX_DMA) {
B
Bjorn Helgaas 已提交
180 181 182
		res->dma_resource[i].flags = IORESOURCE_DMA;	// Also clears _UNSET flag
		res->dma_resource[i].flags |=
		    dma_flags(type, bus_master, transfer);
L
Linus Torvalds 已提交
183 184 185 186
		if (dma == -1) {
			res->dma_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
187 188
		res->dma_resource[i].start = dma;
		res->dma_resource[i].end = dma;
189
	} else if (!warned) {
190 191
		printk(KERN_ERR "pnpacpi: exceeded the max number of DMA "
				"resources: %d \n", PNP_MAX_DMA);
192
		warned = 1;
L
Linus Torvalds 已提交
193 194 195
	}
}

B
Bjorn Helgaas 已提交
196 197
static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
					       u64 io, u64 len, int io_decode)
L
Linus Torvalds 已提交
198 199
{
	int i = 0;
200
	static unsigned char warned;
B
Bjorn Helgaas 已提交
201

L
Linus Torvalds 已提交
202
	while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
203
	       i < PNP_MAX_PORT)
L
Linus Torvalds 已提交
204 205
		i++;
	if (i < PNP_MAX_PORT) {
B
Bjorn Helgaas 已提交
206
		res->port_resource[i].flags = IORESOURCE_IO;	// Also clears _UNSET flag
207 208
		if (io_decode == ACPI_DECODE_16)
			res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
B
Bjorn Helgaas 已提交
209
		if (len <= 0 || (io + len - 1) >= 0x10003) {
L
Linus Torvalds 已提交
210 211 212
			res->port_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
213 214
		res->port_resource[i].start = io;
		res->port_resource[i].end = io + len - 1;
215
	} else if (!warned) {
216 217
		printk(KERN_ERR "pnpacpi: exceeded the max number of IO "
				"resources: %d \n", PNP_MAX_PORT);
218
		warned = 1;
L
Linus Torvalds 已提交
219 220 221
	}
}

B
Bjorn Helgaas 已提交
222 223 224
static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
						u64 mem, u64 len,
						int write_protect)
L
Linus Torvalds 已提交
225 226
{
	int i = 0;
227
	static unsigned char warned;
B
Bjorn Helgaas 已提交
228

L
Linus Torvalds 已提交
229
	while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
230
	       (i < PNP_MAX_MEM))
L
Linus Torvalds 已提交
231 232
		i++;
	if (i < PNP_MAX_MEM) {
B
Bjorn Helgaas 已提交
233
		res->mem_resource[i].flags = IORESOURCE_MEM;	// Also clears _UNSET flag
L
Linus Torvalds 已提交
234 235 236 237
		if (len <= 0) {
			res->mem_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
B
Bjorn Helgaas 已提交
238
		if (write_protect == ACPI_READ_WRITE_MEMORY)
239 240
			res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;

241 242
		res->mem_resource[i].start = mem;
		res->mem_resource[i].end = mem + len - 1;
243
	} else if (!warned) {
244 245
		printk(KERN_ERR "pnpacpi: exceeded the max number of mem "
				"resources: %d\n", PNP_MAX_MEM);
246
		warned = 1;
L
Linus Torvalds 已提交
247 248 249
	}
}

B
Bjorn Helgaas 已提交
250 251
static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
						  struct acpi_resource *res)
252 253 254 255 256 257 258
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;

	status = acpi_resource_to_address64(res, p);
	if (!ACPI_SUCCESS(status)) {
		pnp_warn("PnPACPI: failed to convert resource type %d",
B
Bjorn Helgaas 已提交
259
			 res->type);
260 261 262
		return;
	}

263 264 265
	if (p->producer_consumer == ACPI_PRODUCER)
		return;

266 267
	if (p->resource_type == ACPI_MEMORY_RANGE)
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
268 269
			p->minimum, p->address_length,
			p->info.mem.write_protect);
270 271
	else if (p->resource_type == ACPI_IO_RANGE)
		pnpacpi_parse_allocated_ioresource(res_table,
B
Bjorn Helgaas 已提交
272 273 274
			p->minimum, p->address_length,
			p->granularity == 0xfff ? ACPI_DECODE_10 :
				ACPI_DECODE_16);
275
}
L
Linus Torvalds 已提交
276 277

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
278
					      void *data)
L
Linus Torvalds 已提交
279
{
280
	struct pnp_resource_table *res_table = data;
281
	int i;
L
Linus Torvalds 已提交
282

283
	switch (res->type) {
B
Bob Moore 已提交
284
	case ACPI_RESOURCE_TYPE_IRQ:
285 286 287 288
		/*
		 * Per spec, only one interrupt per descriptor is allowed in
		 * _CRS, but some firmware violates this, so parse them all.
		 */
B
Bob Moore 已提交
289
		for (i = 0; i < res->data.irq.interrupt_count; i++) {
290
			pnpacpi_parse_allocated_irqresource(res_table,
B
Bjorn Helgaas 已提交
291 292 293 294
				res->data.irq.interrupts[i],
				res->data.irq.triggering,
				res->data.irq.polarity,
				res->data.irq.sharable);
L
Linus Torvalds 已提交
295 296 297
		}
		break;

B
Bob Moore 已提交
298 299 300
	case ACPI_RESOURCE_TYPE_DMA:
		if (res->data.dma.channel_count > 0)
			pnpacpi_parse_allocated_dmaresource(res_table,
B
Bjorn Helgaas 已提交
301 302 303 304
				res->data.dma.channels[0],
				res->data.dma.type,
				res->data.dma.bus_master,
				res->data.dma.transfer);
L
Linus Torvalds 已提交
305
		break;
306

B
Bob Moore 已提交
307 308
	case ACPI_RESOURCE_TYPE_IO:
		pnpacpi_parse_allocated_ioresource(res_table,
B
Bjorn Helgaas 已提交
309 310 311
			res->data.io.minimum,
			res->data.io.address_length,
			res->data.io.io_decode);
L
Linus Torvalds 已提交
312
		break;
313 314 315 316 317

	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		break;

B
Bob Moore 已提交
318 319
	case ACPI_RESOURCE_TYPE_FIXED_IO:
		pnpacpi_parse_allocated_ioresource(res_table,
B
Bjorn Helgaas 已提交
320 321 322
			res->data.fixed_io.address,
			res->data.fixed_io.address_length,
			ACPI_DECODE_10);
L
Linus Torvalds 已提交
323
		break;
324 325 326 327 328 329 330

	case ACPI_RESOURCE_TYPE_VENDOR:
		break;

	case ACPI_RESOURCE_TYPE_END_TAG:
		break;

B
Bob Moore 已提交
331 332
	case ACPI_RESOURCE_TYPE_MEMORY24:
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
333 334 335
			res->data.memory24.minimum,
			res->data.memory24.address_length,
			res->data.memory24.write_protect);
L
Linus Torvalds 已提交
336
		break;
B
Bob Moore 已提交
337 338
	case ACPI_RESOURCE_TYPE_MEMORY32:
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
339 340 341
			res->data.memory32.minimum,
			res->data.memory32.address_length,
			res->data.memory32.write_protect);
L
Linus Torvalds 已提交
342
		break;
B
Bob Moore 已提交
343 344
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
345 346 347
			res->data.fixed_memory32.address,
			res->data.fixed_memory32.address_length,
			res->data.fixed_memory32.write_protect);
L
Linus Torvalds 已提交
348
		break;
B
Bob Moore 已提交
349 350 351
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
352
		pnpacpi_parse_allocated_address_space(res_table, res);
L
Linus Torvalds 已提交
353
		break;
354 355

	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
356 357
		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
			return AE_OK;
358 359 360
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
361 362 363
		if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER)
			return AE_OK;

364 365
		for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
			pnpacpi_parse_allocated_irqresource(res_table,
B
Bjorn Helgaas 已提交
366 367 368 369
				res->data.extended_irq.interrupts[i],
				res->data.extended_irq.triggering,
				res->data.extended_irq.polarity,
				res->data.extended_irq.sharable);
370 371 372 373
		}
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
L
Linus Torvalds 已提交
374
		break;
375

L
Linus Torvalds 已提交
376
	default:
377
		pnp_warn("PnPACPI: unknown resource type %d", res->type);
L
Linus Torvalds 已提交
378 379
		return AE_ERROR;
	}
B
Bjorn Helgaas 已提交
380

L
Linus Torvalds 已提交
381 382 383
	return AE_OK;
}

B
Bjorn Helgaas 已提交
384 385
acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle,
					     struct pnp_resource_table * res)
L
Linus Torvalds 已提交
386 387 388 389
{
	/* Blank the resource table values */
	pnp_init_resource_table(res);

B
Bjorn Helgaas 已提交
390 391
	return acpi_walk_resources(handle, METHOD_NAME__CRS,
				   pnpacpi_allocated_resource, res);
L
Linus Torvalds 已提交
392 393
}

394 395
static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
					    struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
396 397
{
	int i;
B
Bjorn Helgaas 已提交
398
	struct pnp_dma *dma;
L
Linus Torvalds 已提交
399

B
Bob Moore 已提交
400
	if (p->channel_count == 0)
L
Linus Torvalds 已提交
401
		return;
402
	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
L
Linus Torvalds 已提交
403 404 405
	if (!dma)
		return;

B
Bjorn Helgaas 已提交
406
	for (i = 0; i < p->channel_count; i++)
L
Linus Torvalds 已提交
407
		dma->map |= 1 << p->channels[i];
408 409

	dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
L
Linus Torvalds 已提交
410

B
Bjorn Helgaas 已提交
411
	pnp_register_dma_resource(option, dma);
L
Linus Torvalds 已提交
412 413
}

414 415
static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
					    struct acpi_resource_irq *p)
L
Linus Torvalds 已提交
416 417
{
	int i;
B
Bjorn Helgaas 已提交
418 419
	struct pnp_irq *irq;

B
Bob Moore 已提交
420
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
421
		return;
422
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
423 424 425
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
426
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
427 428
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
B
Bob Moore 已提交
429
	irq->flags = irq_flags(p->triggering, p->polarity);
L
Linus Torvalds 已提交
430 431 432 433

	pnp_register_irq_resource(option, irq);
}

434 435
static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
					struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
436 437
{
	int i;
B
Bjorn Helgaas 已提交
438
	struct pnp_irq *irq;
L
Linus Torvalds 已提交
439

B
Bob Moore 已提交
440
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
441
		return;
442
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
443 444 445
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
446
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
447 448
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
B
Bob Moore 已提交
449
	irq->flags = irq_flags(p->triggering, p->polarity);
L
Linus Torvalds 已提交
450 451 452 453

	pnp_register_irq_resource(option, irq);
}

454 455
static __init void pnpacpi_parse_port_option(struct pnp_option *option,
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
456
{
B
Bjorn Helgaas 已提交
457
	struct pnp_port *port;
L
Linus Torvalds 已提交
458

B
Bob Moore 已提交
459
	if (io->address_length == 0)
L
Linus Torvalds 已提交
460
		return;
461
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
462 463
	if (!port)
		return;
B
Bob Moore 已提交
464 465
	port->min = io->minimum;
	port->max = io->maximum;
L
Linus Torvalds 已提交
466
	port->align = io->alignment;
B
Bob Moore 已提交
467 468
	port->size = io->address_length;
	port->flags = ACPI_DECODE_16 == io->io_decode ?
B
Bjorn Helgaas 已提交
469
	    PNP_PORT_FLAG_16BITADDR : 0;
B
Bjorn Helgaas 已提交
470
	pnp_register_port_resource(option, port);
L
Linus Torvalds 已提交
471 472
}

473 474
static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
475
{
B
Bjorn Helgaas 已提交
476
	struct pnp_port *port;
L
Linus Torvalds 已提交
477

B
Bob Moore 已提交
478
	if (io->address_length == 0)
L
Linus Torvalds 已提交
479
		return;
480
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
481 482
	if (!port)
		return;
B
Bob Moore 已提交
483 484
	port->min = port->max = io->address;
	port->size = io->address_length;
L
Linus Torvalds 已提交
485 486
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
B
Bjorn Helgaas 已提交
487
	pnp_register_port_resource(option, port);
L
Linus Torvalds 已提交
488 489
}

490 491
static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
492
{
B
Bjorn Helgaas 已提交
493
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
494

B
Bob Moore 已提交
495
	if (p->address_length == 0)
L
Linus Torvalds 已提交
496
		return;
497
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
498 499
	if (!mem)
		return;
B
Bob Moore 已提交
500 501
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
502
	mem->align = p->alignment;
B
Bob Moore 已提交
503
	mem->size = p->address_length;
L
Linus Torvalds 已提交
504

B
Bob Moore 已提交
505
	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
B
Bjorn Helgaas 已提交
506
	    IORESOURCE_MEM_WRITEABLE : 0;
L
Linus Torvalds 已提交
507

B
Bjorn Helgaas 已提交
508
	pnp_register_mem_resource(option, mem);
L
Linus Torvalds 已提交
509 510
}

511 512
static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
513
{
B
Bjorn Helgaas 已提交
514
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
515

B
Bob Moore 已提交
516
	if (p->address_length == 0)
L
Linus Torvalds 已提交
517
		return;
518
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
519 520
	if (!mem)
		return;
B
Bob Moore 已提交
521 522
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
523
	mem->align = p->alignment;
B
Bob Moore 已提交
524
	mem->size = p->address_length;
L
Linus Torvalds 已提交
525

B
Bob Moore 已提交
526
	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
B
Bjorn Helgaas 已提交
527
	    IORESOURCE_MEM_WRITEABLE : 0;
L
Linus Torvalds 已提交
528

B
Bjorn Helgaas 已提交
529
	pnp_register_mem_resource(option, mem);
L
Linus Torvalds 已提交
530 531
}

532 533
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
534
{
B
Bjorn Helgaas 已提交
535
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
536

B
Bob Moore 已提交
537
	if (p->address_length == 0)
L
Linus Torvalds 已提交
538
		return;
539
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
540 541
	if (!mem)
		return;
B
Bob Moore 已提交
542 543
	mem->min = mem->max = p->address;
	mem->size = p->address_length;
L
Linus Torvalds 已提交
544 545
	mem->align = 0;

B
Bob Moore 已提交
546
	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
B
Bjorn Helgaas 已提交
547
	    IORESOURCE_MEM_WRITEABLE : 0;
L
Linus Torvalds 已提交
548

B
Bjorn Helgaas 已提交
549
	pnp_register_mem_resource(option, mem);
L
Linus Torvalds 已提交
550 551
}

552 553
static __init void pnpacpi_parse_address_option(struct pnp_option *option,
						struct acpi_resource *r)
554 555 556
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
B
Bjorn Helgaas 已提交
557 558
	struct pnp_mem *mem;
	struct pnp_port *port;
559 560 561

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
562 563
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
564 565 566 567 568 569 570
		return;
	}

	if (p->address_length == 0)
		return;

	if (p->resource_type == ACPI_MEMORY_RANGE) {
571
		mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
572 573
		if (!mem)
			return;
L
Len Brown 已提交
574
		mem->min = mem->max = p->minimum;
575 576
		mem->size = p->address_length;
		mem->align = 0;
L
Len Brown 已提交
577
		mem->flags = (p->info.mem.write_protect ==
B
Bjorn Helgaas 已提交
578 579
			      ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
		    : 0;
B
Bjorn Helgaas 已提交
580
		pnp_register_mem_resource(option, mem);
581
	} else if (p->resource_type == ACPI_IO_RANGE) {
582
		port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
583 584
		if (!port)
			return;
L
Len Brown 已提交
585
		port->min = port->max = p->minimum;
586 587 588
		port->size = p->address_length;
		port->align = 0;
		port->flags = PNP_PORT_FLAG_FIXED;
B
Bjorn Helgaas 已提交
589
		pnp_register_port_resource(option, port);
590 591 592
	}
}

L
Linus Torvalds 已提交
593 594
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
595
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
596 597 598
	struct pnp_dev *dev;
};

599 600
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
						  void *data)
L
Linus Torvalds 已提交
601 602
{
	int priority = 0;
603
	struct acpipnp_parse_option_s *parse_data = data;
L
Linus Torvalds 已提交
604 605 606
	struct pnp_dev *dev = parse_data->dev;
	struct pnp_option *option = parse_data->option;

607
	switch (res->type) {
B
Bjorn Helgaas 已提交
608 609 610
	case ACPI_RESOURCE_TYPE_IRQ:
		pnpacpi_parse_irq_option(option, &res->data.irq);
		break;
611

B
Bjorn Helgaas 已提交
612 613 614
	case ACPI_RESOURCE_TYPE_DMA:
		pnpacpi_parse_dma_option(option, &res->data.dma);
		break;
615

B
Bjorn Helgaas 已提交
616 617 618 619
	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
		switch (res->data.start_dpf.compatibility_priority) {
		case ACPI_GOOD_CONFIGURATION:
			priority = PNP_RES_PRIORITY_PREFERRED;
L
Linus Torvalds 已提交
620
			break;
621

B
Bjorn Helgaas 已提交
622 623
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
624
			break;
625

B
Bjorn Helgaas 已提交
626 627
		case ACPI_SUB_OPTIMAL_CONFIGURATION:
			priority = PNP_RES_PRIORITY_FUNCTIONAL;
628
			break;
B
Bjorn Helgaas 已提交
629 630
		default:
			priority = PNP_RES_PRIORITY_INVALID;
631
			break;
B
Bjorn Helgaas 已提交
632
		}
B
Bjorn Helgaas 已提交
633
		/* TBD: Consider performance/robustness bits */
B
Bjorn Helgaas 已提交
634 635 636 637 638
		option = pnp_register_dependent_option(dev, priority);
		if (!option)
			return AE_ERROR;
		parse_data->option = option;
		break;
639

B
Bjorn Helgaas 已提交
640 641 642 643 644 645 646 647 648
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		/*only one EndDependentFn is allowed */
		if (!parse_data->option_independent) {
			pnp_warn("PnPACPI: more than one EndDependentFn");
			return AE_ERROR;
		}
		parse_data->option = parse_data->option_independent;
		parse_data->option_independent = NULL;
		break;
649

B
Bjorn Helgaas 已提交
650 651 652
	case ACPI_RESOURCE_TYPE_IO:
		pnpacpi_parse_port_option(option, &res->data.io);
		break;
653

B
Bjorn Helgaas 已提交
654 655 656
	case ACPI_RESOURCE_TYPE_FIXED_IO:
		pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io);
		break;
657

B
Bjorn Helgaas 已提交
658 659 660
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
661

B
Bjorn Helgaas 已提交
662 663 664
	case ACPI_RESOURCE_TYPE_MEMORY24:
		pnpacpi_parse_mem24_option(option, &res->data.memory24);
		break;
665

B
Bjorn Helgaas 已提交
666 667 668
	case ACPI_RESOURCE_TYPE_MEMORY32:
		pnpacpi_parse_mem32_option(option, &res->data.memory32);
		break;
669

B
Bjorn Helgaas 已提交
670 671 672 673
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
		pnpacpi_parse_fixed_mem32_option(option,
						 &res->data.fixed_memory32);
		break;
674

B
Bjorn Helgaas 已提交
675 676 677 678 679
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
		pnpacpi_parse_address_option(option, res);
		break;
680

B
Bjorn Helgaas 已提交
681 682 683 684 685 686 687 688 689 690 691 692 693
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
		pnpacpi_parse_ext_irq_option(option, &res->data.extended_irq);
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

	default:
		pnp_warn("PnPACPI: unknown resource type %d", res->type);
		return AE_ERROR;
L
Linus Torvalds 已提交
694
	}
B
Bjorn Helgaas 已提交
695

L
Linus Torvalds 已提交
696 697 698
	return AE_OK;
}

699 700
acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle,
						      struct pnp_dev *dev)
L
Linus Torvalds 已提交
701 702 703 704 705 706 707
{
	acpi_status status;
	struct acpipnp_parse_option_s parse_data;

	parse_data.option = pnp_register_independent_option(dev);
	if (!parse_data.option)
		return AE_ERROR;
M
Matthieu Castet 已提交
708
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
709
	parse_data.dev = dev;
B
Bob Moore 已提交
710
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
711
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
712 713 714 715

	return status;
}

716
static int pnpacpi_supported_resource(struct acpi_resource *res)
L
Linus Torvalds 已提交
717
{
718
	switch (res->type) {
B
Bob Moore 已提交
719 720 721 722 723 724 725 726 727 728
	case ACPI_RESOURCE_TYPE_IRQ:
	case ACPI_RESOURCE_TYPE_DMA:
	case ACPI_RESOURCE_TYPE_IO:
	case ACPI_RESOURCE_TYPE_FIXED_IO:
	case ACPI_RESOURCE_TYPE_MEMORY24:
	case ACPI_RESOURCE_TYPE_MEMORY32:
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
729
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
730
		return 1;
L
Linus Torvalds 已提交
731
	}
732 733 734 735 736 737 738
	return 0;
}

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
739
					   void *data)
740
{
741
	int *res_cnt = data;
742 743 744

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
745 746 747
	return AE_OK;
}

B
Bjorn Helgaas 已提交
748
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
749
{
750
	struct acpi_resource **resource = data;
751 752

	if (pnpacpi_supported_resource(res)) {
753
		(*resource)->type = res->type;
754
		(*resource)->length = sizeof(struct acpi_resource);
L
Linus Torvalds 已提交
755 756 757 758 759 760
		(*resource)++;
	}

	return AE_OK;
}

B
Bob Moore 已提交
761
int pnpacpi_build_resource_template(acpi_handle handle,
B
Bjorn Helgaas 已提交
762
				    struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
763 764 765 766 767
{
	struct acpi_resource *resource;
	int res_cnt = 0;
	acpi_status status;

B
Bob Moore 已提交
768
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
769
				     pnpacpi_count_resources, &res_cnt);
L
Linus Torvalds 已提交
770 771 772 773 774 775 776
	if (ACPI_FAILURE(status)) {
		pnp_err("Evaluate _CRS failed");
		return -EINVAL;
	}
	if (!res_cnt)
		return -EINVAL;
	buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
777
	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
L
Linus Torvalds 已提交
778 779 780 781
	if (!buffer->pointer)
		return -ENOMEM;
	pnp_dbg("Res cnt %d", res_cnt);
	resource = (struct acpi_resource *)buffer->pointer;
B
Bob Moore 已提交
782
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
783
				     pnpacpi_type_resources, &resource);
L
Linus Torvalds 已提交
784 785 786 787 788 789
	if (ACPI_FAILURE(status)) {
		kfree(buffer->pointer);
		pnp_err("Evaluate _CRS failed");
		return -EINVAL;
	}
	/* resource will pointer the end resource now */
B
Bob Moore 已提交
790
	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
L
Linus Torvalds 已提交
791 792 793 794

	return 0;
}

B
Bob Moore 已提交
795
static void pnpacpi_encode_irq(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
796
			       struct resource *p)
L
Linus Torvalds 已提交
797
{
B
Bob Moore 已提交
798
	int triggering, polarity;
B
Bjorn Helgaas 已提交
799 800

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
B
Bob Moore 已提交
801 802 803 804
	resource->data.irq.triggering = triggering;
	resource->data.irq.polarity = polarity;
	if (triggering == ACPI_EDGE_SENSITIVE)
		resource->data.irq.sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
805
	else
B
Bob Moore 已提交
806 807
		resource->data.irq.sharable = ACPI_SHARED;
	resource->data.irq.interrupt_count = 1;
L
Linus Torvalds 已提交
808 809 810 811
	resource->data.irq.interrupts[0] = p->start;
}

static void pnpacpi_encode_ext_irq(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
812
				   struct resource *p)
L
Linus Torvalds 已提交
813
{
B
Bob Moore 已提交
814
	int triggering, polarity;
B
Bjorn Helgaas 已提交
815 816

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
L
Linus Torvalds 已提交
817
	resource->data.extended_irq.producer_consumer = ACPI_CONSUMER;
B
Bob Moore 已提交
818 819 820 821
	resource->data.extended_irq.triggering = triggering;
	resource->data.extended_irq.polarity = polarity;
	if (triggering == ACPI_EDGE_SENSITIVE)
		resource->data.irq.sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
822
	else
B
Bob Moore 已提交
823 824
		resource->data.irq.sharable = ACPI_SHARED;
	resource->data.extended_irq.interrupt_count = 1;
L
Linus Torvalds 已提交
825 826 827 828
	resource->data.extended_irq.interrupts[0] = p->start;
}

static void pnpacpi_encode_dma(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
829
			       struct resource *p)
L
Linus Torvalds 已提交
830 831
{
	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
832
	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
B
Bjorn Helgaas 已提交
833 834 835 836 837 838 839 840 841 842 843
	case IORESOURCE_DMA_TYPEA:
		resource->data.dma.type = ACPI_TYPE_A;
		break;
	case IORESOURCE_DMA_TYPEB:
		resource->data.dma.type = ACPI_TYPE_B;
		break;
	case IORESOURCE_DMA_TYPEF:
		resource->data.dma.type = ACPI_TYPE_F;
		break;
	default:
		resource->data.dma.type = ACPI_COMPATIBILITY;
844 845 846
	}

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
847 848 849 850 851 852 853 854
	case IORESOURCE_DMA_8BIT:
		resource->data.dma.transfer = ACPI_TRANSFER_8;
		break;
	case IORESOURCE_DMA_8AND16BIT:
		resource->data.dma.transfer = ACPI_TRANSFER_8_16;
		break;
	default:
		resource->data.dma.transfer = ACPI_TRANSFER_16;
855 856 857
	}

	resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
B
Bob Moore 已提交
858
	resource->data.dma.channel_count = 1;
L
Linus Torvalds 已提交
859 860 861 862
	resource->data.dma.channels[0] = p->start;
}

static void pnpacpi_encode_io(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
863
			      struct resource *p)
L
Linus Torvalds 已提交
864 865
{
	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
B
Bjorn Helgaas 已提交
866 867
	resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
	    ACPI_DECODE_16 : ACPI_DECODE_10;
B
Bob Moore 已提交
868 869
	resource->data.io.minimum = p->start;
	resource->data.io.maximum = p->end;
B
Bjorn Helgaas 已提交
870
	resource->data.io.alignment = 0;	/* Correct? */
B
Bob Moore 已提交
871
	resource->data.io.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
872 873 874
}

static void pnpacpi_encode_fixed_io(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
875
				    struct resource *p)
L
Linus Torvalds 已提交
876
{
B
Bob Moore 已提交
877 878
	resource->data.fixed_io.address = p->start;
	resource->data.fixed_io.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
879 880 881
}

static void pnpacpi_encode_mem24(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
882
				 struct resource *p)
L
Linus Torvalds 已提交
883 884
{
	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
B
Bob Moore 已提交
885
	resource->data.memory24.write_protect =
B
Bjorn Helgaas 已提交
886 887
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
B
Bob Moore 已提交
888 889
	resource->data.memory24.minimum = p->start;
	resource->data.memory24.maximum = p->end;
L
Linus Torvalds 已提交
890
	resource->data.memory24.alignment = 0;
B
Bob Moore 已提交
891
	resource->data.memory24.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
892 893 894
}

static void pnpacpi_encode_mem32(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
895
				 struct resource *p)
L
Linus Torvalds 已提交
896
{
B
Bob Moore 已提交
897
	resource->data.memory32.write_protect =
B
Bjorn Helgaas 已提交
898 899
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
B
Bob Moore 已提交
900 901
	resource->data.memory32.minimum = p->start;
	resource->data.memory32.maximum = p->end;
L
Linus Torvalds 已提交
902
	resource->data.memory32.alignment = 0;
B
Bob Moore 已提交
903
	resource->data.memory32.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
904 905 906
}

static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
907
				       struct resource *p)
L
Linus Torvalds 已提交
908
{
B
Bob Moore 已提交
909
	resource->data.fixed_memory32.write_protect =
B
Bjorn Helgaas 已提交
910 911
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
B
Bob Moore 已提交
912 913
	resource->data.fixed_memory32.address = p->start;
	resource->data.fixed_memory32.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
914 915
}

B
Bob Moore 已提交
916
int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
B
Bjorn Helgaas 已提交
917
			     struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
918 919 920
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
921
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
922
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
923 924 925 926
	int port = 0, irq = 0, dma = 0, mem = 0;

	pnp_dbg("res cnt %d", res_cnt);
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
927
		switch (resource->type) {
B
Bob Moore 已提交
928
		case ACPI_RESOURCE_TYPE_IRQ:
L
Linus Torvalds 已提交
929
			pnp_dbg("Encode irq");
B
Bob Moore 已提交
930
			pnpacpi_encode_irq(resource,
B
Bjorn Helgaas 已提交
931
					   &res_table->irq_resource[irq]);
L
Linus Torvalds 已提交
932 933 934
			irq++;
			break;

B
Bob Moore 已提交
935
		case ACPI_RESOURCE_TYPE_DMA:
L
Linus Torvalds 已提交
936
			pnp_dbg("Encode dma");
B
Bob Moore 已提交
937
			pnpacpi_encode_dma(resource,
B
Bjorn Helgaas 已提交
938
					   &res_table->dma_resource[dma]);
B
Bjorn Helgaas 已提交
939
			dma++;
L
Linus Torvalds 已提交
940
			break;
B
Bob Moore 已提交
941
		case ACPI_RESOURCE_TYPE_IO:
L
Linus Torvalds 已提交
942
			pnp_dbg("Encode io");
B
Bob Moore 已提交
943
			pnpacpi_encode_io(resource,
B
Bjorn Helgaas 已提交
944
					  &res_table->port_resource[port]);
B
Bjorn Helgaas 已提交
945
			port++;
L
Linus Torvalds 已提交
946
			break;
B
Bob Moore 已提交
947
		case ACPI_RESOURCE_TYPE_FIXED_IO:
L
Linus Torvalds 已提交
948 949
			pnp_dbg("Encode fixed io");
			pnpacpi_encode_fixed_io(resource,
B
Bjorn Helgaas 已提交
950 951
						&res_table->
						port_resource[port]);
B
Bjorn Helgaas 已提交
952
			port++;
L
Linus Torvalds 已提交
953
			break;
B
Bob Moore 已提交
954
		case ACPI_RESOURCE_TYPE_MEMORY24:
L
Linus Torvalds 已提交
955 956
			pnp_dbg("Encode mem24");
			pnpacpi_encode_mem24(resource,
B
Bjorn Helgaas 已提交
957
					     &res_table->mem_resource[mem]);
B
Bjorn Helgaas 已提交
958
			mem++;
L
Linus Torvalds 已提交
959
			break;
B
Bob Moore 已提交
960
		case ACPI_RESOURCE_TYPE_MEMORY32:
L
Linus Torvalds 已提交
961 962
			pnp_dbg("Encode mem32");
			pnpacpi_encode_mem32(resource,
B
Bjorn Helgaas 已提交
963
					     &res_table->mem_resource[mem]);
B
Bjorn Helgaas 已提交
964
			mem++;
L
Linus Torvalds 已提交
965
			break;
B
Bob Moore 已提交
966
		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
L
Linus Torvalds 已提交
967 968
			pnp_dbg("Encode fixed mem32");
			pnpacpi_encode_fixed_mem32(resource,
B
Bjorn Helgaas 已提交
969 970
						   &res_table->
						   mem_resource[mem]);
B
Bjorn Helgaas 已提交
971
			mem++;
L
Linus Torvalds 已提交
972
			break;
973 974 975
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
			pnp_dbg("Encode ext irq");
			pnpacpi_encode_ext_irq(resource,
B
Bjorn Helgaas 已提交
976
					       &res_table->irq_resource[irq]);
977 978 979 980 981 982 983 984 985 986 987
			irq++;
			break;
		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		case ACPI_RESOURCE_TYPE_VENDOR:
		case ACPI_RESOURCE_TYPE_END_TAG:
		case ACPI_RESOURCE_TYPE_ADDRESS16:
		case ACPI_RESOURCE_TYPE_ADDRESS32:
		case ACPI_RESOURCE_TYPE_ADDRESS64:
		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
B
Bjorn Helgaas 已提交
988
		default:	/* other type */
989
			pnp_warn("unknown resource type %d", resource->type);
L
Linus Torvalds 已提交
990 991
			return -EINVAL;
		}
B
Bjorn Helgaas 已提交
992 993
		resource++;
		i++;
L
Linus Torvalds 已提交
994 995 996
	}
	return 0;
}