rsparser.c 26.8 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
 */
35
static int irq_flags(int triggering, int polarity, int shareable)
L
Linus Torvalds 已提交
36
{
37 38
	int flags;

B
Bob Moore 已提交
39
	if (triggering == ACPI_LEVEL_SENSITIVE) {
B
Bjorn Helgaas 已提交
40
		if (polarity == ACPI_ACTIVE_LOW)
41
			flags = IORESOURCE_IRQ_LOWLEVEL;
L
Linus Torvalds 已提交
42
		else
43
			flags = IORESOURCE_IRQ_HIGHLEVEL;
B
Bjorn Helgaas 已提交
44
	} else {
B
Bjorn Helgaas 已提交
45
		if (polarity == ACPI_ACTIVE_LOW)
46
			flags = IORESOURCE_IRQ_LOWEDGE;
L
Linus Torvalds 已提交
47
		else
48
			flags = IORESOURCE_IRQ_HIGHEDGE;
L
Linus Torvalds 已提交
49
	}
50 51 52 53 54

	if (shareable)
		flags |= IORESOURCE_IRQ_SHAREABLE;

	return flags;
L
Linus Torvalds 已提交
55 56
}

B
Bob Moore 已提交
57
static void decode_irq_flags(int flag, int *triggering, int *polarity)
L
Linus Torvalds 已提交
58 59 60
{
	switch (flag) {
	case IORESOURCE_IRQ_LOWLEVEL:
B
Bob Moore 已提交
61 62
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
63
		break;
B
Bjorn Helgaas 已提交
64
	case IORESOURCE_IRQ_HIGHLEVEL:
B
Bob Moore 已提交
65 66
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
67 68
		break;
	case IORESOURCE_IRQ_LOWEDGE:
B
Bob Moore 已提交
69 70
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
71 72
		break;
	case IORESOURCE_IRQ_HIGHEDGE:
B
Bob Moore 已提交
73 74
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
75 76 77 78
		break;
	}
}

B
Bjorn Helgaas 已提交
79 80 81
static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
						u32 gsi, int triggering,
						int polarity, int shareable)
L
Linus Torvalds 已提交
82 83
{
	int i = 0;
84
	int irq;
85
	int p, t;
86
	static unsigned char warned;
87 88 89 90

	if (!valid_IRQ(gsi))
		return;

L
Linus Torvalds 已提交
91
	while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
92
	       i < PNP_MAX_IRQ)
L
Linus Torvalds 已提交
93
		i++;
94 95 96 97 98 99
	if (i >= PNP_MAX_IRQ) {
		if (!warned) {
			printk(KERN_WARNING "pnpacpi: exceeded the max number"
				" of IRQ resources: %d\n", PNP_MAX_IRQ);
			warned = 1;
		}
100
		return;
101
	}
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
	/*
	 * 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 已提交
119
	res->irq_resource[i].flags = IORESOURCE_IRQ;	// Also clears _UNSET flag
120
	res->irq_resource[i].flags |= irq_flags(triggering, polarity, shareable);
B
Bob Moore 已提交
121
	irq = acpi_register_gsi(gsi, triggering, polarity);
122 123 124
	if (irq < 0) {
		res->irq_resource[i].flags |= IORESOURCE_DISABLED;
		return;
L
Linus Torvalds 已提交
125
	}
126 127 128 129

	res->irq_resource[i].start = irq;
	res->irq_resource[i].end = irq;
	pcibios_penalize_isa_irq(irq, 1);
L
Linus Torvalds 已提交
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 169 170 171 172 173 174
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 已提交
175
static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
176
						u32 dma, int flags)
L
Linus Torvalds 已提交
177 178
{
	int i = 0;
179
	static unsigned char warned;
B
Bjorn Helgaas 已提交
180

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

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

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

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

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

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

B
Bjorn Helgaas 已提交
254 255
static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
						  struct acpi_resource *res)
256 257 258 259 260 261 262
{
	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 已提交
263
			 res->type);
264 265 266
		return;
	}

267 268 269
	if (p->producer_consumer == ACPI_PRODUCER)
		return;

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

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
282
					      void *data)
L
Linus Torvalds 已提交
283
{
284
	struct pnp_resource_table *res_table = data;
285 286 287 288 289 290 291 292
	struct acpi_resource_irq *irq;
	struct acpi_resource_dma *dma;
	struct acpi_resource_io *io;
	struct acpi_resource_fixed_io *fixed_io;
	struct acpi_resource_memory24 *memory24;
	struct acpi_resource_memory32 *memory32;
	struct acpi_resource_fixed_memory32 *fixed_memory32;
	struct acpi_resource_extended_irq *extended_irq;
293
	int i;
L
Linus Torvalds 已提交
294

295
	switch (res->type) {
B
Bob Moore 已提交
296
	case ACPI_RESOURCE_TYPE_IRQ:
297 298 299 300
		/*
		 * Per spec, only one interrupt per descriptor is allowed in
		 * _CRS, but some firmware violates this, so parse them all.
		 */
