File Index
Files and directories
Sign in
FILE

core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/pnp/isapnp/core.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  ISA Plug & Play support
   4 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   5 *
   6 *  Changelog:
   7 *  2000-01-01	Added quirks handling for buggy hardware
   8 *		Peter Denison <peterd@pnd-pc.demon.co.uk>
   9 *  2000-06-14	Added isapnp_probe_devs() and isapnp_activate_dev()
  10 *		Christoph Hellwig <hch@infradead.org>
  11 *  2001-06-03  Added release_region calls to correspond with
  12 *		request_region calls when a failure occurs.  Also
  13 *		added KERN_* constants to printk() calls.
  14 *  2001-11-07  Added isapnp_{,un}register_driver calls along the lines
  15 *              of the pci driver interface
  16 *              Kai Germaschewski <kai.germaschewski@gmx.de>
  17 *  2002-06-06  Made the use of dma channel 0 configurable
  18 *              Gerald Teschl <gerald.teschl@univie.ac.at>
  19 *  2002-10-06  Ported to PnP Layer - Adam Belay <ambx1@neo.rr.com>
  20 *  2003-08-11	Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
  21 */
  22
  23#include <linux/moduleparam.h>
  24#include <linux/kernel.h>
  25#include <linux/errno.h>
  26#include <linux/delay.h>
  27#include <linux/init.h>
  28#include <linux/isapnp.h>
  29#include <linux/mutex.h>
  30#include <linux/string_choices.h>
  31#include <asm/io.h>
  32
  33#include "../base.h"
  34
  35#if 0
  36#define ISAPNP_REGION_OK
  37#endif
  38
  39int isapnp_disable;		/* Disable ISA PnP */
  40static int isapnp_rdp;		/* Read Data Port */
  41static int isapnp_reset = 1;	/* reset all PnP cards (deactivate) */
  42static int isapnp_verbose = 1;	/* verbose mode */
  43
  44module_param(isapnp_disable, int, 0);
  45MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
  46module_param(isapnp_rdp, int, 0);
  47MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
  48module_param(isapnp_reset, int, 0);
  49MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
  50module_param(isapnp_verbose, int, 0);
  51MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
  52
  53#define _PIDXR		0x279
  54#define _PNPWRP		0xa79
  55
  56/* short tags */
  57#define _STAG_PNPVERNO		0x01
  58#define _STAG_LOGDEVID		0x02
  59#define _STAG_COMPATDEVID	0x03
  60#define _STAG_IRQ		0x04
  61#define _STAG_DMA		0x05
  62#define _STAG_STARTDEP		0x06
  63#define _STAG_ENDDEP		0x07
  64#define _STAG_IOPORT		0x08
  65#define _STAG_FIXEDIO		0x09
  66#define _STAG_VENDOR		0x0e
  67#define _STAG_END		0x0f
  68/* long tags */
  69#define _LTAG_MEMRANGE		0x81
  70#define _LTAG_ANSISTR		0x82
  71#define _LTAG_UNICODESTR	0x83
  72#define _LTAG_VENDOR		0x84
  73#define _LTAG_MEM32RANGE	0x85
  74#define _LTAG_FIXEDMEM32RANGE	0x86
  75
  76/* Logical device control and configuration registers */
  77
  78#define ISAPNP_CFG_ACTIVATE	0x30	/* byte */
  79#define ISAPNP_CFG_MEM		0x40	/* 4 * dword */
  80#define ISAPNP_CFG_PORT		0x60	/* 8 * word */
  81#define ISAPNP_CFG_IRQ		0x70	/* 2 * word */
  82#define ISAPNP_CFG_DMA		0x74	/* 2 * byte */
  83
  84/*
  85 * Sizes of ISAPNP logical device configuration register sets.
  86 * See PNP-ISA-v1.0a.pdf, Appendix A.
  87 */
  88#define ISAPNP_MAX_MEM		4
  89#define ISAPNP_MAX_PORT		8
  90#define ISAPNP_MAX_IRQ		2
  91#define ISAPNP_MAX_DMA		2
  92
  93static unsigned char isapnp_checksum_value;
  94static DEFINE_MUTEX(isapnp_cfg_mutex);
  95static int isapnp_csn_count;
  96
  97/* some prototypes */
  98
  99static inline void write_data(unsigned char x)
 100{
 101	outb(x, _PNPWRP);
 102}
 103
 104static inline void write_address(unsigned char x)
 105{
 106	outb(x, _PIDXR);
 107	udelay(20);
 108}
 109
 110static inline unsigned char read_data(void)
 111{
 112	unsigned char val = inb(isapnp_rdp);
 113	return val;
 114}
 115
 116unsigned char isapnp_read_byte(unsigned char idx)
 117{
 118	write_address(idx);
 119	return read_data();
 120}
 121
 122static unsigned short isapnp_read_word(unsigned char idx)
 123{
 124	unsigned short val;
 125
 126	val = isapnp_read_byte(idx);
 127	val = (val << 8) + isapnp_read_byte(idx + 1);
 128	return val;
 129}
 130
 131void isapnp_write_byte(unsigned char idx, unsigned char val)
 132{
 133	write_address(idx);
 134	write_data(val);
 135}
 136
 137static void isapnp_write_word(unsigned char idx, unsigned short val)
 138{
 139	isapnp_write_byte(idx, val >> 8);
 140	isapnp_write_byte(idx + 1, val);
 141}
 142
 143static void isapnp_key(void)
 144{
 145	unsigned char code = 0x6a, msb;
 146	int i;
 147
 148	mdelay(1);
 149	write_address(0x00);
 150	write_address(0x00);
 151
 152	write_address(code);
 153
 154	for (i = 1; i < 32; i++) {
 155		msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
 156		code = (code >> 1) | msb;
 157		write_address(code);
 158	}
 159}
 160
 161/* place all pnp cards in wait-for-key state */
 162static void isapnp_wait(void)
 163{
 164	isapnp_write_byte(0x02, 0x02);
 165}
 166
 167static void isapnp_wake(unsigned char csn)
 168{
 169	isapnp_write_byte(0x03, csn);
 170}
 171
 172static void isapnp_device(unsigned char logdev)
 173{
 174	isapnp_write_byte(0x07, logdev);
 175}
 176
 177static void isapnp_activate(unsigned char logdev)
 178{
 179	isapnp_device(logdev);
 180	isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
 181	udelay(250);
 182}
 183
 184static void isapnp_deactivate(unsigned char logdev)
 185{
 186	isapnp_device(logdev);
 187	isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
 188	udelay(500);
 189}
 190
 191static void __init isapnp_peek(unsigned char *data, int bytes)
 192{
 193	int i, j;
 194	unsigned char d = 0;
 195
 196	for (i = 1; i <= bytes; i++) {
 197		for (j = 0; j < 20; j++) {
 198			d = isapnp_read_byte(0x05);
 199			if (d & 1)
 200				break;
 201			udelay(100);
 202		}
 203		if (!(d & 1)) {
 204			if (data != NULL)
 205				*data++ = 0xff;
 206			continue;
 207		}
 208		d = isapnp_read_byte(0x04);	/* PRESDI */
 209		isapnp_checksum_value += d;
 210		if (data != NULL)
 211			*data++ = d;
 212	}
 213}
 214
 215#define RDP_STEP	32	/* minimum is 4 */
 216
 217static int isapnp_next_rdp(void)
 218{
 219	int rdp = isapnp_rdp;
 220	static int old_rdp = 0;
 221
 222	if (old_rdp) {
 223		release_region(old_rdp, 1);
 224		old_rdp = 0;
 225	}
 226	while (rdp <= 0x3ff) {
 227		/*
 228		 *      We cannot use NE2000 probe spaces for ISAPnP or we
 229		 *      will lock up machines.
 230		 */
 231		if ((rdp < 0x280 || rdp > 0x380)
 232		    && request_region(rdp, 1, "ISAPnP")) {
 233			isapnp_rdp = rdp;
 234			old_rdp = rdp;
 235			return 0;
 236		}
 237		rdp += RDP_STEP;
 238	}
 239	return -1;
 240}
 241
 242/* Set read port address */
 243static inline void isapnp_set_rdp(void)
 244{
 245	isapnp_write_byte(0x00, isapnp_rdp >> 2);
 246	udelay(100);
 247}
 248
 249/*
 250 *	Perform an isolation. The port selection code now tries to avoid
 251 *	"dangerous to read" ports.
 252 */
 253static int __init isapnp_isolate_rdp_select(void)
 254{
 255	isapnp_wait();
 256	isapnp_key();
 257
 258	/* Control: reset CSN and conditionally everything else too */
 259	isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
 260	mdelay(2);
 261
 262	isapnp_wait();
 263	isapnp_key();
 264	isapnp_wake(0x00);
 265
 266	if (isapnp_next_rdp() < 0) {
 267		isapnp_wait();
 268		return -1;
 269	}
 270
 271	isapnp_set_rdp();
 272	udelay(1000);
 273	write_address(0x01);
 274	udelay(1000);
 275	return 0;
 276}
 277
 278/*
 279 *  Isolate (assign uniqued CSN) to all ISA PnP devices.
 280 */
 281static int __init isapnp_isolate(void)
 282{
 283	unsigned char checksum = 0x6a;
 284	unsigned char chksum = 0x00;
 285	unsigned char bit = 0x00;
 286	int data;
 287	int csn = 0;
 288	int i;
 289	int iteration = 1;
 290
 291	isapnp_rdp = 0x213;
 292	if (isapnp_isolate_rdp_select() < 0)
 293		return -1;
 294
 295	while (1) {
 296		for (i = 1; i <= 64; i++) {
 297			data = read_data() << 8;
 298			udelay(250);
 299			data = data | read_data();
 300			udelay(250);
 301			if (data == 0x55aa)
 302				bit = 0x01;
 303			checksum =
 304			    ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
 305			    | (checksum >> 1);
 306			bit = 0x00;
 307		}
 308		for (i = 65; i <= 72; i++) {
 309			data = read_data() << 8;
 310			udelay(250);
 311			data = data | read_data();
 312			udelay(250);
 313			if (data == 0x55aa)
 314				chksum |= (1 << (i - 65));
 315		}
 316		if (checksum != 0x00 && checksum == chksum) {
 317			csn++;
 318
 319			isapnp_write_byte(0x06, csn);
 320			udelay(250);
 321			iteration++;
 322			isapnp_wake(0x00);
 323			isapnp_set_rdp();
 324			udelay(1000);
 325			write_address(0x01);
 326			udelay(1000);
 327			goto __next;
 328		}
 329		if (iteration == 1) {
 330			isapnp_rdp += RDP_STEP;
 331			if (isapnp_isolate_rdp_select() < 0)
 332				return -1;
 333		} else if (iteration > 1) {
 334			break;
 335		}
 336__next:
 337		if (csn == 255)
 338			break;
 339		checksum = 0x6a;
 340		chksum = 0x00;
 341		bit = 0x00;
 342	}
 343	isapnp_wait();
 344	isapnp_csn_count = csn;
 345	return csn;
 346}
 347
 348/*
 349 *  Read one tag from stream.
 350 */
 351static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
 352{
 353	unsigned char tag, tmp[2];
 354
 355	isapnp_peek(&tag, 1);
 356	if (tag == 0)		/* invalid tag */
 357		return -1;
 358	if (tag & 0x80) {	/* large item */
 359		*type = tag;
 360		isapnp_peek(tmp, 2);
 361		*size = (tmp[1] << 8) | tmp[0];
 362	} else {
 363		*type = (tag >> 3) & 0x0f;
 364		*size = tag & 0x07;
 365	}
 366	if (*type == 0xff && *size == 0xffff)	/* probably invalid data */
 367		return -1;
 368	return 0;
 369}
 370
 371/*
 372 *  Skip specified number of bytes from stream.
 373 */
 374static void __init isapnp_skip_bytes(int count)
 375{
 376	isapnp_peek(NULL, count);
 377}
 378
 379/*
 380 *  Parse logical device tag.
 381 */
 382static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
 383						  int size, int number)
 384{
 385	unsigned char tmp[6];
 386	struct pnp_dev *dev;
 387	u32 eisa_id;
 388	char id[8];
 389
 390	isapnp_peek(tmp, size);
 391	eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
 392	pnp_eisa_id_to_string(eisa_id, id);
 393
 394	dev = pnp_alloc_dev(&isapnp_protocol, number, id);
 395	if (!dev)
 396		return NULL;
 397
 398	dev->card = card;
 399	dev->capabilities |= PNP_CONFIGURABLE;
 400	dev->capabilities |= PNP_READ;
 401	dev->capabilities |= PNP_WRITE;
 402	dev->capabilities |= PNP_DISABLE;
 403	pnp_init_resources(dev);
 404	return dev;
 405}
 406
 407/*
 408 *  Add IRQ resource to resources list.
 409 */
 410static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
 411					     unsigned int option_flags,
 412					     int size)
 413{
 414	unsigned char tmp[3];
 415	unsigned long bits;
 416	pnp_irq_mask_t map;
 417	unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
 418
 419	isapnp_peek(tmp, size);
 420	bits = (tmp[1] << 8) | tmp[0];
 421
 422	bitmap_zero(map.bits, PNP_IRQ_NR);
 423	bitmap_copy(map.bits, &bits, 16);
 424
 425	if (size > 2)
 426		flags = tmp[2];
 427
 428	pnp_register_irq_resource(dev, option_flags, &map, flags);
 429}
 430
 431/*
 432 *  Add DMA resource to resources list.
 433 */
 434static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
 435					     unsigned int option_flags,
 436					     int size)
 437{
 438	unsigned char tmp[2];
 439
 440	isapnp_peek(tmp, size);
 441	pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
 442}
 443
 444/*
 445 *  Add port resource to resources list.
 446 */
 447static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
 448					      unsigned int option_flags,
 449					      int size)
 450{
 451	unsigned char tmp[7];
 452	resource_size_t min, max, align, len;
 453	unsigned char flags;
 454
 455	isapnp_peek(tmp, size);
 456	min = (tmp[2] << 8) | tmp[1];
 457	max = (tmp[4] << 8) | tmp[3];
 458	align = tmp[5];
 459	len = tmp[6];
 460	flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
 461	pnp_register_port_resource(dev, option_flags,
 462				   min, max, align, len, flags);
 463}
 464
 465/*
 466 *  Add fixed port resource to resources list.
 467 */
 468static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
 469						    unsigned int option_flags,
 470						    int size)
 471{
 472	unsigned char tmp[3];
 473	resource_size_t base, len;
 474
 475	isapnp_peek(tmp, size);
 476	base = (tmp[1] << 8) | tmp[0];
 477	len = tmp[2];
 478	pnp_register_port_resource(dev, option_flags, base, base, 0, len,
 479				   IORESOURCE_IO_FIXED);
 480}
 481
 482/*
 483 *  Add memory resource to resources list.
 484 */
 485static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
 486					     unsigned int option_flags,
 487					     int size)
 488{
 489	unsigned char tmp[9];
 490	resource_size_t min, max, align, len;
 491	unsigned char flags;
 492
 493	isapnp_peek(tmp, size);
 494	min = ((tmp[2] << 8) | tmp[1]) << 8;
 495	max = ((tmp[4] << 8) | tmp[3]) << 8;
 496	align = (tmp[6] << 8) | tmp[5];
 497	len = ((tmp[8] << 8) | tmp[7]) << 8;
 498	flags = tmp[0];
 499	pnp_register_mem_resource(dev, option_flags,
 500				  min, max, align, len, flags);
 501}
 502
 503/*
 504 *  Add 32-bit memory resource to resources list.
 505 */
 506static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
 507					       unsigned int option_flags,
 508					       int size)
 509{
 510	unsigned char tmp[17];
 511	resource_size_t min, max, align, len;
 512	unsigned char flags;
 513
 514	isapnp_peek(tmp, size);
 515	min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
 516	max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
 517	align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
 518	len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
 519	flags = tmp[0];
 520	pnp_register_mem_resource(dev, option_flags,
 521				  min, max, align, len, flags);
 522}
 523
 524/*
 525 *  Add 32-bit fixed memory resource to resources list.
 526 */
 527static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
 528						     unsigned int option_flags,
 529						     int size)
 530{
 531	unsigned char tmp[9];
 532	resource_size_t base, len;
 533	unsigned char flags;
 534
 535	isapnp_peek(tmp, size);
 536	base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
 537	len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
 538	flags = tmp[0];
 539	pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
 540}
 541
 542/*
 543 *  Parse card name for ISA PnP device.
 544 */
 545static void __init
 546isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
 547{
 548	if (name[0] == '\0') {
 549		unsigned short size1 =
 550		    *size >= name_max ? (name_max - 1) : *size;
 551		isapnp_peek(name, size1);
 552		name[size1] = '\0';
 553		*size -= size1;
 554
 555		/* clean whitespace from end of string */
 556		while (size1 > 0 && name[--size1] == ' ')
 557			name[size1] = '\0';
 558	}
 559}
 560
 561/*
 562 *  Parse resource map for logical device.
 563 */
 564static int __init isapnp_create_device(struct pnp_card *card,
 565				       unsigned short size)
 566{
 567	int number = 0, skip = 0, priority, compat = 0;
 568	unsigned char type, tmp[17];
 569	unsigned int option_flags;
 570	struct pnp_dev *dev;
 571	u32 eisa_id;
 572	char id[8];
 573
 574	if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 575		return 1;
 576	option_flags = 0;
 577	pnp_add_card_device(card, dev);
 578
 579	while (1) {
 580		if (isapnp_read_tag(&type, &size) < 0)
 581			return 1;
 582		if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
 583			goto __skip;
 584		switch (type) {
 585		case _STAG_LOGDEVID:
 586			if (size >= 5 && size <= 6) {
 587				if ((dev =
 588				     isapnp_parse_device(card, size,
 589							 number++)) == NULL)
 590					return 1;
 591				size = 0;
 592				skip = 0;
 593				option_flags = 0;
 594				pnp_add_card_device(card, dev);
 595			} else {
 596				skip = 1;
 597			}
 598			compat = 0;
 599			break;
 600		case _STAG_COMPATDEVID:
 601			if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
 602				isapnp_peek(tmp, 4);
 603				eisa_id = tmp[0] | tmp[1] << 8 |
 604					  tmp[2] << 16 | tmp[3] << 24;
 605				pnp_eisa_id_to_string(eisa_id, id);
 606				pnp_add_id(dev, id);
 607				compat++;
 608				size = 0;
 609			}
 610			break;
 611		case _STAG_IRQ:
 612			if (size < 2 || size > 3)
 613				goto __skip;
 614			isapnp_parse_irq_resource(dev, option_flags, size);
 615			size = 0;
 616			break;
 617		case _STAG_DMA:
 618			if (size != 2)
 619				goto __skip;
 620			isapnp_parse_dma_resource(dev, option_flags, size);
 621			size = 0;
 622			break;
 623		case _STAG_STARTDEP:
 624			if (size > 1)
 625				goto __skip;
 626			priority = PNP_RES_PRIORITY_ACCEPTABLE;
 627			if (size > 0) {
 628				isapnp_peek(tmp, size);
 629				priority = tmp[0];
 630				size = 0;
 631			}
 632			option_flags = pnp_new_dependent_set(dev, priority);
 633			break;
 634		case _STAG_ENDDEP:
 635			if (size != 0)
 636				goto __skip;
 637			option_flags = 0;
 638			break;
 639		case _STAG_IOPORT:
 640			if (size != 7)
 641				goto __skip;
 642			isapnp_parse_port_resource(dev, option_flags, size);
 643			size = 0;
 644			break;
 645		case _STAG_FIXEDIO:
 646			if (size != 3)
 647				goto __skip;
 648			isapnp_parse_fixed_port_resource(dev, option_flags,
 649							 size);
 650			size = 0;
 651			break;
 652		case _STAG_VENDOR:
 653			break;
 654		case _LTAG_MEMRANGE:
 655			if (size != 9)
 656				goto __skip;
 657			isapnp_parse_mem_resource(dev, option_flags, size);
 658			size = 0;
 659			break;
 660		case _LTAG_ANSISTR:
 661			isapnp_parse_name(dev->name, sizeof(dev->name), &size);
 662			break;
 663		case _LTAG_UNICODESTR:
 664			/* silently ignore */
 665			/* who use unicode for hardware identification? */
 666			break;
 667		case _LTAG_VENDOR:
 668			break;
 669		case _LTAG_MEM32RANGE:
 670			if (size != 17)
 671				goto __skip;
 672			isapnp_parse_mem32_resource(dev, option_flags, size);
 673			size = 0;
 674			break;
 675		case _LTAG_FIXEDMEM32RANGE:
 676			if (size != 9)
 677				goto __skip;
 678			isapnp_parse_fixed_mem32_resource(dev, option_flags,
 679							  size);
 680			size = 0;
 681			break;
 682		case _STAG_END:
 683			if (size > 0)
 684				isapnp_skip_bytes(size);
 685			return 1;
 686		default:
 687			dev_err(&dev->dev, "unknown tag %#x (card %i), "
 688				"ignored\n", type, card->number);
 689		}
 690__skip:
 691		if (size > 0)
 692			isapnp_skip_bytes(size);
 693	}
 694	return 0;
 695}
 696
 697/*
 698 *  Parse resource map for ISA PnP card.
 699 */
 700static void __init isapnp_parse_resource_map(struct pnp_card *card)
 701{
 702	unsigned char type, tmp[17];
 703	unsigned short size;
 704
 705	while (1) {
 706		if (isapnp_read_tag(&type, &size) < 0)
 707			return;
 708		switch (type) {
 709		case _STAG_PNPVERNO:
 710			if (size != 2)
 711				goto __skip;
 712			isapnp_peek(tmp, 2);
 713			card->pnpver = tmp[0];
 714			card->productver = tmp[1];
 715			size = 0;
 716			break;
 717		case _STAG_LOGDEVID:
 718			if (size >= 5 && size <= 6) {
 719				if (isapnp_create_device(card, size) == 1)
 720					return;
 721				size = 0;
 722			}
 723			break;
 724		case _STAG_VENDOR:
 725			break;
 726		case _LTAG_ANSISTR:
 727			isapnp_parse_name(card->name, sizeof(card->name),
 728					  &size);
 729			break;
 730		case _LTAG_UNICODESTR:
 731			/* silently ignore */
 732			/* who use unicode for hardware identification? */
 733			break;
 734		case _LTAG_VENDOR:
 735			break;
 736		case _STAG_END:
 737			if (size > 0)
 738				isapnp_skip_bytes(size);
 739			return;
 740		default:
 741			dev_err(&card->dev, "unknown tag %#x, ignored\n",
 742			       type);
 743		}
 744__skip:
 745		if (size > 0)
 746			isapnp_skip_bytes(size);
 747	}
 748}
 749
 750/*
 751 *  Build device list for all present ISA PnP devices.
 752 */
 753static int __init isapnp_build_device_list(void)
 754{
 755	int csn;
 756	unsigned char header[9];
 757	struct pnp_card *card;
 758	u32 eisa_id;
 759	char id[8];
 760
 761	isapnp_wait();
 762	isapnp_key();
 763	for (csn = 1; csn <= isapnp_csn_count; csn++) {
 764		isapnp_wake(csn);
 765		isapnp_peek(header, 9);
 766		eisa_id = header[0] | header[1] << 8 |
 767			  header[2] << 16 | header[3] << 24;
 768		pnp_eisa_id_to_string(eisa_id, id);
 769		card = pnp_alloc_card(&isapnp_protocol, csn, id);
 770		if (!card)
 771			continue;
 772
 773		INIT_LIST_HEAD(&card->devices);
 774		card->serial =
 775		    (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
 776		    header[4];
 777		isapnp_checksum_value = 0x00;
 778		isapnp_parse_resource_map(card);
 779		if (isapnp_checksum_value != 0x00)
 780			dev_err(&card->dev, "invalid checksum %#x\n",
 781				isapnp_checksum_value);
 782		card->checksum = isapnp_checksum_value;
 783
 784		pnp_add_card(card);
 785	}
 786	isapnp_wait();
 787	return 0;
 788}
 789
 790/*
 791 *  Basic configuration routines.
 792 */
 793
 794int isapnp_present(void)
 795{
 796	struct pnp_card *card;
 797
 798	pnp_for_each_card(card) {
 799		if (card->protocol == &isapnp_protocol)
 800			return 1;
 801	}
 802	return 0;
 803}
 804
 805int isapnp_cfg_begin(int csn, int logdev)
 806{
 807	if (csn < 1 || csn > isapnp_csn_count || logdev > 10)
 808		return -EINVAL;
 809	mutex_lock(&isapnp_cfg_mutex);
 810	isapnp_wait();
 811	isapnp_key();
 812	isapnp_wake(csn);
 813#if 0
 814	/* to avoid malfunction when the isapnptools package is used */
 815	/* we must set RDP to our value again */
 816	/* it is possible to set RDP only in the isolation phase */
 817	/*   Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
 818	isapnp_write_byte(0x02, 0x04);	/* clear CSN of card */
 819	mdelay(2);		/* is this necessary? */
 820	isapnp_wake(csn);	/* bring card into sleep state */
 821	isapnp_wake(0);		/* bring card into isolation state */
 822	isapnp_set_rdp();	/* reset the RDP port */
 823	udelay(1000);		/* delay 1000us */
 824	isapnp_write_byte(0x06, csn);	/* reset CSN to previous value */
 825	udelay(250);		/* is this necessary? */
 826#endif
 827	if (logdev >= 0)
 828		isapnp_device(logdev);
 829	return 0;
 830}
 831
 832int isapnp_cfg_end(void)
 833{
 834	isapnp_wait();
 835	mutex_unlock(&isapnp_cfg_mutex);
 836	return 0;
 837}
 838
 839/*
 840 *  Initialization.
 841 */
 842
 843EXPORT_SYMBOL(isapnp_protocol);
 844EXPORT_SYMBOL(isapnp_present);
 845EXPORT_SYMBOL(isapnp_cfg_begin);
 846EXPORT_SYMBOL(isapnp_cfg_end);
 847EXPORT_SYMBOL(isapnp_read_byte);
 848EXPORT_SYMBOL(isapnp_write_byte);
 849
 850static int isapnp_get_resources(struct pnp_dev *dev)
 851{
 852	int i, ret;
 853
 854	pnp_dbg(&dev->dev, "get resources\n");
 855	pnp_init_resources(dev);
 856	isapnp_cfg_begin(dev->card->number, dev->number);
 857	dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
 858	if (!dev->active)
 859		goto __end;
 860
 861	for (i = 0; i < ISAPNP_MAX_PORT; i++) {
 862		ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
 863		pnp_add_io_resource(dev, ret, ret,
 864				    ret == 0 ? IORESOURCE_DISABLED : 0);
 865	}
 866	for (i = 0; i < ISAPNP_MAX_MEM; i++) {
 867		ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
 868		pnp_add_mem_resource(dev, ret, ret,
 869				     ret == 0 ? IORESOURCE_DISABLED : 0);
 870	}
 871	for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
 872		ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
 873		pnp_add_irq_resource(dev, ret,
 874				     ret == 0 ? IORESOURCE_DISABLED : 0);
 875	}
 876	for (i = 0; i < ISAPNP_MAX_DMA; i++) {
 877		ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
 878		pnp_add_dma_resource(dev, ret,
 879				     ret == 4 ? IORESOURCE_DISABLED : 0);
 880	}
 881
 882__end:
 883	isapnp_cfg_end();
 884	return 0;
 885}
 886
 887static int isapnp_set_resources(struct pnp_dev *dev)
 888{
 889	struct resource *res;
 890	int tmp;
 891
 892	pnp_dbg(&dev->dev, "set resources\n");
 893	isapnp_cfg_begin(dev->card->number, dev->number);
 894	dev->active = 1;
 895	for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
 896		res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
 897		if (pnp_resource_enabled(res)) {
 898			pnp_dbg(&dev->dev, "  set io  %d to %#llx\n",
 899				tmp, (unsigned long long) res->start);
 900			isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
 901					  res->start);
 902		}
 903	}
 904	for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
 905		res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
 906		if (pnp_resource_enabled(res)) {
 907			int irq = res->start;
 908			if (irq == 2)
 909				irq = 9;
 910			pnp_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
 911			isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
 912		}
 913	}
 914	for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
 915		res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
 916		if (pnp_resource_enabled(res)) {
 917			pnp_dbg(&dev->dev, "  set dma %d to %lld\n",
 918				tmp, (unsigned long long) res->start);
 919			isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
 920		}
 921	}
 922	for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
 923		res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
 924		if (pnp_resource_enabled(res)) {
 925			pnp_dbg(&dev->dev, "  set mem %d to %#llx\n",
 926				tmp, (unsigned long long) res->start);
 927			isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
 928					  (res->start >> 8) & 0xffff);
 929		}
 930	}
 931	/* FIXME: We aren't handling 32bit mems properly here */
 932	isapnp_activate(dev->number);
 933	isapnp_cfg_end();
 934	return 0;
 935}
 936
 937static int isapnp_disable_resources(struct pnp_dev *dev)
 938{
 939	if (!dev->active)
 940		return -EINVAL;
 941	isapnp_cfg_begin(dev->card->number, dev->number);
 942	isapnp_deactivate(dev->number);
 943	dev->active = 0;
 944	isapnp_cfg_end();
 945	return 0;
 946}
 947
 948struct pnp_protocol isapnp_protocol = {
 949	.name = "ISA Plug and Play",
 950	.get = isapnp_get_resources,
 951	.set = isapnp_set_resources,
 952	.disable = isapnp_disable_resources,
 953};
 954
 955static int __init isapnp_init(void)
 956{
 957	int cards;
 958	struct pnp_card *card;
 959	struct pnp_dev *dev;
 960
 961	if (isapnp_disable) {
 962		printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
 963		return 0;
 964	}
 965#ifdef CONFIG_PPC
 966	if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
 967		return -EINVAL;
 968#endif
 969#ifdef ISAPNP_REGION_OK
 970	if (!request_region(_PIDXR, 1, "isapnp index")) {
 971		printk(KERN_ERR "isapnp: Index Register 0x%x already used\n",
 972		       _PIDXR);
 973		return -EBUSY;
 974	}
 975#endif
 976	if (!request_region(_PNPWRP, 1, "isapnp write")) {
 977		printk(KERN_ERR
 978		       "isapnp: Write Data Register 0x%x already used\n",
 979		       _PNPWRP);
 980#ifdef ISAPNP_REGION_OK
 981		release_region(_PIDXR, 1);
 982#endif
 983		return -EBUSY;
 984	}
 985
 986	if (pnp_register_protocol(&isapnp_protocol) < 0)
 987		return -EBUSY;
 988
 989	/*
 990	 *      Print a message. The existing ISAPnP code is hanging machines
 991	 *      so let the user know where.
 992	 */
 993
 994	printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
 995	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
 996		isapnp_rdp |= 3;
 997		if (!request_region(isapnp_rdp, 1, "isapnp read")) {
 998			printk(KERN_ERR
 999			       "isapnp: Read Data Register 0x%x already used\n",
1000			       isapnp_rdp);
1001#ifdef ISAPNP_REGION_OK
1002			release_region(_PIDXR, 1);
1003#endif
1004			release_region(_PNPWRP, 1);
1005			return -EBUSY;
1006		}
1007		isapnp_set_rdp();
1008	}
1009	if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
1010		cards = isapnp_isolate();
1011		if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
1012#ifdef ISAPNP_REGION_OK
1013			release_region(_PIDXR, 1);
1014#endif
1015			release_region(_PNPWRP, 1);
1016			printk(KERN_INFO
1017			       "isapnp: No Plug & Play device found\n");
1018			return 0;
1019		}
1020		request_region(isapnp_rdp, 1, "isapnp read");
1021	}
1022	isapnp_build_device_list();
1023	cards = 0;
1024
1025	protocol_for_each_card(&isapnp_protocol, card) {
1026		cards++;
1027		if (isapnp_verbose) {
1028			dev_info(&card->dev, "card '%s'\n",
1029			       card->name[0] ? card->name : "unknown");
1030			if (isapnp_verbose < 2)
1031				continue;
1032			card_for_each_dev(card, dev) {
1033				dev_info(&card->dev, "device '%s'\n",
1034				       dev->name[0] ? dev->name : "unknown");
1035			}
1036		}
1037	}
1038	if (cards)
1039		printk(KERN_INFO
1040		       "isapnp: %i Plug & Play card%s detected total\n", cards,
1041		       str_plural(cards));
1042	else
1043		printk(KERN_INFO "isapnp: No Plug & Play card found\n");
1044
1045	isapnp_proc_init();
1046	return 0;
1047}
1048
1049device_initcall(isapnp_init);
1050
1051/* format is: noisapnp */
1052
1053static int __init isapnp_setup_disable(char *str)
1054{
1055	isapnp_disable = 1;
1056	return 1;
1057}
1058
1059__setup("noisapnp", isapnp_setup_disable);
1060
1061/* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
1062
1063static int __init isapnp_setup_isapnp(char *str)
1064{
1065	(void)((get_option(&str, &isapnp_rdp) == 2) &&
1066	       (get_option(&str, &isapnp_reset) == 2) &&
1067	       (get_option(&str, &isapnp_verbose) == 2));
1068	return 1;
1069}
1070
1071__setup("isapnp=", isapnp_setup_isapnp);
~/ Read-only file preview.