rsparser.c 25.4 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 80 81 82

	if (!valid_IRQ(gsi))
		return;

L
Linus Torvalds 已提交
83
	while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
84
	       i < PNP_MAX_IRQ)
L
Linus Torvalds 已提交
85
		i++;
86 87 88
	if (i >= PNP_MAX_IRQ)
		return;

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	/*
	 * 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 已提交
106
	res->irq_resource[i].flags = IORESOURCE_IRQ;	// Also clears _UNSET flag
107
	res->irq_resource[i].flags |= irq_flags(triggering, polarity);
B
Bob Moore 已提交
108
	irq = acpi_register_gsi(gsi, triggering, polarity);
109 110 111
	if (irq < 0) {
		res->irq_resource[i].flags |= IORESOURCE_DISABLED;
		return;
L
Linus Torvalds 已提交
112
	}
113

114 115 116
	if (shareable)
		res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;

117 118 119
	res->irq_resource[i].start = irq;
	res->irq_resource[i].end = irq;
	pcibios_penalize_isa_irq(irq, 1);
L
Linus Torvalds 已提交
120 121
}

122 123 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
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 已提交
165 166 167
static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
						u32 dma, int type,
						int bus_master, int transfer)
L
Linus Torvalds 已提交
168 169
{
	int i = 0;
B
Bjorn Helgaas 已提交
170

171
	while (i < PNP_MAX_DMA &&
B
Bjorn Helgaas 已提交
172
	       !(res->dma_resource[i].flags & IORESOURCE_UNSET))
L
Linus Torvalds 已提交
173 174
		i++;
	if (i < PNP_MAX_DMA) {
B
Bjorn Helgaas 已提交
175 176 177
		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 已提交
178 179 180 181
		if (dma == -1) {
			res->dma_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
182 183
		res->dma_resource[i].start = dma;
		res->dma_resource[i].end = dma;
L
Linus Torvalds 已提交
184 185 186
	}
}

B
Bjorn Helgaas 已提交
187 188
static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
					       u64 io, u64 len, int io_decode)
L
Linus Torvalds 已提交
189 190
{
	int i = 0;
B
Bjorn Helgaas 已提交
191

L
Linus Torvalds 已提交
192
	while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
193
	       i < PNP_MAX_PORT)
L
Linus Torvalds 已提交
194 195
		i++;
	if (i < PNP_MAX_PORT) {
B
Bjorn Helgaas 已提交
196
		res->port_resource[i].flags = IORESOURCE_IO;	// Also clears _UNSET flag
197 198
		if (io_decode == ACPI_DECODE_16)
			res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
B
Bjorn Helgaas 已提交
199
		if (len <= 0 || (io + len - 1) >= 0x10003) {
L
Linus Torvalds 已提交
200 201 202
			res->port_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
203 204
		res->port_resource[i].start = io;
		res->port_resource[i].end = io + len - 1;
L
Linus Torvalds 已提交
205 206 207
	}
}

B
Bjorn Helgaas 已提交
208 209 210
static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
						u64 mem, u64 len,
						int write_protect)
L
Linus Torvalds 已提交
211 212
{
	int i = 0;
B
Bjorn Helgaas 已提交
213

L
Linus Torvalds 已提交
214
	while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
B
Bjorn Helgaas 已提交
215
	       (i < PNP_MAX_MEM))
L
Linus Torvalds 已提交
216 217
		i++;
	if (i < PNP_MAX_MEM) {
B
Bjorn Helgaas 已提交
218
		res->mem_resource[i].flags = IORESOURCE_MEM;	// Also clears _UNSET flag
L
Linus Torvalds 已提交
219 220 221 222
		if (len <= 0) {
			res->mem_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
B
Bjorn Helgaas 已提交
223
		if (write_protect == ACPI_READ_WRITE_MEMORY)
224 225
			res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;

226 227
		res->mem_resource[i].start = mem;
		res->mem_resource[i].end = mem + len - 1;
L
Linus Torvalds 已提交
228 229 230
	}
}

B
Bjorn Helgaas 已提交
231 232
static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
						  struct acpi_resource *res)
233 234 235 236 237 238 239
{
	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 已提交
240
			 res->type);
241 242 243
		return;
	}

244 245 246
	if (p->producer_consumer == ACPI_PRODUCER)
		return;

247 248
	if (p->resource_type == ACPI_MEMORY_RANGE)
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
249 250
			p->minimum, p->address_length,
			p->info.mem.write_protect);
251 252
	else if (p->resource_type == ACPI_IO_RANGE)
		pnpacpi_parse_allocated_ioresource(res_table,
B
Bjorn Helgaas 已提交
253 254 255
			p->minimum, p->address_length,
			p->granularity == 0xfff ? ACPI_DECODE_10 :
				ACPI_DECODE_16);
256
}
L
Linus Torvalds 已提交
257 258

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
259
					      void *data)
L
Linus Torvalds 已提交
260
{
261
	struct pnp_resource_table *res_table = data;
262
	int i;
L
Linus Torvalds 已提交
263

264
	switch (res->type) {
B
Bob Moore 已提交
265
	case ACPI_RESOURCE_TYPE_IRQ:
266 267 268 269
		/*
		 * Per spec, only one interrupt per descriptor is allowed in
		 * _CRS, but some firmware violates this, so parse them all.
		 */