301 302
		irq = &res->data.irq;
		for (i = 0; i < irq->interrupt_count; i++) {
303
			pnpacpi_parse_allocated_irqresource(res_table,
304 305 306 307
				irq->interrupts[i],
				irq->triggering,
				irq->polarity,
				irq->sharable);
L
Linus Torvalds 已提交
308 309 310
		}
		break;

B
Bob Moore 已提交
311
	case ACPI_RESOURCE_TYPE_DMA:
312 313
		dma = &res->data.dma;
		if (dma->channel_count > 0)
B
Bob Moore 已提交
314
			pnpacpi_parse_allocated_dmaresource(res_table,
315
				dma->channels[0],
316 317
				dma_flags(dma->type, dma->bus_master,
					  dma->transfer));
L
Linus Torvalds 已提交
318
		break;
319

B
Bob Moore 已提交
320
	case ACPI_RESOURCE_TYPE_IO:
321
		io = &res->data.io;
B
Bob Moore 已提交
322
		pnpacpi_parse_allocated_ioresource(res_table,
323 324 325
			io->minimum,
			io->address_length,
			io->io_decode);
L
Linus Torvalds 已提交
326
		break;
327 328 329 330 331

	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		break;

B
Bob Moore 已提交
332
	case ACPI_RESOURCE_TYPE_FIXED_IO:
333
		fixed_io = &res->data.fixed_io;
B
Bob Moore 已提交
334
		pnpacpi_parse_allocated_ioresource(res_table,
335 336
			fixed_io->address,
			fixed_io->address_length,
B
Bjorn Helgaas 已提交
337
			ACPI_DECODE_10);
L
Linus Torvalds 已提交
338
		break;
339 340 341 342 343 344 345

	case ACPI_RESOURCE_TYPE_VENDOR:
		break;

	case ACPI_RESOURCE_TYPE_END_TAG:
		break;

B
Bob Moore 已提交
346
	case ACPI_RESOURCE_TYPE_MEMORY24:
347
		memory24 = &res->data.memory24;
B
Bob Moore 已提交
348
		pnpacpi_parse_allocated_memresource(res_table,
349 350 351
			memory24->minimum,
			memory24->address_length,
			memory24->write_protect);
L
Linus Torvalds 已提交
352
		break;
B
Bob Moore 已提交
353
	case ACPI_RESOURCE_TYPE_MEMORY32:
354
		memory32 = &res->data.memory32;
B
Bob Moore 已提交
355
		pnpacpi_parse_allocated_memresource(res_table,
356 357 358
			memory32->minimum,
			memory32->address_length,
			memory32->write_protect);
L
Linus Torvalds 已提交
359
		break;
B
Bob Moore 已提交
360
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
361
		fixed_memory32 = &res->data.fixed_memory32;
B
Bob Moore 已提交
362
		pnpacpi_parse_allocated_memresource(res_table,
363 364 365
			fixed_memory32->address,
			fixed_memory32->address_length,
			fixed_memory32->write_protect);
L
Linus Torvalds 已提交
366
		break;
B
Bob Moore 已提交
367 368 369
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
370
		pnpacpi_parse_allocated_address_space(res_table, res);
L
Linus Torvalds 已提交
371
		break;
372 373

	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
374 375
		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
			return AE_OK;
376 377 378
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
379 380
		extended_irq = &res->data.extended_irq;
		if (extended_irq->producer_consumer == ACPI_PRODUCER)
381 382
			return AE_OK;

