Linux Audio

Check our new training course

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