B
Bob Moore 已提交
270
		for (i = 0; i < res->data.irq.interrupt_count; i++) {
271
			pnpacpi_parse_allocated_irqresource(res_table,
B
Bjorn Helgaas 已提交
272 273 274 275
				res->data.irq.interrupts[i],
				res->data.irq.triggering,
				res->data.irq.polarity,
				res->data.irq.sharable);
L
Linus Torvalds 已提交
276 277 278
		}
		break;

B
Bob Moore 已提交
279 280 281
	case ACPI_RESOURCE_TYPE_DMA:
		if (res->data.dma.channel_count > 0)
			pnpacpi_parse_allocated_dmaresource(res_table,
B
Bjorn Helgaas 已提交
282 283 284 285
				res->data.dma.channels[0],
				res->data.dma.type,
				res->data.dma.bus_master,
				res->data.dma.transfer);
L
Linus Torvalds 已提交
286
		break;
287

B
Bob Moore 已提交
288 289
	case ACPI_RESOURCE_TYPE_IO:
		pnpacpi_parse_allocated_ioresource(res_table,
B
Bjorn Helgaas 已提交
290 291 292
			res->data.io.minimum,
			res->data.io.address_length,
			res->data.io.io_decode);
L
Linus Torvalds 已提交
293
		break;
294 295 296 297 298

	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		break;

B
Bob Moore 已提交
299 300
	case ACPI_RESOURCE_TYPE_FIXED_IO:
		pnpacpi_parse_allocated_ioresource(res_table,
B
Bjorn Helgaas 已提交
301 302 303
			res->data.fixed_io.address,
			res->data.fixed_io.address_length,
			ACPI_DECODE_10);
L
Linus Torvalds 已提交
304
		break;
305 306 307 308 309 310 311

	case ACPI_RESOURCE_TYPE_VENDOR:
		break;

	case ACPI_RESOURCE_TYPE_END_TAG:
		break;

B
Bob Moore 已提交
312 313
	case ACPI_RESOURCE_TYPE_MEMORY24:
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
314 315 316
			res->data.memory24.minimum,
			res->data.memory24.address_length,
			res->data.memory24.write_protect);
L
Linus Torvalds 已提交
317
		break;
B
Bob Moore 已提交
318 319
	case ACPI_RESOURCE_TYPE_MEMORY32:
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
320 321 322
			res->data.memory32.minimum,
			res->data.memory32.address_length,
			res->data.memory32.write_protect);
L
Linus Torvalds 已提交
323
		break;
B
Bob Moore 已提交
324 325
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
		pnpacpi_parse_allocated_memresource(res_table,
B
Bjorn Helgaas 已提交
326 327 328
			res->data.fixed_memory32.address,
			res->data.fixed_memory32.address_length,
			res->data.fixed_memory32.write_protect);
L
Linus Torvalds 已提交
329
		break;
B
Bob Moore 已提交
330 331 332
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
333
		pnpacpi_parse_allocated_address_space(res_table, res);
L
Linus Torvalds 已提交
334
		break;
335 336

	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
337 338
		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
			return AE_OK;