383
		for (i = 0; i < extended_irq->interrupt_count; i++) {
384
			pnpacpi_parse_allocated_irqresource(res_table,
385 386 387 388
				extended_irq->interrupts[i],
				extended_irq->triggering,
				extended_irq->polarity,
				extended_irq->sharable);
389 390 391 392
		}
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
L
Linus Torvalds 已提交
393
		break;
394

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

L
Linus Torvalds 已提交
400 401 402
	return AE_OK;
}

B
Bjorn Helgaas 已提交
403 404
acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle,
					     struct pnp_resource_table * res)
L
Linus Torvalds 已提交
405 406 407 408
{
	/* Blank the resource table values */
	pnp_init_resource_table(res);

B
Bjorn Helgaas 已提交
409 410
	return acpi_walk_resources(handle, METHOD_NAME__CRS,
				   pnpacpi_allocated_resource, res);
L
Linus Torvalds 已提交
411 412
}

413 414
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
					    struct pnp_option *option,
415
					    struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
416 417
{
	int i;
B
Bjorn Helgaas 已提交
418
	struct pnp_dma *dma;
L
Linus Torvalds 已提交
419

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

B
Bjorn Helgaas 已提交
426
	for (i = 0; i < p->channel_count; i++)
L
Linus Torvalds 已提交
427
		dma->map |= 1 << p->channels[i];
428 429

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

431
	pnp_register_dma_resource(dev, option, dma);
L
Linus Torvalds 已提交
432 433
}

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

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

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

452
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
453 454
}

455 456
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
						struct pnp_option *option,
457
					struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
458 459
{
	int i;
B
Bjorn Helgaas 已提交
460
	struct pnp_irq *irq;
L
Linus Torvalds 已提交
461

B
Bob Moore 已提交
462
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
463
		return;
464
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
465 466 467
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
468
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
469 470
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
471
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
472

473
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
474 475
}

476 477
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
					     struct pnp_option *option,
478
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
479
{
B
Bjorn Helgaas 已提交
480
	struct pnp_port *port;
L
Linus Torvalds 已提交
481

B
Bob Moore 已提交
482
	if (io->address_length == 0)
L
Linus Torvalds 已提交
483
		return;
484
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
485 486
	if (!port)
		return;
B
Bob Moore 已提交
487 488
	port->min = io->minimum;
	port->max = io->maximum;
L
Linus Torvalds 已提交
489
	port->align = io->alignment;
B
Bob Moore 已提交
490 491
	port->size = io->address_length;
	port->flags = ACPI_DECODE_16 == io->io_decode ?
B
Bjorn Helgaas 已提交
492
	    PNP_PORT_FLAG_16BITADDR : 0;
493
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
494 495
}

496 497
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
						   struct pnp_option *option,
498
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
499
{
B
Bjorn Helgaas 已提交
500
	struct pnp_port *port;
L
Linus Torvalds 已提交
501

B
Bob Moore 已提交
502
	if (io->address_length == 0)
L
Linus Torvalds 已提交
503
		return;
504
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
505 506
	if (!port)
		return;
B
Bob Moore 已提交
507 508
	port->min = port->max = io->address;
	port->size = io->address_length;
L
Linus Torvalds 已提交
509 510
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
511
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
512 513
}

514 515
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
					      struct pnp_option *option,
516
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
517
{
B
Bjorn Helgaas 已提交
518
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
519

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

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

533
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
534 535
}

536 537
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
					      struct pnp_option *option,
538
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
539
{
B
Bjorn Helgaas 已提交
540
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
541

B
Bob Moore 已提交
542
	if (p->address_length == 0)
L
Linus Torvalds 已提交
543
		return;
544
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
545 546
	if (!mem)
		return;
B
Bob Moore 已提交
547 548
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
549
	mem->align = p->alignment;
B
Bob Moore 已提交
550
	mem->size = p->address_length;
L
Linus Torvalds 已提交
551

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

555
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
556 557
}

558 559
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
						    struct pnp_option *option,
560
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
561
{
B
Bjorn Helgaas 已提交
562
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
563

B
Bob Moore 已提交
564
	if (p->address_length == 0)
L
Linus Torvalds 已提交
565
		return;
566
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
567 568
	if (!mem)
		return;
B
Bob Moore 已提交
569 570
	mem->min = mem->max = p->address;
	mem->size = p->address_length;
L
Linus Torvalds 已提交
571 572
	mem->align = 0;

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

576
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
577 578
}

