1/*
2 * compat.c - A series of functions to make it easier to convert drivers that use
3 *            the old isapnp APIs. If possible use the new APIs instead.
4 *
5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
6 *
7 */
8
9/* TODO: see if more isapnp functions are needed here */
10
11#include <linux/module.h>
12#include <linux/isapnp.h>
13#include <linux/string.h>
14
15static void pnp_convert_id(char *buf, unsigned short vendor, unsigned short device)
16{
17	sprintf(buf, "%c%c%c%x%x%x%x",
18			'A' + ((vendor >> 2) & 0x3f) - 1,
19			'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
20			'A' + ((vendor >> 8) & 0x1f) - 1,
21			(device >> 4) & 0x0f,
22			device & 0x0f,
23			(device >> 12) & 0x0f,
24			(device >> 8) & 0x0f);
25}
26
27struct pnp_card *pnp_find_card(unsigned short vendor,
28			       unsigned short device,
29			       struct pnp_card *from)
30{
31	char id[8];
32	char any[8];
33	struct list_head *list;
34	pnp_convert_id(id, vendor, device);
35	pnp_convert_id(any, ISAPNP_ANY_ID, ISAPNP_ANY_ID);
36
37	list = from ? from->global_list.next : pnp_cards.next;
38
39	while (list != &pnp_cards) {
40		struct pnp_card *card = global_to_pnp_card(list);
41		if (compare_pnp_id(card->id,id) || (memcmp(id,any,7)==0))
42			return card;
43		list = list->next;
44	}
45	return NULL;
46}
47
48struct pnp_dev *pnp_find_dev(struct pnp_card *card,
49			     unsigned short vendor,
50			     unsigned short function,
51			     struct pnp_dev *from)
52{
53	char id[8];
54	char any[8];
55	pnp_convert_id(id, vendor, function);
56	pnp_convert_id(any, ISAPNP_ANY_ID, ISAPNP_ANY_ID);
57	if (card == NULL) {	/* look for a logical device from all cards */
58		struct list_head *list;
59
60		list = pnp_global.next;
61		if (from)
62			list = from->global_list.next;
63
64		while (list != &pnp_global) {
65			struct pnp_dev *dev = global_to_pnp_dev(list);
66			if (compare_pnp_id(dev->id,id) || (memcmp(id,any,7)==0))
67				return dev;
68			list = list->next;
69		}
70	} else {
71		struct list_head *list;
72
73		list = card->devices.next;
74		if (from) {
75			list = from->card_list.next;
76			if (from->card != card)	/* something is wrong */
77				return NULL;
78		}
79		while (list != &card->devices) {
80			struct pnp_dev *dev = card_to_pnp_dev(list);
81			if (compare_pnp_id(dev->id,id))
82				return dev;
83			list = list->next;
84		}
85	}
86	return NULL;
87}
88
89EXPORT_SYMBOL(pnp_find_card);
90EXPORT_SYMBOL(pnp_find_dev);
91