339 340 341
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
342 343 344
		if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER)
			return AE_OK;

345 346
		for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
			pnpacpi_parse_allocated_irqresource(res_table,
B
Bjorn Helgaas 已提交
347 348 349 350
				res->data.extended_irq.interrupts[i],
				res->data.extended_irq.triggering,
				res->data.extended_irq.polarity,
				res->data.extended_irq.sharable);
351 352 353 354
		}
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
L
Linus Torvalds 已提交
355
		break;
356

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

L
Linus Torvalds 已提交
362 363 364
	return AE_OK;
}

B
Bjorn Helgaas 已提交
365 366
acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle,
					     struct pnp_resource_table * res)
L
Linus Torvalds 已提交
367 368 369 370
{
	/* Blank the resource table values */
	pnp_init_resource_table(res);

B
Bjorn Helgaas 已提交
371 372
	return acpi_walk_resources(handle, METHOD_NAME__CRS,
				   pnpacpi_allocated_resource, res);
L
Linus Torvalds 已提交
373 374
}

B
Bjorn Helgaas 已提交
375 376
static void pnpacpi_parse_dma_option(struct pnp_option *option,
				     struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
377 378
{
	int i;
B
Bjorn Helgaas 已提交
379
	struct pnp_dma *dma;
L
Linus Torvalds 已提交
380

B
Bob Moore 已提交
381
	if (p->channel_count == 0)
L
Linus Torvalds 已提交
382
		return;
383
	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
L
Linus Torvalds 已提交
384 385 386
	if (!dma)
		return;

B
Bjorn Helgaas 已提交
387
	for (i = 0; i < p->channel_count; i++)
L
Linus Torvalds 已提交
388
		dma->map |= 1 << p->channels[i];
389 390

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

B
Bjorn Helgaas 已提交
392
	pnp_register_dma_resource(option, dma);
L
Linus Torvalds 已提交
393 394 395
}

static void pnpacpi_parse_irq_option(struct pnp_option *option,
B
Bjorn Helgaas 已提交
396
				     struct acpi_resource_irq *p)
L
Linus Torvalds 已提交
397 398
{
	int i;
B
Bjorn Helgaas 已提交
399 400
	struct pnp_irq *irq;

B
Bob Moore 已提交
401
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
402
		return;
403
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
404 405 406
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
407
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
408 409
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
B
Bob Moore 已提交
410
	irq->flags = irq_flags(p->triggering, p->polarity);
L
Linus Torvalds 已提交
411 412 413 414 415

	pnp_register_irq_resource(option, irq);
}

static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
B
Bjorn Helgaas 已提交
416
					 struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
417 418
{
	int i;
B
Bjorn Helgaas 已提交
419
	struct pnp_irq *irq;
L
Linus Torvalds 已提交
420

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

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

	pnp_register_irq_resource(option, irq);
}

B
Bjorn Helgaas 已提交
435 436
static void pnpacpi_parse_port_option(struct pnp_option *option,
				      struct acpi_resource_io *io)
L
Linus Torvalds 已提交
437
{
B
Bjorn Helgaas 已提交
438
	struct pnp_port *port;
L
Linus Torvalds 已提交
439

B
Bob Moore 已提交
440
	if (io->address_length == 0)
L
Linus Torvalds 已提交
441
		return;
442
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
443 444
	if (!port)
		return;
B
Bob Moore 已提交
445 446
	port->min = io->minimum;
	port->max = io->maximum;
L
Linus Torvalds 已提交
447
	port->align = io->alignment;
B
Bob Moore 已提交
448 449
	port->size = io->address_length;
	port->flags = ACPI_DECODE_16 == io->io_decode ?
B
Bjorn Helgaas 已提交
450
	    PNP_PORT_FLAG_16BITADDR : 0;
B
Bjorn Helgaas 已提交
451
	pnp_register_port_resource(option, port);
L
Linus Torvalds 已提交
452 453
}

B
Bjorn Helgaas 已提交
454 455
static void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
					    struct acpi_resource_fixed_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 = port->max = io->address;
	port->size = io->address_length;
L
Linus Torvalds 已提交
466 467
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
B
Bjorn Helgaas 已提交
468
	pnp_register_port_resource(option, port);
L
Linus Torvalds 已提交
469 470
}