579 580
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
						struct pnp_option *option,
581
						struct acpi_resource *r)
582 583 584
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
B
Bjorn Helgaas 已提交
585 586
	struct pnp_mem *mem;
	struct pnp_port *port;
587 588 589

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
590 591
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
592 593 594 595 596 597 598
		return;
	}

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

	if (p->resource_type == ACPI_MEMORY_RANGE) {
599
		mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
600 601
		if (!mem)
			return;
L
Len Brown 已提交
602
		mem->min = mem->max = p->minimum;
603 604
		mem->size = p->address_length;
		mem->align = 0;
L
Len Brown 已提交
605
		mem->flags = (p->info.mem.write_protect ==
B
Bjorn Helgaas 已提交
606 607
			      ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
		    : 0;
608
		pnp_register_mem_resource(dev, option, mem);
609
	} else if (p->resource_type == ACPI_IO_RANGE) {
610
		port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
611 612
		if (!port)
			return;
L
Len Brown 已提交
613
		port->min = port->max = p->minimum;
614 615 616
		port->size = p->address_length;
		port->align = 0;
		port->flags = PNP_PORT_FLAG_FIXED;
617
		pnp_register_port_resource(dev, option, port);
618 619 620
	}
}

L
Linus Torvalds 已提交
621 622
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
623
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
624 625 626
	struct pnp_dev *dev;
};

627 628
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
						  void *data)
L
Linus Torvalds 已提交
629 630
{
	int priority = 0;
631
	struct acpipnp_parse_option_s *parse_data = data;
L
Linus Torvalds 已提交
632 633 634
	struct pnp_dev *dev = parse_data->dev;
	struct pnp_option *option = parse_data->option;

635
	switch (res->type) {
B
Bjorn Helgaas 已提交
636
	case ACPI_RESOURCE_TYPE_IRQ:
637
		pnpacpi_parse_irq_option(dev, option, &res->data.irq);
B
Bjorn Helgaas 已提交
638
		break;
639

B
Bjorn Helgaas 已提交
640
	case ACPI_RESOURCE_TYPE_DMA:
641
		pnpacpi_parse_dma_option(dev, option, &res->data.dma);
B
Bjorn Helgaas 已提交
642
		break;
643

B
Bjorn Helgaas 已提交
644 645 646 647
	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 已提交
648
			break;
649

B
Bjorn Helgaas 已提交
650 651
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
652
			break;
653

B
Bjorn Helgaas 已提交
654 655
		case ACPI_SUB_OPTIMAL_CONFIGURATION:
			priority = PNP_RES_PRIORITY_FUNCTIONAL;
656
			break;
B
Bjorn Helgaas 已提交
657 658
		default:
			priority = PNP_RES_PRIORITY_INVALID;
659
			break;
B
Bjorn Helgaas 已提交
660
		}
B
Bjorn Helgaas 已提交
661
		/* TBD: Consider performance/robustness bits */
B
Bjorn Helgaas 已提交
662 663 664 665 666
		option = pnp_register_dependent_option(dev, priority);
		if (!option)
			return AE_ERROR;
		parse_data->option = option;
		break;
667

B
Bjorn Helgaas 已提交
668 669 670 671 672 673 674 675
	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;
676
		dev_dbg(&dev->dev, "end dependent options\n");
B
Bjorn Helgaas 已提交
677
		break;
678

B
Bjorn Helgaas 已提交
679
	case ACPI_RESOURCE_TYPE_IO:
680
		pnpacpi_parse_port_option(dev, option, &res->data.io);
B
Bjorn Helgaas 已提交
681
		break;
682

B
Bjorn Helgaas 已提交
683
	case ACPI_RESOURCE_TYPE_FIXED_IO:
684 685
		pnpacpi_parse_fixed_port_option(dev, option,
					        &res->data.fixed_io);
B
Bjorn Helgaas 已提交
686
		break;
687

B
Bjorn Helgaas 已提交
688 689 690
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
691

B
Bjorn Helgaas 已提交
692
	case ACPI_RESOURCE_TYPE_MEMORY24:
693
		pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
B
Bjorn Helgaas 已提交
694
		break;
695

B
Bjorn Helgaas 已提交
696
	case ACPI_RESOURCE_TYPE_MEMORY32:
697
		pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
B
Bjorn Helgaas 已提交
698
		break;
699

B
Bjorn Helgaas 已提交
700
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
701
		pnpacpi_parse_fixed_mem32_option(dev, option,
B
Bjorn Helgaas 已提交
702 703
						 &res->data.fixed_memory32);
		break;
704

B
Bjorn Helgaas 已提交
705 706 707
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
708
		pnpacpi_parse_address_option(dev, option, res);
B
Bjorn Helgaas 已提交
709
		break;
710

B
Bjorn Helgaas 已提交
711 712 713 714
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
715 716
		pnpacpi_parse_ext_irq_option(dev, option,
					     &res->data.extended_irq);
B
Bjorn Helgaas 已提交
717 718 719 720 721 722 723 724
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

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

L
Linus Torvalds 已提交
727 728 729
	return AE_OK;
}

