1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (c) 1995,2001 Compaq Computer Corporation
5 * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (c) 2001 IBM
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT.  See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28#ifndef _CPQPHP_H
29#define _CPQPHP_H
30
31#include "pci_hotplug.h"
32#include <asm/io.h>		/* for read? and write? functions */
33
34
35#if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE)
36	#define MY_NAME	"cpqphp.o"
37#else
38	#define MY_NAME	THIS_MODULE->name
39#endif
40
41#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
42#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
43#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
44#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
45
46
47
48struct smbios_system_slot {
49	u8 type;
50	u8 length;
51	u16 handle;
52	u8 name_string_num;
53	u8 slot_type;
54	u8 slot_width;
55	u8 slot_current_usage;
56	u8 slot_length;
57	u16 slot_number;
58	u8 properties1;
59	u8 properties2;
60} __attribute__ ((packed));
61
62/* offsets to the smbios generic type based on the above structure layout */
63enum smbios_system_slot_offsets {
64	SMBIOS_SLOT_GENERIC_TYPE =	offsetof(struct smbios_system_slot, type),
65	SMBIOS_SLOT_GENERIC_LENGTH =	offsetof(struct smbios_system_slot, length),
66	SMBIOS_SLOT_GENERIC_HANDLE =	offsetof(struct smbios_system_slot, handle),
67	SMBIOS_SLOT_NAME_STRING_NUM =	offsetof(struct smbios_system_slot, name_string_num),
68	SMBIOS_SLOT_TYPE =		offsetof(struct smbios_system_slot, slot_type),
69	SMBIOS_SLOT_WIDTH =		offsetof(struct smbios_system_slot, slot_width),
70	SMBIOS_SLOT_CURRENT_USAGE =	offsetof(struct smbios_system_slot, slot_current_usage),
71	SMBIOS_SLOT_LENGTH =		offsetof(struct smbios_system_slot, slot_length),
72	SMBIOS_SLOT_NUMBER =		offsetof(struct smbios_system_slot, slot_number),
73	SMBIOS_SLOT_PROPERTIES1 =	offsetof(struct smbios_system_slot, properties1),
74	SMBIOS_SLOT_PROPERTIES2 =	offsetof(struct smbios_system_slot, properties2),
75};
76
77struct smbios_generic {
78	u8 type;
79	u8 length;
80	u16 handle;
81} __attribute__ ((packed));
82
83/* offsets to the smbios generic type based on the above structure layout */
84enum smbios_generic_offsets {
85	SMBIOS_GENERIC_TYPE =	offsetof(struct smbios_generic, type),
86	SMBIOS_GENERIC_LENGTH =	offsetof(struct smbios_generic, length),
87	SMBIOS_GENERIC_HANDLE =	offsetof(struct smbios_generic, handle),
88};
89
90struct smbios_entry_point {
91	char anchor[4];
92	u8 ep_checksum;
93	u8 ep_length;
94	u8 major_version;
95	u8 minor_version;
96	u16 max_size_entry;
97	u8 ep_rev;
98	u8 reserved[5];
99	char int_anchor[5];
100	u8 int_checksum;
101	u16 st_length;
102	u32 st_address;
103	u16 number_of_entrys;
104	u8 bcd_rev;
105} __attribute__ ((packed));
106
107/* offsets to the smbios entry point based on the above structure layout */
108enum smbios_entry_point_offsets {
109	ANCHOR =		offsetof(struct smbios_entry_point, anchor[0]),
110	EP_CHECKSUM =		offsetof(struct smbios_entry_point, ep_checksum),
111	EP_LENGTH =		offsetof(struct smbios_entry_point, ep_length),
112	MAJOR_VERSION =		offsetof(struct smbios_entry_point, major_version),
113	MINOR_VERSION =		offsetof(struct smbios_entry_point, minor_version),
114	MAX_SIZE_ENTRY =	offsetof(struct smbios_entry_point, max_size_entry),
115	EP_REV =		offsetof(struct smbios_entry_point, ep_rev),
116	INT_ANCHOR =		offsetof(struct smbios_entry_point, int_anchor[0]),
117	INT_CHECKSUM =		offsetof(struct smbios_entry_point, int_checksum),
118	ST_LENGTH =		offsetof(struct smbios_entry_point, st_length),
119	ST_ADDRESS =		offsetof(struct smbios_entry_point, st_address),
120	NUMBER_OF_ENTRYS =	offsetof(struct smbios_entry_point, number_of_entrys),
121	BCD_REV =		offsetof(struct smbios_entry_point, bcd_rev),
122};
123
124struct ctrl_reg {			/* offset */
125	u8	slot_RST;		/* 0x00 */
126	u8	slot_enable;		/* 0x01 */
127	u16	misc;			/* 0x02 */
128	u32	led_control;		/* 0x04 */
129	u32	int_input_clear;	/* 0x08 */
130	u32	int_mask;		/* 0x0a */
131	u8	reserved0;		/* 0x10 */
132	u8	reserved1;		/* 0x11 */
133	u8	reserved2;		/* 0x12 */
134	u8	gen_output_AB;		/* 0x13 */
135	u32	non_int_input;		/* 0x14 */
136	u32	reserved3;		/* 0x18 */
137	u32	reserved4;		/* 0x1a */
138	u32	reserved5;		/* 0x20 */
139	u8	reserved6;		/* 0x24 */
140	u8	reserved7;		/* 0x25 */
141	u16	reserved8;		/* 0x26 */
142	u8	slot_mask;		/* 0x28 */
143	u8	reserved9;		/* 0x29 */
144	u8	reserved10;		/* 0x2a */
145	u8	reserved11;		/* 0x2b */
146	u8	slot_SERR;		/* 0x2c */
147	u8	slot_power;		/* 0x2d */
148} __attribute__ ((packed));
149
150/* offsets to the controller registers based on the above structure layout */
151enum ctrl_offsets {
152	SLOT_RST = 		offsetof(struct ctrl_reg, slot_RST),
153	SLOT_ENABLE =		offsetof(struct ctrl_reg, slot_enable),
154	MISC =			offsetof(struct ctrl_reg, misc),
155	LED_CONTROL =		offsetof(struct ctrl_reg, led_control),
156	INT_INPUT_CLEAR =	offsetof(struct ctrl_reg, int_input_clear),
157	INT_MASK = 		offsetof(struct ctrl_reg, int_mask),
158	CTRL_RESERVED0 = 	offsetof(struct ctrl_reg, reserved0),
159	CTRL_RESERVED1 =	offsetof(struct ctrl_reg, reserved1),
160	CTRL_RESERVED2 =	offsetof(struct ctrl_reg, reserved1),
161	GEN_OUTPUT_AB = 	offsetof(struct ctrl_reg, gen_output_AB),
162	NON_INT_INPUT = 	offsetof(struct ctrl_reg, non_int_input),
163	CTRL_RESERVED3 =	offsetof(struct ctrl_reg, reserved3),
164	CTRL_RESERVED4 =	offsetof(struct ctrl_reg, reserved4),
165	CTRL_RESERVED5 =	offsetof(struct ctrl_reg, reserved5),
166	CTRL_RESERVED6 =	offsetof(struct ctrl_reg, reserved6),
167	CTRL_RESERVED7 =	offsetof(struct ctrl_reg, reserved7),
168	CTRL_RESERVED8 =	offsetof(struct ctrl_reg, reserved8),
169	SLOT_MASK = 		offsetof(struct ctrl_reg, slot_mask),
170	CTRL_RESERVED9 = 	offsetof(struct ctrl_reg, reserved9),
171	CTRL_RESERVED10 =	offsetof(struct ctrl_reg, reserved10),
172	CTRL_RESERVED11 =	offsetof(struct ctrl_reg, reserved11),
173	SLOT_SERR =		offsetof(struct ctrl_reg, slot_SERR),
174	SLOT_POWER =		offsetof(struct ctrl_reg, slot_power),
175};
176
177struct hrt {
178	char sig0;
179	char sig1;
180	char sig2;
181	char sig3;
182	u16 unused_IRQ;
183	u16 PCIIRQ;
184	u8 number_of_entries;
185	u8 revision;
186	u16 reserved1;
187	u32 reserved2;
188} __attribute__ ((packed));
189
190/* offsets to the hotplug resource table registers based on the above structure layout */
191enum hrt_offsets {
192	SIG0 =			offsetof(struct hrt, sig0),
193	SIG1 =			offsetof(struct hrt, sig1),
194	SIG2 =			offsetof(struct hrt, sig2),
195	SIG3 =			offsetof(struct hrt, sig3),
196	UNUSED_IRQ =		offsetof(struct hrt, unused_IRQ),
197	PCIIRQ =		offsetof(struct hrt, PCIIRQ),
198	NUMBER_OF_ENTRIES =	offsetof(struct hrt, number_of_entries),
199	REVISION =		offsetof(struct hrt, revision),
200	HRT_RESERVED1 =		offsetof(struct hrt, reserved1),
201	HRT_RESERVED2 =		offsetof(struct hrt, reserved2),
202};
203
204struct slot_rt {
205	u8 dev_func;
206	u8 primary_bus;
207	u8 secondary_bus;
208	u8 max_bus;
209	u16 io_base;
210	u16 io_length;
211	u16 mem_base;
212	u16 mem_length;
213	u16 pre_mem_base;
214	u16 pre_mem_length;
215} __attribute__ ((packed));
216
217/* offsets to the hotplug slot resource table registers based on the above structure layout */
218enum slot_rt_offsets {
219	DEV_FUNC =		offsetof(struct slot_rt, dev_func),
220	PRIMARY_BUS = 		offsetof(struct slot_rt, primary_bus),
221	SECONDARY_BUS = 	offsetof(struct slot_rt, secondary_bus),
222	MAX_BUS = 		offsetof(struct slot_rt, max_bus),
223	IO_BASE = 		offsetof(struct slot_rt, io_base),
224	IO_LENGTH = 		offsetof(struct slot_rt, io_length),
225	MEM_BASE = 		offsetof(struct slot_rt, mem_base),
226	MEM_LENGTH = 		offsetof(struct slot_rt, mem_length),
227	PRE_MEM_BASE = 		offsetof(struct slot_rt, pre_mem_base),
228	PRE_MEM_LENGTH = 	offsetof(struct slot_rt, pre_mem_length),
229};
230
231struct pci_func {
232	struct pci_func *next;
233	u8 bus;
234	u8 device;
235	u8 function;
236	u8 is_a_board;
237	u16 status;
238	u8 configured;
239	u8 switch_save;
240	u8 presence_save;
241	u32 base_length[0x06];
242	u8 base_type[0x06];
243	u16 reserved2;
244	u32 config_space[0x20];
245	struct pci_resource *mem_head;
246	struct pci_resource *p_mem_head;
247	struct pci_resource *io_head;
248	struct pci_resource *bus_head;
249	struct timer_list *p_task_event;
250	struct pci_dev* pci_dev;
251};
252
253#define SLOT_MAGIC	0x67267321
254struct slot {
255	u32 magic;
256	struct slot *next;
257	u8 bus;
258	u8 device;
259	u8 number;
260	u8 is_a_board;
261	u8 configured;
262	u8 state;
263	u8 switch_save;
264	u8 presence_save;
265	u32 capabilities;
266	u16 reserved2;
267	struct timer_list task_event;
268	u8 hp_slot;
269	struct controller *ctrl;
270	void *p_sm_slot;
271	struct hotplug_slot *hotplug_slot;
272};
273
274struct pci_resource {
275	struct pci_resource * next;
276	u32 base;
277	u32 length;
278};
279
280struct event_info {
281	u32 event_type;
282	u8 hp_slot;
283};
284
285struct controller {
286	struct controller *next;
287	u32 ctrl_int_comp;
288	struct semaphore crit_sect;	/* critical section semaphore */
289	void *hpc_reg;			/* cookie for our pci controller location */
290	struct pci_resource *mem_head;
291	struct pci_resource *p_mem_head;
292	struct pci_resource *io_head;
293	struct pci_resource *bus_head;
294	struct pci_dev *pci_dev;
295	struct pci_ops *pci_ops;
296	struct proc_dir_entry* proc_entry;
297	struct proc_dir_entry* proc_entry2;
298	struct event_info event_queue[10];
299	struct slot *slot;
300	u8 next_event;
301	u8 interrupt;
302	u8 bus;
303	u8 device;
304	u8 function;
305	u8 rev;
306	u8 slot_device_offset;
307	u8 first_slot;
308	u8 add_support;
309	u8 push_flag;
310	enum pci_bus_speed speed;
311	enum pci_bus_speed speed_capability;
312	u8 push_button;			/* 0 = no pushbutton, 1 = pushbutton present */
313	u8 slot_switch_type;		/* 0 = no switch, 1 = switch present */
314	u8 defeature_PHP;		/* 0 = PHP not supported, 1 = PHP supported */
315	u8 alternate_base_address;	/* 0 = not supported, 1 = supported */
316	u8 pci_config_space;		/* Index/data access to working registers 0 = not supported, 1 = supported */
317	u8 pcix_speed_capability;	/* PCI-X */
318	u8 pcix_support;		/* PCI-X */
319	u16 vendor_id;
320	char proc_name[20];
321	char proc_name2[20];
322	struct tq_struct int_task_event;
323	wait_queue_head_t queue;	/* sleep & wake process */
324};
325
326struct irq_mapping {
327	u8 barber_pole;
328	u8 valid_INT;
329	u8 interrupt[4];
330};
331
332struct resource_lists {
333	struct pci_resource *mem_head;
334	struct pci_resource *p_mem_head;
335	struct pci_resource *io_head;
336	struct pci_resource *bus_head;
337	struct irq_mapping *irqs;
338};
339
340#define ROM_PHY_ADDR			0x0F0000
341#define ROM_PHY_LEN			0x00ffff
342
343#define PCI_HPC_ID			0xA0F7
344#define PCI_SUB_HPC_ID			0xA2F7
345#define PCI_SUB_HPC_ID2			0xA2F8
346#define PCI_SUB_HPC_ID3			0xA2F9
347#define PCI_SUB_HPC_ID_INTC		0xA2FA
348
349#define INT_BUTTON_IGNORE		0
350#define INT_PRESENCE_ON			1
351#define INT_PRESENCE_OFF		2
352#define INT_SWITCH_CLOSE		3
353#define INT_SWITCH_OPEN			4
354#define INT_POWER_FAULT			5
355#define INT_POWER_FAULT_CLEAR		6
356#define INT_BUTTON_PRESS		7
357#define INT_BUTTON_RELEASE		8
358#define INT_BUTTON_CANCEL		9
359
360#define STATIC_STATE			0
361#define BLINKINGON_STATE		1
362#define BLINKINGOFF_STATE		2
363#define POWERON_STATE			3
364#define POWEROFF_STATE			4
365
366#define PCISLOT_INTERLOCK_CLOSED	0x00000001
367#define PCISLOT_ADAPTER_PRESENT		0x00000002
368#define PCISLOT_POWERED			0x00000004
369#define PCISLOT_66_MHZ_OPERATION	0x00000008
370#define PCISLOT_64_BIT_OPERATION	0x00000010
371#define PCISLOT_REPLACE_SUPPORTED	0x00000020
372#define PCISLOT_ADD_SUPPORTED		0x00000040
373#define PCISLOT_INTERLOCK_SUPPORTED	0x00000080
374#define PCISLOT_66_MHZ_SUPPORTED	0x00000100
375#define PCISLOT_64_BIT_SUPPORTED	0x00000200
376
377
378
379#define PCI_TO_PCI_BRIDGE_CLASS		0x00060400
380
381
382#define INTERLOCK_OPEN			0x00000002
383#define ADD_NOT_SUPPORTED		0x00000003
384#define CARD_FUNCTIONING		0x00000005
385#define ADAPTER_NOT_SAME		0x00000006
386#define NO_ADAPTER_PRESENT		0x00000009
387#define NOT_ENOUGH_RESOURCES		0x0000000B
388#define DEVICE_TYPE_NOT_SUPPORTED	0x0000000C
389#define POWER_FAILURE			0x0000000E
390
391#define REMOVE_NOT_SUPPORTED		0x00000003
392
393
394/*
395 * error Messages
396 */
397#define msg_initialization_err	"Initialization failure, error=%d\n"
398#define msg_HPC_rev_error	"Unsupported revision of the PCI hot plug controller found.\n"
399#define msg_HPC_non_compaq_or_intel	"The PCI hot plug controller is not supported by this driver.\n"
400#define msg_HPC_not_supported	"this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
401#define msg_unable_to_save	"unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
402#define msg_button_on		"PCI slot #%d - powering on due to button press.\n"
403#define msg_button_off		"PCI slot #%d - powering off due to button press.\n"
404#define msg_button_cancel	"PCI slot #%d - action canceled due to button press.\n"
405#define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
406
407
408/* Proc functions for the hotplug controller info */
409#ifdef CONFIG_PROC_FS
410extern int cpqhp_proc_init_ctrl		(void);
411extern int cpqhp_proc_destroy_ctrl	(void);
412extern int cpqhp_proc_create_ctrl	(struct controller *ctrl);
413extern int cpqhp_proc_remove_ctrl	(struct controller *ctrl);
414#else
415static inline int cpqhp_proc_init_ctrl (void)
416{
417	return 0;
418}
419static inline int cpqhp_proc_destroy_ctrl (void)
420{
421	return 0;
422}
423static inline int cpqhp_proc_create_ctrl (struct controller *ctrl)
424{
425	return 0;
426}
427static inline int cpqhp_proc_remove_ctrl (struct controller *ctrl)
428{
429	return 0;
430}
431#endif
432
433
434/* controller functions */
435extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
436extern void	cpqhp_ctrl_intr			(int IRQ, struct controller *ctrl_input, struct pt_regs *regs);
437extern int	cpqhp_find_available_resources	(struct controller *ctrl, void *rom_start);
438extern int	cpqhp_event_start_thread	(void);
439extern void	cpqhp_event_stop_thread		(void);
440extern struct pci_func *cpqhp_slot_create	(unsigned char busnumber);
441extern struct pci_func *cpqhp_slot_find		(unsigned char bus, unsigned char device, unsigned char index);
442extern int	cpqhp_process_SI		(struct controller *ctrl, struct pci_func *func);
443extern int	cpqhp_process_SS		(struct controller *ctrl, struct pci_func *func);
444extern int	cpqhp_hardware_test		(struct controller *ctrl, int test_num);
445
446/* resource functions */
447extern int	cpqhp_resource_sort_and_combine	(struct pci_resource **head);
448
449/* pci functions */
450extern int	cpqhp_set_irq			(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
451extern int	cpqhp_get_bus_dev		(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
452extern int	cpqhp_save_config		(struct controller *ctrl, int busnumber, int is_hot_plug);
453extern int	cpqhp_save_base_addr_length	(struct controller *ctrl, struct pci_func * func);
454extern int	cpqhp_save_used_resources	(struct controller *ctrl, struct pci_func * func);
455extern int	cpqhp_configure_board		(struct controller *ctrl, struct pci_func * func);
456extern int	cpqhp_save_slot_config		(struct controller *ctrl, struct pci_func * new_slot);
457extern int	cpqhp_valid_replace		(struct controller *ctrl, struct pci_func * func);
458extern void	cpqhp_destroy_board_resources	(struct pci_func * func);
459extern int	cpqhp_return_board_resources	(struct pci_func * func, struct resource_lists * resources);
460extern void	cpqhp_destroy_resource_list	(struct resource_lists * resources);
461extern int	cpqhp_configure_device		(struct controller* ctrl, struct pci_func* func);
462extern int	cpqhp_unconfigure_device	(struct pci_func* func);
463
464
465/* Global variables */
466extern int cpqhp_debug;
467extern struct controller *cpqhp_ctrl_list;
468extern struct pci_func *cpqhp_slot_list[256];
469
470/* these can be gotten rid of, but for debugging they are purty */
471extern u8 cpqhp_nic_irq;
472extern u8 cpqhp_disk_irq;
473
474
475
476/* inline functions */
477
478
479/* Inline functions to check the sanity of a pointer that is passed to us */
480static inline int slot_paranoia_check (struct slot *slot, const char *function)
481{
482	if (!slot) {
483		dbg("%s - slot == NULL", function);
484		return -1;
485	}
486	if (slot->magic != SLOT_MAGIC) {
487		dbg("%s - bad magic number for slot", function);
488		return -1;
489	}
490	if (!slot->hotplug_slot) {
491		dbg("%s - slot->hotplug_slot == NULL!", function);
492		return -1;
493	}
494	return 0;
495}
496
497static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
498{
499	struct slot *slot;
500
501	if (!hotplug_slot) {
502		dbg("%s - hotplug_slot == NULL\n", function);
503		return NULL;
504	}
505
506	slot = (struct slot *)hotplug_slot->private;
507	if (slot_paranoia_check (slot, function))
508                return NULL;
509	return slot;
510}
511
512/*
513 * return_resource
514 *
515 * Puts node back in the resource list pointed to by head
516 *
517 */
518static inline void return_resource (struct pci_resource **head, struct pci_resource *node)
519{
520	if (!node || !head)
521		return;
522	node->next = *head;
523	*head = node;
524}
525
526static inline void set_SOGO (struct controller *ctrl)
527{
528	u16 misc;
529
530	misc = readw(ctrl->hpc_reg + MISC);
531	misc = (misc | 0x0001) & 0xFFFB;
532	writew(misc, ctrl->hpc_reg + MISC);
533}
534
535
536static inline void amber_LED_on (struct controller *ctrl, u8 slot)
537{
538	u32 led_control;
539
540	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
541	led_control |= (0x01010000L << slot);
542	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
543}
544
545
546static inline void amber_LED_off (struct controller *ctrl, u8 slot)
547{
548	u32 led_control;
549
550	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
551	led_control &= ~(0x01010000L << slot);
552	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
553}
554
555
556static inline int read_amber_LED (struct controller *ctrl, u8 slot)
557{
558	u32 led_control;
559
560	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
561	led_control &= (0x01010000L << slot);
562
563	return led_control ? 1 : 0;
564}
565
566
567static inline void green_LED_on (struct controller *ctrl, u8 slot)
568{
569	u32 led_control;
570
571	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
572	led_control |= 0x0101L << slot;
573	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
574}
575
576static inline void green_LED_off (struct controller *ctrl, u8 slot)
577{
578	u32 led_control;
579
580	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
581	led_control &= ~(0x0101L << slot);
582	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
583}
584
585
586static inline void green_LED_blink (struct controller *ctrl, u8 slot)
587{
588	u32 led_control;
589
590	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
591	led_control |= (0x0001L << slot);
592	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
593}
594
595
596static inline void slot_disable (struct controller *ctrl, u8 slot)
597{
598	u8 slot_enable;
599
600	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
601	slot_enable &= ~(0x01 << slot);
602	writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
603}
604
605
606static inline void slot_enable (struct controller *ctrl, u8 slot)
607{
608	u8 slot_enable;
609
610	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
611	slot_enable |= (0x01 << slot);
612	writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
613}
614
615
616static inline u8 is_slot_enabled (struct controller *ctrl, u8 slot)
617{
618	u8 slot_enable;
619
620	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
621	slot_enable &= (0x01 << slot);
622	return slot_enable ? 1 : 0;
623}
624
625
626static inline u8 read_slot_enable (struct controller *ctrl)
627{
628	return readb(ctrl->hpc_reg + SLOT_ENABLE);
629}
630
631
632static inline u8 get_controller_speed (struct controller *ctrl)
633{
634	u16 misc;
635
636	misc = readw(ctrl->hpc_reg + MISC);
637	return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
638}
639
640
641static inline void enable_slot_power (struct controller *ctrl, u8 slot)
642{
643	u8 slot_power;
644
645	slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
646	slot_power |= (0x01 << slot);
647	writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
648}
649
650static inline void disable_slot_power (struct controller *ctrl, u8 slot)
651{
652	u8 slot_power;
653
654	slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
655	slot_power &= ~(0x01 << slot);
656	writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
657}
658
659
660static inline int cpq_get_attention_status (struct controller *ctrl, struct slot *slot)
661{
662	u8 hp_slot;
663
664	if (slot == NULL)
665		return 1;
666
667	hp_slot = slot->device - ctrl->slot_device_offset;
668
669	return read_amber_LED (ctrl, hp_slot);
670}
671
672
673static inline int get_slot_enabled (struct controller *ctrl, struct slot *slot)
674{
675	u8 hp_slot;
676
677	if (slot == NULL)
678		return 1;
679
680	hp_slot = slot->device - ctrl->slot_device_offset;
681
682	return is_slot_enabled (ctrl, hp_slot);
683}
684
685
686static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *slot)
687{
688	u32 status;
689	u8 hp_slot;
690
691	if (slot == NULL)
692		return 1;
693
694	hp_slot = slot->device - ctrl->slot_device_offset;
695	dbg(__FUNCTION__": slot->device = %d, ctrl->slot_device_offset = %d \n", slot->device, ctrl->slot_device_offset);
696
697	status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
698
699	return(status == 0) ? 1 : 0;
700}
701
702
703static inline int get_presence_status (struct controller *ctrl, struct slot *slot)
704{
705	int presence_save = 0;
706	u8 hp_slot;
707	u32 tempdword;
708
709	if (slot == NULL)
710		return 0;
711
712	hp_slot = slot->device - ctrl->slot_device_offset;
713
714	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
715	presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
716
717	return presence_save;
718}
719
720#define SLOT_NAME_SIZE 10
721
722static inline void make_slot_name (char *buffer, int buffer_size, struct slot *slot)
723{
724	snprintf (buffer, buffer_size, "%d", slot->number);
725}
726
727
728static inline int wait_for_ctrl_irq (struct controller *ctrl)
729{
730        DECLARE_WAITQUEUE(wait, current);
731	int retval = 0;
732
733	dbg(__FUNCTION__" - start\n");
734	add_wait_queue(&ctrl->queue, &wait);
735	set_current_state(TASK_INTERRUPTIBLE);
736	/* Sleep for up to 1 second to wait for the LED to change. */
737	schedule_timeout(1*HZ);
738	set_current_state(TASK_RUNNING);
739	remove_wait_queue(&ctrl->queue, &wait);
740	if (signal_pending(current))
741		retval =  -EINTR;
742
743	dbg(__FUNCTION__" - end\n");
744	return retval;
745}
746
747#endif
748
749