B
Bjorn Helgaas 已提交
471 472
static void pnpacpi_parse_mem24_option(struct pnp_option *option,
				       struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
473
{
B
Bjorn Helgaas 已提交
474
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
475

B
Bob Moore 已提交
476
	if (p->address_length == 0)
L
Linus Torvalds 已提交
477
		return;
478
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
479 480
	if (!mem)
		return;
B
Bob Moore 已提交
481 482
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
483
	mem->align = p->alignment;
B
Bob Moore 已提交
484
	mem->size = p->address_length;
L
Linus Torvalds 已提交
485

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

B
Bjorn Helgaas 已提交
489
	pnp_register_mem_resource(option, mem);
L
Linus Torvalds 已提交
490 491
}

B
Bjorn Helgaas 已提交
492 493
static void pnpacpi_parse_mem32_option(struct pnp_option *option,
				       struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
494
{
B
Bjorn Helgaas 已提交
495
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
496

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

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

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

B
Bjorn Helgaas 已提交
513 514
static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
					 struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
515
{
B
Bjorn Helgaas 已提交
516
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
517

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

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

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

B
Bjorn Helgaas 已提交
533 534
static void pnpacpi_parse_address_option(struct pnp_option *option,
					 struct acpi_resource *r)
535 536 537
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
B
Bjorn Helgaas 已提交
538 539
	struct pnp_mem *mem;
	struct pnp_port *port;
540 541 542

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
543 544
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
545 546 547 548 549 550 551
		return;
	}

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

	if (p->resource_type == ACPI_MEMORY_RANGE) {
552
		mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
553 554
		if (!mem)
			return;
L
Len Brown 已提交
555
		mem->min = mem->max = p->minimum;
556 557
		mem->size = p->address_length;
		mem->align = 0;
L
Len Brown 已提交
558
		mem->flags = (p->info.mem.write_protect ==
B
Bjorn Helgaas 已提交
559 560
			      ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
		    : 0;
B
Bjorn Helgaas 已提交
561
		pnp_register_mem_resource(option, mem);
562
	} else if (p->resource_type == ACPI_IO_RANGE) {
563
		port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
564 565
		if (!port)
			return;
L
Len Brown 已提交
566
		port->min = port->max = p->minimum;
567 568 569
		port->size = p->address_length;
		port->align = 0;
		port->flags = PNP_PORT_FLAG_FIXED;
B
Bjorn Helgaas 已提交
570
		pnp_register_port_resource(option, port);
571 572 573
	}
}

L
Linus Torvalds 已提交
574 575
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
576
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
577 578 579
	struct pnp_dev *dev;
};

B
Bob Moore 已提交
580
static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
581
					   void *data)
L
Linus Torvalds 已提交
582 583
{
	int priority = 0;
584
	struct acpipnp_parse_option_s *parse_data = data;
L
Linus Torvalds 已提交
585 586 587
	struct pnp_dev *dev = parse_data->dev;
	struct pnp_option *option = parse_data->option;

588
	switch (res->type) {
B
Bjorn Helgaas 已提交
589 590 591
	case ACPI_RESOURCE_TYPE_IRQ:
		pnpacpi_parse_irq_option(option, &res->data.irq);
		break;
592

B
Bjorn Helgaas 已提交
593 594 595
	case ACPI_RESOURCE_TYPE_DMA:
		pnpacpi_parse_dma_option(option, &res->data.dma);
		break;
596

B
Bjorn Helgaas 已提交
597 598 599 600
	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 已提交
601
			break;
602

B
Bjorn Helgaas 已提交
603 604
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
605
			break;
606

B
Bjorn Helgaas 已提交
607 608
		case ACPI_SUB_OPTIMAL_CONFIGURATION:
			priority = PNP_RES_PRIORITY_FUNCTIONAL;
609
			break;
B
Bjorn Helgaas 已提交
610 611
		default:
			priority = PNP_RES_PRIORITY_INVALID;
612
			break;
B
Bjorn Helgaas 已提交
613
		}
B
Bjorn Helgaas 已提交
614
		/* TBD: Consider performance/robustness bits */
B
Bjorn Helgaas 已提交
615 616 617 618 619
		option = pnp_register_dependent_option(dev, priority);
		if (!option)
			return AE_ERROR;
		parse_data->option = option;
		break;
620

B
Bjorn Helgaas 已提交
621 622 623 624 625 626 627 628 629
	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;
630

B
Bjorn Helgaas 已提交
631 632 633
	case ACPI_RESOURCE_TYPE_IO:
		pnpacpi_parse_port_option(option, &res->data.io);
		break;
634

B
Bjorn Helgaas 已提交
635 636 637
	case ACPI_RESOURCE_TYPE_FIXED_IO:
		pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io);
		break;
638

B
Bjorn Helgaas 已提交
639 640 641
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
642

B
Bjorn Helgaas 已提交
643 644 645
	case ACPI_RESOURCE_TYPE_MEMORY24:
		pnpacpi_parse_mem24_option(option, &res->data.memory24);
		break;
646

B
Bjorn Helgaas 已提交
647 648 649
	case ACPI_RESOURCE_TYPE_MEMORY32:
		pnpacpi_parse_mem32_option(option, &res->data.memory32);
		break;
650

B
Bjorn Helgaas 已提交
651 652 653 654
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
		pnpacpi_parse_fixed_mem32_option(option,
						 &res->data.fixed_memory32);
		break;
655

B
Bjorn Helgaas 已提交
656 657 658 659 660
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
		pnpacpi_parse_address_option(option, res);
		break;
661

B
Bjorn Helgaas 已提交
662 663 664 665 666 667 668 669 670 671 672 673 674
	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 已提交
675
	}