730 731
acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle,
						      struct pnp_dev *dev)
L
Linus Torvalds 已提交
732 733 734 735 736 737 738
{
	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 已提交
739
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
740
	parse_data.dev = dev;
B
Bob Moore 已提交
741
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
742
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
743 744 745 746

	return status;
}

747
static int pnpacpi_supported_resource(struct acpi_resource *res)
L
Linus Torvalds 已提交
748
{
749
	switch (res->type) {
B
Bob Moore 已提交
750 751 752 753 754 755 756 757 758 759
	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:
760
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
761
		return 1;
L
Linus Torvalds 已提交
762
	}
763 764 765 766 767 768 769
	return 0;
}

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
770
					   void *data)
771
{
772
	int *res_cnt = data;
773 774 775

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
776 777 778
	return AE_OK;
}

B
Bjorn Helgaas 已提交
779
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
780
{
781
	struct acpi_resource **resource = data;
782 783

	if (pnpacpi_supported_resource(res)) {
784
		(*resource)->type = res->type;
785
		(*resource)->length = sizeof(struct acpi_resource);
L
Linus Torvalds 已提交
786 787 788 789 790 791
		(*resource)++;
	}

	return AE_OK;
}

792
int pnpacpi_build_resource_template(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
793
				    struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
794
{
795
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
796 797 798 799
	struct acpi_resource *resource;
	int res_cnt = 0;
	acpi_status status;

B
Bob Moore 已提交
800
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
801
				     pnpacpi_count_resources, &res_cnt);
L
Linus Torvalds 已提交
802 803 804 805 806 807 808
	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;
809
	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
L
Linus Torvalds 已提交
810 811 812 813
	if (!buffer->pointer)
		return -ENOMEM;
	pnp_dbg("Res cnt %d", res_cnt);
	resource = (struct acpi_resource *)buffer->pointer;
B
Bob Moore 已提交
814
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
815
				     pnpacpi_type_resources, &resource);
L
Linus Torvalds 已提交
816 817 818 819 820 821
	if (ACPI_FAILURE(status)) {
		kfree(buffer->pointer);
		pnp_err("Evaluate _CRS failed");
		return -EINVAL;
	}
	/* resource will pointer the end resource now */
B
Bob Moore 已提交
822
	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
L
Linus Torvalds 已提交
823 824 825 826

	return 0;
}

B
Bob Moore 已提交
827
static void pnpacpi_encode_irq(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
828
			       struct resource *p)
L
Linus Torvalds 已提交
829
{
830
	struct acpi_resource_irq *irq = &resource->data.irq;
B
Bob Moore 已提交
831
	int triggering, polarity;
B
Bjorn Helgaas 已提交
832 833

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
834 835
	irq->triggering = triggering;
	irq->polarity = polarity;
B
Bob Moore 已提交
836
	if (triggering == ACPI_EDGE_SENSITIVE)
837
		irq->sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
838
	else
839 840 841
		irq->sharable = ACPI_SHARED;
	irq->interrupt_count = 1;
	irq->interrupts[0] = p->start;
L
Linus Torvalds 已提交
842 843 844
}

static void pnpacpi_encode_ext_irq(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
845
				   struct resource *p)