B
Bjorn Helgaas 已提交
676

L
Linus Torvalds 已提交
677 678 679
	return AE_OK;
}

B
Bob Moore 已提交
680
acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle,
B
Bjorn Helgaas 已提交
681
					       struct pnp_dev * dev)
L
Linus Torvalds 已提交
682 683 684 685 686 687 688
{
	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 已提交
689
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
690
	parse_data.dev = dev;
B
Bob Moore 已提交
691
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
692
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
693 694 695 696

	return status;
}

697
static int pnpacpi_supported_resource(struct acpi_resource *res)
L
Linus Torvalds 已提交
698
{
699
	switch (res->type) {
B
Bob Moore 已提交
700 701 702 703 704 705 706 707 708 709
	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:
710
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
711
		return 1;
L
Linus Torvalds 已提交
712
	}
713 714 715 716 717 718 719
	return 0;
}

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
720
					   void *data)
721
{
722
	int *res_cnt = data;
723 724 725

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
726 727 728
	return AE_OK;
}

B
Bjorn Helgaas 已提交
729
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
730
{
731
	struct acpi_resource **resource = data;
732 733

	if (pnpacpi_supported_resource(res)) {
734
		(*resource)->type = res->type;
735
		(*resource)->length = sizeof(struct acpi_resource);
L
Linus Torvalds 已提交
736 737 738 739 740 741
		(*resource)++;
	}

	return AE_OK;
}

B
Bob Moore 已提交
742
int pnpacpi_build_resource_template(acpi_handle handle,
B
Bjorn Helgaas 已提交
743
				    struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
744 745 746 747 748
{
	struct acpi_resource *resource;
	int res_cnt = 0;
	acpi_status status;

B
Bob Moore 已提交
749
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
750
				     pnpacpi_count_resources, &res_cnt);
L
Linus Torvalds 已提交
751 752 753 754 755 756 757
	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;
758
	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
L
Linus Torvalds 已提交
759 760 761 762
	if (!buffer->pointer)
		return -ENOMEM;
	pnp_dbg("Res cnt %d", res_cnt);
	resource = (struct acpi_resource *)buffer->pointer;
B
Bob Moore 已提交
763
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
764
				     pnpacpi_type_resources, &resource);
L
Linus Torvalds 已提交
765 766 767 768 769 770
	if (ACPI_FAILURE(status)) {
		kfree(buffer->pointer);
		pnp_err("Evaluate _CRS failed");
		return -EINVAL;
	}
	/* resource will pointer the end resource now */
B
Bob Moore 已提交
771
	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
L
Linus Torvalds 已提交
772 773 774 775

	return 0;
}

B
Bob Moore 已提交
776
static void pnpacpi_encode_irq(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
777
			       struct resource *p)
L
Linus Torvalds 已提交
778
{
B
Bob Moore 已提交
779
	int triggering, polarity;
B
Bjorn Helgaas 已提交
780 781

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
B
Bob Moore 已提交
782 783 784 785
	resource->data.irq.triggering = triggering;
	resource->data.irq.polarity = polarity;
	if (triggering == ACPI_EDGE_SENSITIVE)
		resource->data.irq.sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
786
	else
B
Bob Moore 已提交
787 788
		resource->data.irq.sharable = ACPI_SHARED;
	resource->data.irq.interrupt_count = 1;
L
Linus Torvalds 已提交
789 790 791 792
	resource->data.irq.interrupts[0] = p->start;
}

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

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
L
Linus Torvalds 已提交
798
	resource->data.extended_irq.producer_consumer = ACPI_CONSUMER;
B
Bob Moore 已提交
799 800 801 802
	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 已提交
803
	else
B
Bob Moore 已提交
804 805
		resource->data.irq.sharable = ACPI_SHARED;
	resource->data.extended_irq.interrupt_count = 1;
L
Linus Torvalds 已提交
806 807 808 809
	resource->data.extended_irq.interrupts[0] = p->start;
}

static void pnpacpi_encode_dma(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
810
			       struct resource *p)
L
Linus Torvalds 已提交
811 812
{
	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
813
	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
B
Bjorn Helgaas 已提交
814 815 816 817 818 819 820 821 822 823 824
	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;
825 826 827
	}

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
828 829 830 831 832 833 834 835
	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;
836 837 838
	}

	resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
B
Bob Moore 已提交
839
	resource->data.dma.channel_count = 1;
L
Linus Torvalds 已提交
840 841 842 843
	resource->data.dma.channels[0] = p->start;
}

static void pnpacpi_encode_io(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
844
			      struct resource *p)
L
Linus Torvalds 已提交
845 846
{
	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
B
Bjorn Helgaas 已提交
847 848
	resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
	    ACPI_DECODE_16 : ACPI_DECODE_10;
B
Bob Moore 已提交
849 850
	resource->data.io.minimum = p->start;
	resource->data.io.maximum = p->end;
B
Bjorn Helgaas 已提交
851
	resource->data.io.alignment = 0;	/* Correct? */
B
Bob Moore 已提交
852
	resource->data.io.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
853 854 855
}

static void pnpacpi_encode_fixed_io(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
856
				    struct resource *p)
L
Linus Torvalds 已提交
857
{
B
Bob Moore 已提交
858 859
	resource->data.fixed_io.address = p->start;
	resource->data.fixed_io.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
860 861 862
}

static void pnpacpi_encode_mem24(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
863
				 struct resource *p)
L
Linus Torvalds 已提交
864 865
{
	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
B
Bob Moore 已提交
866
	resource->data.memory24.write_protect =
B
Bjorn Helgaas 已提交
867 868
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
B
Bob Moore 已提交
869 870
	resource->data.memory24.minimum = p->start;
	resource->data.memory24.maximum = p->end;
L
Linus Torvalds 已提交
871
	resource->data.memory24.alignment = 0;
B
Bob Moore 已提交
872
	resource->data.memory24.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
873 874 875
}

static void pnpacpi_encode_mem32(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
876
				 struct resource *p)
L
Linus Torvalds 已提交
877
{
B
Bob Moore 已提交
878
	resource->data.memory32.write_protect =
B
Bjorn Helgaas 已提交
879 880
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
B
Bob Moore 已提交
881 882
	resource->data.memory32.minimum = p->start;
	resource->data.memory32.maximum = p->end;
L
Linus Torvalds 已提交
883
	resource->data.memory32.alignment = 0;
B
Bob Moore 已提交
884
	resource->data.memory32.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
885 886 887
}

static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
888
				       struct resource *p)
L
Linus Torvalds 已提交
889
{
B
Bob Moore 已提交
890
	resource->data.fixed_memory32.write_protect =
B
Bjorn Helgaas 已提交
891 892
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
B
Bob Moore 已提交
893 894
	resource->data.fixed_memory32.address = p->start;
	resource->data.fixed_memory32.address_length = p->end - p->start + 1;
L
Linus Torvalds 已提交
895 896
}