L
Linus Torvalds 已提交
846
{
847
	struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
B
Bob Moore 已提交
848
	int triggering, polarity;
B
Bjorn Helgaas 已提交
849 850

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
851 852 853
	extended_irq->producer_consumer = ACPI_CONSUMER;
	extended_irq->triggering = triggering;
	extended_irq->polarity = polarity;
B
Bob Moore 已提交
854
	if (triggering == ACPI_EDGE_SENSITIVE)
855
		extended_irq->sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
856
	else
857 858 859
		extended_irq->sharable = ACPI_SHARED;
	extended_irq->interrupt_count = 1;
	extended_irq->interrupts[0] = p->start;
L
Linus Torvalds 已提交
860 861 862
}

static void pnpacpi_encode_dma(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
863
			       struct resource *p)
L
Linus Torvalds 已提交
864
{
865 866
	struct acpi_resource_dma *dma = &resource->data.dma;

L
Linus Torvalds 已提交
867
	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
868
	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
B
Bjorn Helgaas 已提交
869
	case IORESOURCE_DMA_TYPEA:
870
		dma->type = ACPI_TYPE_A;
B
Bjorn Helgaas 已提交
871 872
		break;
	case IORESOURCE_DMA_TYPEB:
873
		dma->type = ACPI_TYPE_B;
B
Bjorn Helgaas 已提交
874 875
		break;
	case IORESOURCE_DMA_TYPEF:
876
		dma->type = ACPI_TYPE_F;
B
Bjorn Helgaas 已提交
877 878
		break;
	default:
879
		dma->type = ACPI_COMPATIBILITY;
880 881 882
	}

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
883
	case IORESOURCE_DMA_8BIT:
884
		dma->transfer = ACPI_TRANSFER_8;
B
Bjorn Helgaas 已提交
885 886
		break;
	case IORESOURCE_DMA_8AND16BIT:
887
		dma->transfer = ACPI_TRANSFER_8_16;
B
Bjorn Helgaas 已提交
888 889
		break;
	default:
890
		dma->transfer = ACPI_TRANSFER_16;
891 892
	}

893 894 895
	dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
	dma->channel_count = 1;
	dma->channels[0] = p->start;
L
Linus Torvalds 已提交
896 897 898
}

static void pnpacpi_encode_io(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
899
			      struct resource *p)
L
Linus Torvalds 已提交
900
{
901 902
	struct acpi_resource_io *io = &resource->data.io;

L
Linus Torvalds 已提交
903
	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
904
	io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
B
Bjorn Helgaas 已提交
905
	    ACPI_DECODE_16 : ACPI_DECODE_10;
906 907 908 909
	io->minimum = p->start;
	io->maximum = p->end;
	io->alignment = 0;	/* Correct? */
	io->address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
910 911 912
}

static void pnpacpi_encode_fixed_io(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
913
				    struct resource *p)
L
Linus Torvalds 已提交
914
{
915 916 917 918
	struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;

	fixed_io->address = p->start;
	fixed_io->address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
919 920 921
}

static void pnpacpi_encode_mem24(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
922
				 struct resource *p)
L
Linus Torvalds 已提交
923
{
924 925
	struct acpi_resource_memory24 *memory24 = &resource->data.memory24;

L
Linus Torvalds 已提交
926
	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
927
	memory24->write_protect =
B
Bjorn Helgaas 已提交
928 929
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
930 931 932 933
	memory24->minimum = p->start;
	memory24->maximum = p->end;
	memory24->alignment = 0;
	memory24->address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
934 935 936
}

static void pnpacpi_encode_mem32(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
937
				 struct resource *p)
L
Linus Torvalds 已提交
938
{
939 940 941
	struct acpi_resource_memory32 *memory32 = &resource->data.memory32;

	memory32->write_protect =
B
Bjorn Helgaas 已提交
942 943
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
944 945 946 947
	memory32->minimum = p->start;
	memory32->maximum = p->end;
	memory32->alignment = 0;
	memory32->address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
948 949 950
}

static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
951
				       struct resource *p)
L
Linus Torvalds 已提交
952
{
953 954 955
	struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;

	fixed_memory32->write_protect =
B
Bjorn Helgaas 已提交
956 957
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
958 959
	fixed_memory32->address = p->start;
	fixed_memory32->address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
960 961
}

B
Bob Moore 已提交
962
int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
B
Bjorn Helgaas 已提交
963
			     struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
964 965 966
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
967
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
968
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
969 970 971 972
	int port = 0, irq = 0, dma = 0, mem = 0;

	pnp_dbg("res cnt %d", res_cnt);
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
973
		switch (resource->type) {
B
Bob Moore 已提交
974
		case ACPI_RESOURCE_TYPE_IRQ:
L
Linus Torvalds 已提交
975
			pnp_dbg("Encode irq");
B
Bob Moore 已提交
976
			pnpacpi_encode_irq(resource,
B
Bjorn Helgaas 已提交
977
					   &res_table->irq_resource[irq]);
L
Linus Torvalds 已提交
978 979 980
			irq++;
			break;

B
Bob Moore 已提交
981
		case ACPI_RESOURCE_TYPE_DMA:
L
Linus Torvalds 已提交
982
			pnp_dbg("Encode dma");
B
Bob Moore 已提交
983
			pnpacpi_encode_dma(resource,
B
Bjorn Helgaas 已提交
984
					   &res_table->dma_resource[dma]);
B
Bjorn Helgaas 已提交
985
			dma++;
L
Linus Torvalds 已提交
986
			break;
B
Bob Moore 已提交
987
		case ACPI_RESOURCE_TYPE_IO:
L
Linus Torvalds 已提交
988
			pnp_dbg("Encode io");
B
Bob Moore 已提交
989
			pnpacpi_encode_io(resource,
B
Bjorn Helgaas 已提交
990
					  &res_table->port_resource[port]);
B
Bjorn Helgaas 已提交
991
			port++;
L
Linus Torvalds 已提交
992
			break;
B
Bob Moore 已提交
993
		case ACPI_RESOURCE_TYPE_FIXED_IO:
L
Linus Torvalds 已提交
994 995
			pnp_dbg("Encode fixed io");
			pnpacpi_encode_fixed_io(resource,
B
Bjorn Helgaas 已提交
996 997
						&res_table->
						port_resource[port]);
B
Bjorn Helgaas 已提交
998
			port++;
L
Linus Torvalds 已提交
999
			break;
B
Bob Moore 已提交
1000
		case ACPI_RESOURCE_TYPE_MEMORY24:
L
Linus Torvalds 已提交
1001 1002
			pnp_dbg("Encode mem24");
			pnpacpi_encode_mem24(resource,
B
Bjorn Helgaas 已提交
1003
					     &res_table->mem_resource[mem]);
B
Bjorn Helgaas 已提交
1004
			mem++;
L
Linus Torvalds 已提交
1005
			break;
B
Bob Moore 已提交
1006
		case ACPI_RESOURCE_TYPE_MEMORY32:
L
Linus Torvalds 已提交
1007 1008
			pnp_dbg("Encode mem32");
			pnpacpi_encode_mem32(resource,
B
Bjorn Helgaas 已提交
1009
					     &res_table->mem_resource[mem]);
B
Bjorn Helgaas 已提交
1010
			mem++;
L
Linus Torvalds 已提交
1011
			break;
B
Bob Moore 已提交
1012
		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
L
Linus Torvalds 已提交
1013 1014
			pnp_dbg("Encode fixed mem32");
			pnpacpi_encode_fixed_mem32(resource,
B
Bjorn Helgaas 已提交
1015 1016
						   &res_table->
						   mem_resource[mem]);
B
Bjorn Helgaas 已提交
1017
			mem++;
L
Linus Torvalds 已提交
1018
			break;
1019 1020 1021
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
			pnp_dbg("Encode ext irq");
			pnpacpi_encode_ext_irq(resource,
B
Bjorn Helgaas 已提交
1022
					       &res_table->irq_resource[irq]);
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
			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 已提交
1034
		default:	/* other type */
1035
			pnp_warn("unknown resource type %d", resource->type);
L
Linus Torvalds 已提交
1036 1037
			return -EINVAL;
		}
B
Bjorn Helgaas 已提交
1038 1039
		resource++;
		i++;
L
Linus Torvalds 已提交
1040 1041 1042
	}
	return 0;
}