B
Bob Moore 已提交
897
int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
B
Bjorn Helgaas 已提交
898
			     struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
899 900 901
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
902
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
903
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
904 905 906 907
	int port = 0, irq = 0, dma = 0, mem = 0;

	pnp_dbg("res cnt %d", res_cnt);
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
908
		switch (resource->type) {
B
Bob Moore 已提交
909
		case ACPI_RESOURCE_TYPE_IRQ:
L
Linus Torvalds 已提交
910
			pnp_dbg("Encode irq");
B
Bob Moore 已提交
911
			pnpacpi_encode_irq(resource,
B
Bjorn Helgaas 已提交
912
					   &res_table->irq_resource[irq]);
L
Linus Torvalds 已提交
913 914 915
			irq++;
			break;

B
Bob Moore 已提交
916
		case ACPI_RESOURCE_TYPE_DMA:
L
Linus Torvalds 已提交
917
			pnp_dbg("Encode dma");
B
Bob Moore 已提交
918
			pnpacpi_encode_dma(resource,
B
Bjorn Helgaas 已提交
919
					   &res_table->dma_resource[dma]);
B
Bjorn Helgaas 已提交
920
			dma++;
L
Linus Torvalds 已提交
921
			break;
B
Bob Moore 已提交
922
		case ACPI_RESOURCE_TYPE_IO:
L
Linus Torvalds 已提交
923
			pnp_dbg("Encode io");
B
Bob Moore 已提交
924
			pnpacpi_encode_io(resource,
B
Bjorn Helgaas 已提交
925
					  &res_table->port_resource[port]);
B
Bjorn Helgaas 已提交
926
			port++;
L
Linus Torvalds 已提交
927
			break;
B
Bob Moore 已提交
928
		case ACPI_RESOURCE_TYPE_FIXED_IO:
L
Linus Torvalds 已提交
929 930
			pnp_dbg("Encode fixed io");
			pnpacpi_encode_fixed_io(resource,
B
Bjorn Helgaas 已提交
931 932
						&res_table->
						port_resource[port]);
B
Bjorn Helgaas 已提交
933
			port++;
L
Linus Torvalds 已提交
934
			break;
B
Bob Moore 已提交
935
		case ACPI_RESOURCE_TYPE_MEMORY24:
L
Linus Torvalds 已提交
936 937
			pnp_dbg("Encode mem24");
			pnpacpi_encode_mem24(resource,
B
Bjorn Helgaas 已提交
938
					     &res_table->mem_resource[mem]);
B
Bjorn Helgaas 已提交
939
			mem++;
L
Linus Torvalds 已提交
940
			break;
B
Bob Moore 已提交
941
		case ACPI_RESOURCE_TYPE_MEMORY32:
L
Linus Torvalds 已提交
942 943
			pnp_dbg("Encode mem32");
			pnpacpi_encode_mem32(resource,
B
Bjorn Helgaas 已提交
944
					     &res_table->mem_resource[mem]);
B
Bjorn Helgaas 已提交
945
			mem++;
L
Linus Torvalds 已提交
946
			break;
B
Bob Moore 已提交
947
		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
L
Linus Torvalds 已提交
948 949
			pnp_dbg("Encode fixed mem32");
			pnpacpi_encode_fixed_mem32(resource,
B
Bjorn Helgaas 已提交
950 951
						   &res_table->
						   mem_resource[mem]);
B
Bjorn Helgaas 已提交
952
			mem++;
L
Linus Torvalds 已提交
953
			break;
954 955 956
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
			pnp_dbg("Encode ext irq");
			pnpacpi_encode_ext_irq(resource,
B
Bjorn Helgaas 已提交
957
					       &res_table->irq_resource[irq]);
958 959 960 961 962 963 964 965 966 967 968
			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 已提交
969
		default:	/* other type */
970
			pnp_warn("unknown resource type %d", resource->type);
L
Linus Torvalds 已提交
971 972
			return -EINVAL;
		}
B
Bjorn Helgaas 已提交
973 974
		resource++;
		i++;
L
Linus Torvalds 已提交
975 976 977
	}
	return 0;
}