1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001-2003 IBM Corp.
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT.  See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/pci.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/wait.h>
37#include "../pci.h"
38#include "../../../arch/i386/pci/pci.h"	/* for struct irq_routing_table */
39#include "ibmphp.h"
40
41#define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
42#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
43#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
44#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
45#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
46
47#define DRIVER_VERSION	"0.6"
48#define DRIVER_DESC	"IBM Hot Plug PCI Controller Driver"
49
50int ibmphp_debug;
51
52static int debug;
53module_param(debug, bool, S_IRUGO | S_IWUSR);
54MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
55MODULE_LICENSE ("GPL");
56MODULE_DESCRIPTION (DRIVER_DESC);
57
58struct pci_bus *ibmphp_pci_bus;
59static int max_slots;
60
61static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS
62			 * tables don't provide default info for empty slots */
63
64static int init_flag;
65
66/*
67static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
68
69static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
70{
71	return get_max_adapter_speed_1 (hs, value, 1);
72}
73*/
74static inline int get_cur_bus_info(struct slot **sl)
75{
76	int rc = 1;
77	struct slot * slot_cur = *sl;
78
79	debug("options = %x\n", slot_cur->ctrl->options);
80	debug("revision = %x\n", slot_cur->ctrl->revision);
81
82	if (READ_BUS_STATUS(slot_cur->ctrl))
83		rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
84
85	if (rc)
86		return rc;
87
88	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
89	if (READ_BUS_MODE(slot_cur->ctrl))
90		slot_cur->bus_on->current_bus_mode =
91				CURRENT_BUS_MODE(slot_cur->busstatus);
92	else
93		slot_cur->bus_on->current_bus_mode = 0xFF;
94
95	debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
96			slot_cur->busstatus,
97			slot_cur->bus_on->current_speed,
98			slot_cur->bus_on->current_bus_mode);
99
100	*sl = slot_cur;
101	return 0;
102}
103
104static inline int slot_update(struct slot **sl)
105{
106	int rc;
107 	rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
108	if (rc)
109		return rc;
110	if (!init_flag)
111		rc = get_cur_bus_info(sl);
112	return rc;
113}
114
115static int __init get_max_slots (void)
116{
117	struct slot * slot_cur;
118	struct list_head * tmp;
119	u8 slot_count = 0;
120
121	list_for_each(tmp, &ibmphp_slot_head) {
122		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
123		/* sometimes the hot-pluggable slots start with 4 (not always from 1) */
124		slot_count = max(slot_count, slot_cur->number);
125	}
126	return slot_count;
127}
128
129/* This routine will put the correct slot->device information per slot.  It's
130 * called from initialization of the slot structures. It will also assign
131 * interrupt numbers per each slot.
132 * Parameters: struct slot
133 * Returns 0 or errors
134 */
135int ibmphp_init_devno(struct slot **cur_slot)
136{
137	struct irq_routing_table *rtable;
138	int len;
139	int loop;
140	int i;
141
142	rtable = pcibios_get_irq_routing_table();
143	if (!rtable) {
144		err("no BIOS routing table...\n");
145		return -ENOMEM;
146	}
147
148	len = (rtable->size - sizeof(struct irq_routing_table)) /
149			sizeof(struct irq_info);
150
151	if (!len)
152		return -1;
153	for (loop = 0; loop < len; loop++) {
154		if ((*cur_slot)->number == rtable->slots[loop].slot) {
155		if ((*cur_slot)->bus == rtable->slots[loop].bus) {
156			(*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
157			for (i = 0; i < 4; i++)
158				(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
159						(int) (*cur_slot)->device, i);
160
161				debug("(*cur_slot)->irq[0] = %x\n",
162						(*cur_slot)->irq[0]);
163				debug("(*cur_slot)->irq[1] = %x\n",
164						(*cur_slot)->irq[1]);
165				debug("(*cur_slot)->irq[2] = %x\n",
166						(*cur_slot)->irq[2]);
167				debug("(*cur_slot)->irq[3] = %x\n",
168						(*cur_slot)->irq[3]);
169
170				debug("rtable->exlusive_irqs = %x\n",
171					rtable->exclusive_irqs);
172				debug("rtable->slots[loop].irq[0].bitmap = %x\n",
173					rtable->slots[loop].irq[0].bitmap);
174				debug("rtable->slots[loop].irq[1].bitmap = %x\n",
175					rtable->slots[loop].irq[1].bitmap);
176				debug("rtable->slots[loop].irq[2].bitmap = %x\n",
177					rtable->slots[loop].irq[2].bitmap);
178				debug("rtable->slots[loop].irq[3].bitmap = %x\n",
179					rtable->slots[loop].irq[3].bitmap);
180
181				debug("rtable->slots[loop].irq[0].link = %x\n",
182					rtable->slots[loop].irq[0].link);
183				debug("rtable->slots[loop].irq[1].link = %x\n",
184					rtable->slots[loop].irq[1].link);
185				debug("rtable->slots[loop].irq[2].link = %x\n",
186					rtable->slots[loop].irq[2].link);
187				debug("rtable->slots[loop].irq[3].link = %x\n",
188					rtable->slots[loop].irq[3].link);
189				debug("end of init_devno\n");
190				return 0;
191			}
192		}
193	}
194
195	return -1;
196}
197
198static inline int power_on(struct slot *slot_cur)
199{
200	u8 cmd = HPC_SLOT_ON;
201	int retval;
202
203	retval = ibmphp_hpc_writeslot(slot_cur, cmd);
204	if (retval) {
205		err("power on failed\n");
206		return retval;
207	}
208	if (CTLR_RESULT(slot_cur->ctrl->status)) {
209		err("command not completed successfully in power_on\n");
210		return -EIO;
211	}
212	msleep(3000);	/* For ServeRAID cards, and some 66 PCI */
213	return 0;
214}
215
216static inline int power_off(struct slot *slot_cur)
217{
218	u8 cmd = HPC_SLOT_OFF;
219	int retval;
220
221	retval = ibmphp_hpc_writeslot(slot_cur, cmd);
222	if (retval) {
223		err("power off failed\n");
224		return retval;
225	}
226	if (CTLR_RESULT(slot_cur->ctrl->status)) {
227		err("command not completed successfully in power_off\n");
228		retval = -EIO;
229	}
230	return retval;
231}
232
233static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
234{
235	int rc = 0;
236	struct slot *pslot;
237	u8 cmd = 0x00;     /* avoid compiler warning */
238
239	debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
240			(ulong) hotplug_slot, value);
241	ibmphp_lock_operations();
242
243
244	if (hotplug_slot) {
245		switch (value) {
246		case HPC_SLOT_ATTN_OFF:
247			cmd = HPC_SLOT_ATTNOFF;
248			break;
249		case HPC_SLOT_ATTN_ON:
250			cmd = HPC_SLOT_ATTNON;
251			break;
252		case HPC_SLOT_ATTN_BLINK:
253			cmd = HPC_SLOT_BLINKLED;
254			break;
255		default:
256			rc = -ENODEV;
257			err("set_attention_status - Error : invalid input [%x]\n",
258					value);
259			break;
260		}
261		if (rc == 0) {
262			pslot = hotplug_slot->private;
263			if (pslot)
264				rc = ibmphp_hpc_writeslot(pslot, cmd);
265			else
266				rc = -ENODEV;
267		}
268	} else
269		rc = -ENODEV;
270
271	ibmphp_unlock_operations();
272
273	debug("set_attention_status - Exit rc[%d]\n", rc);
274	return rc;
275}
276
277static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
278{
279	int rc = -ENODEV;
280	struct slot *pslot;
281	struct slot myslot;
282
283	debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
284					(ulong) hotplug_slot, (ulong) value);
285
286	ibmphp_lock_operations();
287	if (hotplug_slot) {
288		pslot = hotplug_slot->private;
289		if (pslot) {
290			memcpy(&myslot, pslot, sizeof(struct slot));
291			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
292						&(myslot.status));
293			if (!rc)
294				rc = ibmphp_hpc_readslot(pslot,
295						READ_EXTSLOTSTATUS,
296						&(myslot.ext_status));
297			if (!rc)
298				*value = SLOT_ATTN(myslot.status,
299						myslot.ext_status);
300		}
301	}
302
303	ibmphp_unlock_operations();
304	debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
305	return rc;
306}
307
308static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
309{
310	int rc = -ENODEV;
311	struct slot *pslot;
312	struct slot myslot;
313
314	debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
315					(ulong) hotplug_slot, (ulong) value);
316	ibmphp_lock_operations();
317	if (hotplug_slot) {
318		pslot = hotplug_slot->private;
319		if (pslot) {
320			memcpy(&myslot, pslot, sizeof(struct slot));
321			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
322						&(myslot.status));
323			if (!rc)
324				*value = SLOT_LATCH(myslot.status);
325		}
326	}
327
328	ibmphp_unlock_operations();
329	debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
330			rc, rc, *value);
331	return rc;
332}
333
334
335static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
336{
337	int rc = -ENODEV;
338	struct slot *pslot;
339	struct slot myslot;
340
341	debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
342					(ulong) hotplug_slot, (ulong) value);
343	ibmphp_lock_operations();
344	if (hotplug_slot) {
345		pslot = hotplug_slot->private;
346		if (pslot) {
347			memcpy(&myslot, pslot, sizeof(struct slot));
348			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
349						&(myslot.status));
350			if (!rc)
351				*value = SLOT_PWRGD(myslot.status);
352		}
353	}
354
355	ibmphp_unlock_operations();
356	debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
357			rc, rc, *value);
358	return rc;
359}
360
361static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
362{
363	int rc = -ENODEV;
364	struct slot *pslot;
365	u8 present;
366	struct slot myslot;
367
368	debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
369					(ulong) hotplug_slot, (ulong) value);
370	ibmphp_lock_operations();
371	if (hotplug_slot) {
372		pslot = hotplug_slot->private;
373		if (pslot) {
374			memcpy(&myslot, pslot, sizeof(struct slot));
375			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
376						&(myslot.status));
377			if (!rc) {
378				present = SLOT_PRESENT(myslot.status);
379				if (present == HPC_SLOT_EMPTY)
380					*value = 0;
381				else
382					*value = 1;
383			}
384		}
385	}
386
387	ibmphp_unlock_operations();
388	debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
389	return rc;
390}
391
392static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
393{
394	int rc = -ENODEV;
395	struct slot *pslot;
396	u8 mode = 0;
397
398	debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
399		hotplug_slot, value);
400
401	ibmphp_lock_operations();
402
403	if (hotplug_slot) {
404		pslot = hotplug_slot->private;
405		if (pslot) {
406			rc = 0;
407			mode = pslot->supported_bus_mode;
408			*value = pslot->supported_speed;
409			switch (*value) {
410			case BUS_SPEED_33:
411				break;
412			case BUS_SPEED_66:
413				if (mode == BUS_MODE_PCIX)
414					*value += 0x01;
415				break;
416			case BUS_SPEED_100:
417			case BUS_SPEED_133:
418				*value = pslot->supported_speed + 0x01;
419				break;
420			default:
421				/* Note (will need to change): there would be soon 256, 512 also */
422				rc = -ENODEV;
423			}
424		}
425	}
426
427	ibmphp_unlock_operations();
428	debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
429	return rc;
430}
431
432static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
433{
434	int rc = -ENODEV;
435	struct slot *pslot;
436	u8 mode = 0;
437
438	debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
439		hotplug_slot, value);
440
441	ibmphp_lock_operations();
442
443	if (hotplug_slot) {
444		pslot = hotplug_slot->private;
445		if (pslot) {
446			rc = get_cur_bus_info(&pslot);
447			if (!rc) {
448				mode = pslot->bus_on->current_bus_mode;
449				*value = pslot->bus_on->current_speed;
450				switch (*value) {
451				case BUS_SPEED_33:
452					break;
453				case BUS_SPEED_66:
454					if (mode == BUS_MODE_PCIX)
455						*value += 0x01;
456					else if (mode == BUS_MODE_PCI)
457						;
458					else
459						*value = PCI_SPEED_UNKNOWN;
460					break;
461				case BUS_SPEED_100:
462				case BUS_SPEED_133:
463					*value += 0x01;
464					break;
465				default:
466					/* Note of change: there would also be 256, 512 soon */
467					rc = -ENODEV;
468				}
469			}
470		}
471	}
472
473	ibmphp_unlock_operations();
474	debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
475	return rc;
476}
477
478/*
479static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
480{
481	int rc = -ENODEV;
482	struct slot *pslot;
483	struct slot myslot;
484
485	debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
486						(ulong)hotplug_slot, (ulong) value);
487
488	if (flag)
489		ibmphp_lock_operations();
490
491	if (hotplug_slot && value) {
492		pslot = hotplug_slot->private;
493		if (pslot) {
494			memcpy(&myslot, pslot, sizeof(struct slot));
495			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
496						&(myslot.status));
497
498			if (!(SLOT_LATCH (myslot.status)) &&
499					(SLOT_PRESENT (myslot.status))) {
500				rc = ibmphp_hpc_readslot(pslot,
501						READ_EXTSLOTSTATUS,
502						&(myslot.ext_status));
503				if (!rc)
504					*value = SLOT_SPEED(myslot.ext_status);
505			} else
506				*value = MAX_ADAPTER_NONE;
507                }
508	}
509
510	if (flag)
511		ibmphp_unlock_operations();
512
513	debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
514	return rc;
515}
516
517static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
518{
519	int rc = -ENODEV;
520	struct slot *pslot = NULL;
521
522	debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
523
524	ibmphp_lock_operations();
525
526	if (hotplug_slot) {
527		pslot = hotplug_slot->private;
528		if (pslot) {
529			rc = 0;
530			snprintf(value, 100, "Bus %x", pslot->bus);
531		}
532	} else
533		rc = -ENODEV;
534
535	ibmphp_unlock_operations();
536	debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
537	return rc;
538}
539*/
540
541/****************************************************************************
542 * This routine will initialize the ops data structure used in the validate
543 * function. It will also power off empty slots that are powered on since BIOS
544 * leaves those on, albeit disconnected
545 ****************************************************************************/
546static int __init init_ops(void)
547{
548	struct slot *slot_cur;
549	struct list_head *tmp;
550	int retval;
551	int rc;
552
553	list_for_each(tmp, &ibmphp_slot_head) {
554		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
555
556		if (!slot_cur)
557			return -ENODEV;
558
559		debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
560							slot_cur->number);
561		if (slot_cur->ctrl->revision == 0xFF)
562			if (get_ctrl_revision(slot_cur,
563						&slot_cur->ctrl->revision))
564				return -1;
565
566		if (slot_cur->bus_on->current_speed == 0xFF)
567			if (get_cur_bus_info(&slot_cur))
568				return -1;
569
570		if (slot_cur->ctrl->options == 0xFF)
571			if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
572				return -1;
573
574		retval = slot_update(&slot_cur);
575		if (retval)
576			return retval;
577
578		debug("status = %x\n", slot_cur->status);
579		debug("ext_status = %x\n", slot_cur->ext_status);
580		debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
581		debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
582		debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
583
584		if ((SLOT_PWRGD(slot_cur->status)) &&
585		    !(SLOT_PRESENT(slot_cur->status)) &&
586		    !(SLOT_LATCH(slot_cur->status))) {
587			debug("BEFORE POWER OFF COMMAND\n");
588				rc = power_off(slot_cur);
589				if (rc)
590					return rc;
591
592	/*		retval = slot_update(&slot_cur);
593	 *		if (retval)
594	 *			return retval;
595	 *		ibmphp_update_slot_info(slot_cur);
596	 */
597		}
598	}
599	init_flag = 0;
600	return 0;
601}
602
603/* This operation will check whether the slot is within the bounds and
604 * the operation is valid to perform on that slot
605 * Parameters: slot, operation
606 * Returns: 0 or error codes
607 */
608static int validate(struct slot *slot_cur, int opn)
609{
610	int number;
611	int retval;
612
613	if (!slot_cur)
614		return -ENODEV;
615	number = slot_cur->number;
616	if ((number > max_slots) || (number < 0))
617		return -EBADSLT;
618	debug("slot_number in validate is %d\n", slot_cur->number);
619
620	retval = slot_update(&slot_cur);
621	if (retval)
622		return retval;
623
624	switch (opn) {
625		case ENABLE:
626			if (!(SLOT_PWRGD(slot_cur->status)) &&
627			     (SLOT_PRESENT(slot_cur->status)) &&
628			     !(SLOT_LATCH(slot_cur->status)))
629				return 0;
630			break;
631		case DISABLE:
632			if ((SLOT_PWRGD(slot_cur->status)) &&
633			    (SLOT_PRESENT(slot_cur->status)) &&
634			    !(SLOT_LATCH(slot_cur->status)))
635				return 0;
636			break;
637		default:
638			break;
639	}
640	err("validate failed....\n");
641	return -EINVAL;
642}
643
644/****************************************************************************
645 * This routine is for updating the data structures in the hotplug core
646 * Parameters: struct slot
647 * Returns: 0 or error
648 ****************************************************************************/
649int ibmphp_update_slot_info(struct slot *slot_cur)
650{
651	struct hotplug_slot_info *info;
652	int rc;
653	u8 bus_speed;
654	u8 mode;
655
656	info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
657	if (!info) {
658		err("out of system memory\n");
659		return -ENOMEM;
660	}
661
662	info->power_status = SLOT_PWRGD(slot_cur->status);
663	info->attention_status = SLOT_ATTN(slot_cur->status,
664						slot_cur->ext_status);
665	info->latch_status = SLOT_LATCH(slot_cur->status);
666        if (!SLOT_PRESENT(slot_cur->status)) {
667                info->adapter_status = 0;
668/*		info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
669	} else {
670                info->adapter_status = 1;
671/*		get_max_adapter_speed_1(slot_cur->hotplug_slot,
672					&info->max_adapter_speed_status, 0); */
673	}
674
675	bus_speed = slot_cur->bus_on->current_speed;
676	mode = slot_cur->bus_on->current_bus_mode;
677
678	switch (bus_speed) {
679		case BUS_SPEED_33:
680			break;
681		case BUS_SPEED_66:
682			if (mode == BUS_MODE_PCIX)
683				bus_speed += 0x01;
684			else if (mode == BUS_MODE_PCI)
685				;
686			else
687				bus_speed = PCI_SPEED_UNKNOWN;
688			break;
689		case BUS_SPEED_100:
690		case BUS_SPEED_133:
691			bus_speed += 0x01;
692			break;
693		default:
694			bus_speed = PCI_SPEED_UNKNOWN;
695	}
696
697	info->cur_bus_speed = bus_speed;
698	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
699	// To do: bus_names
700
701	rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
702	kfree(info);
703	return rc;
704}
705
706
707/******************************************************************************
708 * This function will return the pci_func, given bus and devfunc, or NULL.  It
709 * is called from visit routines
710 ******************************************************************************/
711
712static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
713{
714	struct pci_func *func_cur;
715	struct slot *slot_cur;
716	struct list_head * tmp;
717	list_for_each(tmp, &ibmphp_slot_head) {
718		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
719		if (slot_cur->func) {
720			func_cur = slot_cur->func;
721			while (func_cur) {
722				if ((func_cur->busno == busno) &&
723						(func_cur->device == device) &&
724						(func_cur->function == function))
725					return func_cur;
726				func_cur = func_cur->next;
727			}
728		}
729	}
730	return NULL;
731}
732
733/*************************************************************
734 * This routine frees up memory used by struct slot, including
735 * the pointers to pci_func, bus, hotplug_slot, controller,
736 * and deregistering from the hotplug core
737 *************************************************************/
738static void free_slots(void)
739{
740	struct slot *slot_cur;
741	struct list_head * tmp;
742	struct list_head * next;
743
744	debug("%s -- enter\n", __FUNCTION__);
745
746	list_for_each_safe(tmp, next, &ibmphp_slot_head) {
747		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
748		pci_hp_deregister(slot_cur->hotplug_slot);
749	}
750	debug("%s -- exit\n", __FUNCTION__);
751}
752
753static void ibm_unconfigure_device(struct pci_func *func)
754{
755	struct pci_dev *temp;
756	u8 j;
757
758	debug("inside %s\n", __FUNCTION__);
759	debug("func->device = %x, func->function = %x\n",
760					func->device, func->function);
761	debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
762
763	for (j = 0; j < 0x08; j++) {
764		temp = pci_find_slot(func->busno, (func->device << 3) | j);
765		if (temp)
766			pci_remove_bus_device(temp);
767	}
768}
769
770/*
771 * The following function is to fix kernel bug regarding
772 * getting bus entries, here we manually add those primary
773 * bus entries to kernel bus structure whenever apply
774 */
775static u8 bus_structure_fixup(u8 busno)
776{
777	struct pci_bus *bus;
778	struct pci_dev *dev;
779	u16 l;
780
781	if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
782		return 1;
783
784	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
785	if (!bus) {
786		err("%s - out of memory\n", __FUNCTION__);
787		return 1;
788	}
789	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
790	if (!dev) {
791		kfree(bus);
792		err("%s - out of memory\n", __FUNCTION__);
793		return 1;
794	}
795
796	bus->number = busno;
797	bus->ops = ibmphp_pci_bus->ops;
798	dev->bus = bus;
799	for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
800		if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
801					(l != 0x0000) && (l != 0xffff)) {
802			debug("%s - Inside bus_struture_fixup()\n",
803							__FUNCTION__);
804			pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
805			break;
806		}
807	}
808
809	kfree(dev);
810	kfree(bus);
811
812	return 0;
813}
814
815static int ibm_configure_device(struct pci_func *func)
816{
817	unsigned char bus;
818	struct pci_bus *child;
819	int num;
820	int flag = 0;	/* this is to make sure we don't double scan the bus,
821					for bridged devices primarily */
822
823	if (!(bus_structure_fixup(func->busno)))
824		flag = 1;
825	if (func->dev == NULL)
826		func->dev = pci_find_slot(func->busno,
827				PCI_DEVFN(func->device, func->function));
828
829	if (func->dev == NULL) {
830		struct pci_bus *bus = pci_find_bus(0, func->busno);
831		if (!bus)
832			return 0;
833
834		num = pci_scan_slot(bus,
835				PCI_DEVFN(func->device, func->function));
836		if (num)
837			pci_bus_add_devices(bus);
838
839		func->dev = pci_find_slot(func->busno,
840				PCI_DEVFN(func->device, func->function));
841		if (func->dev == NULL) {
842			err("ERROR... : pci_dev still NULL\n");
843			return 0;
844		}
845	}
846	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
847		pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
848		child = pci_add_new_bus(func->dev->bus, func->dev, bus);
849		pci_do_scan_bus(child);
850	}
851
852	return 0;
853}
854
855/*******************************************************
856 * Returns whether the bus is empty or not
857 *******************************************************/
858static int is_bus_empty(struct slot * slot_cur)
859{
860	int rc;
861	struct slot * tmp_slot;
862	u8 i = slot_cur->bus_on->slot_min;
863
864	while (i <= slot_cur->bus_on->slot_max) {
865		if (i == slot_cur->number) {
866			i++;
867			continue;
868		}
869		tmp_slot = ibmphp_get_slot_from_physical_num(i);
870		if (!tmp_slot)
871			return 0;
872		rc = slot_update(&tmp_slot);
873		if (rc)
874			return 0;
875		if (SLOT_PRESENT(tmp_slot->status) &&
876					SLOT_PWRGD(tmp_slot->status))
877			return 0;
878		i++;
879	}
880	return 1;
881}
882
883/***********************************************************
884 * If the HPC permits and the bus currently empty, tries to set the
885 * bus speed and mode at the maximum card and bus capability
886 * Parameters: slot
887 * Returns: bus is set (0) or error code
888 ***********************************************************/
889static int set_bus(struct slot * slot_cur)
890{
891	int rc;
892	u8 speed;
893	u8 cmd = 0x0;
894	int retval;
895	static struct pci_device_id ciobx[] = {
896		{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
897	        { },
898	};
899
900	debug("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
901	if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
902		rc = slot_update(&slot_cur);
903		if (rc)
904			return rc;
905		speed = SLOT_SPEED(slot_cur->ext_status);
906		debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
907		switch (speed) {
908		case HPC_SLOT_SPEED_33:
909			cmd = HPC_BUS_33CONVMODE;
910			break;
911		case HPC_SLOT_SPEED_66:
912			if (SLOT_PCIX(slot_cur->ext_status)) {
913				if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
914						(slot_cur->supported_bus_mode == BUS_MODE_PCIX))
915					cmd = HPC_BUS_66PCIXMODE;
916				else if (!SLOT_BUS_MODE(slot_cur->ext_status))
917					/* if max slot/bus capability is 66 pci
918					and there's no bus mode mismatch, then
919					the adapter supports 66 pci */
920					cmd = HPC_BUS_66CONVMODE;
921				else
922					cmd = HPC_BUS_33CONVMODE;
923			} else {
924				if (slot_cur->supported_speed >= BUS_SPEED_66)
925					cmd = HPC_BUS_66CONVMODE;
926				else
927					cmd = HPC_BUS_33CONVMODE;
928			}
929			break;
930		case HPC_SLOT_SPEED_133:
931			switch (slot_cur->supported_speed) {
932			case BUS_SPEED_33:
933				cmd = HPC_BUS_33CONVMODE;
934				break;
935			case BUS_SPEED_66:
936				if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
937					cmd = HPC_BUS_66PCIXMODE;
938				else
939					cmd = HPC_BUS_66CONVMODE;
940				break;
941			case BUS_SPEED_100:
942				cmd = HPC_BUS_100PCIXMODE;
943				break;
944			case BUS_SPEED_133:
945				/* This is to take care of the bug in CIOBX chip */
946				if (pci_dev_present(ciobx))
947					ibmphp_hpc_writeslot(slot_cur,
948							HPC_BUS_100PCIXMODE);
949				cmd = HPC_BUS_133PCIXMODE;
950				break;
951			default:
952				err("Wrong bus speed\n");
953				return -ENODEV;
954			}
955			break;
956		default:
957			err("wrong slot speed\n");
958			return -ENODEV;
959		}
960		debug("setting bus speed for slot %d, cmd %x\n",
961						slot_cur->number, cmd);
962		retval = ibmphp_hpc_writeslot(slot_cur, cmd);
963		if (retval) {
964			err("setting bus speed failed\n");
965			return retval;
966		}
967		if (CTLR_RESULT(slot_cur->ctrl->status)) {
968			err("command not completed successfully in set_bus\n");
969			return -EIO;
970		}
971	}
972	/* This is for x440, once Brandon fixes the firmware,
973	will not need this delay */
974	msleep(1000);
975	debug("%s -Exit\n", __FUNCTION__);
976	return 0;
977}
978
979/* This routine checks the bus limitations that the slot is on from the BIOS.
980 * This is used in deciding whether or not to power up the slot.
981 * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
982 * same bus)
983 * Parameters: slot
984 * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
985 */
986static int check_limitations(struct slot *slot_cur)
987{
988	u8 i;
989	struct slot * tmp_slot;
990	u8 count = 0;
991	u8 limitation = 0;
992
993	for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
994		tmp_slot = ibmphp_get_slot_from_physical_num(i);
995		if (!tmp_slot)
996			return -ENODEV;
997		if ((SLOT_PWRGD(tmp_slot->status)) &&
998					!(SLOT_CONNECT(tmp_slot->status)))
999			count++;
1000	}
1001	get_cur_bus_info(&slot_cur);
1002	switch (slot_cur->bus_on->current_speed) {
1003	case BUS_SPEED_33:
1004		limitation = slot_cur->bus_on->slots_at_33_conv;
1005		break;
1006	case BUS_SPEED_66:
1007		if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1008			limitation = slot_cur->bus_on->slots_at_66_pcix;
1009		else
1010			limitation = slot_cur->bus_on->slots_at_66_conv;
1011		break;
1012	case BUS_SPEED_100:
1013		limitation = slot_cur->bus_on->slots_at_100_pcix;
1014		break;
1015	case BUS_SPEED_133:
1016		limitation = slot_cur->bus_on->slots_at_133_pcix;
1017		break;
1018	}
1019
1020	if ((count + 1) > limitation)
1021		return -EINVAL;
1022	return 0;
1023}
1024
1025static inline void print_card_capability(struct slot *slot_cur)
1026{
1027	info("capability of the card is ");
1028	if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
1029		info("   133 MHz PCI-X\n");
1030	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1031		info("    66 MHz PCI-X\n");
1032	else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1033		info("    66 MHz PCI\n");
1034	else
1035		info("    33 MHz PCI\n");
1036
1037}
1038
1039/* This routine will power on the slot, configure the device(s) and find the
1040 * drivers for them.
1041 * Parameters: hotplug_slot
1042 * Returns: 0 or failure codes
1043 */
1044static int enable_slot(struct hotplug_slot *hs)
1045{
1046	int rc, i, rcpr;
1047	struct slot *slot_cur;
1048	u8 function;
1049	struct pci_func *tmp_func;
1050
1051	ibmphp_lock_operations();
1052
1053	debug("ENABLING SLOT........\n");
1054	slot_cur = hs->private;
1055
1056	if ((rc = validate(slot_cur, ENABLE))) {
1057		err("validate function failed\n");
1058		goto error_nopower;
1059	}
1060
1061	attn_LED_blink(slot_cur);
1062
1063	rc = set_bus(slot_cur);
1064	if (rc) {
1065		err("was not able to set the bus\n");
1066		goto error_nopower;
1067	}
1068
1069	/*-----------------debugging------------------------------*/
1070	get_cur_bus_info(&slot_cur);
1071	debug("the current bus speed right after set_bus = %x\n",
1072					slot_cur->bus_on->current_speed);
1073	/*----------------------------------------------------------*/
1074
1075	rc = check_limitations(slot_cur);
1076	if (rc) {
1077		err("Adding this card exceeds the limitations of this bus.\n");
1078		err("(i.e., >1 133MHz cards running on same bus, or "
1079		     ">2 66 PCI cards running on same bus.\n");
1080		err("Try hot-adding into another bus\n");
1081		rc = -EINVAL;
1082		goto error_nopower;
1083	}
1084
1085	rc = power_on(slot_cur);
1086
1087	if (rc) {
1088		err("something wrong when powering up... please see below for details\n");
1089		/* need to turn off before on, otherwise, blinking overwrites */
1090		attn_off(slot_cur);
1091		attn_on(slot_cur);
1092		if (slot_update(&slot_cur)) {
1093			attn_off(slot_cur);
1094			attn_on(slot_cur);
1095			rc = -ENODEV;
1096			goto exit;
1097		}
1098		/* Check to see the error of why it failed */
1099		if ((SLOT_POWER(slot_cur->status)) &&
1100					!(SLOT_PWRGD(slot_cur->status)))
1101			err("power fault occurred trying to power up\n");
1102		else if (SLOT_BUS_SPEED(slot_cur->status)) {
1103			err("bus speed mismatch occurred.  please check "
1104				"current bus speed and card capability\n");
1105			print_card_capability(slot_cur);
1106		} else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1107			err("bus mode mismatch occurred.  please check "
1108				"current bus mode and card capability\n");
1109			print_card_capability(slot_cur);
1110		}
1111		ibmphp_update_slot_info(slot_cur);
1112		goto exit;
1113	}
1114	debug("after power_on\n");
1115	/*-----------------------debugging---------------------------*/
1116	get_cur_bus_info(&slot_cur);
1117	debug("the current bus speed right after power_on = %x\n",
1118					slot_cur->bus_on->current_speed);
1119	/*----------------------------------------------------------*/
1120
1121	rc = slot_update(&slot_cur);
1122	if (rc)
1123		goto error_power;
1124
1125	rc = -EINVAL;
1126	if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1127		err("power fault occurred trying to power up...\n");
1128		goto error_power;
1129	}
1130	if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1131		err("bus speed mismatch occurred.  please check current bus "
1132					"speed and card capability\n");
1133		print_card_capability(slot_cur);
1134		goto error_power;
1135	}
1136	/* Don't think this case will happen after above checks...
1137	 * but just in case, for paranoia sake */
1138	if (!(SLOT_POWER(slot_cur->status))) {
1139		err("power on failed...\n");
1140		goto error_power;
1141	}
1142
1143	slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1144	if (!slot_cur->func) {
1145		/* We cannot do update_slot_info here, since no memory for
1146		 * kmalloc n.e.ways, and update_slot_info allocates some */
1147		err("out of system memory\n");
1148		rc = -ENOMEM;
1149		goto error_power;
1150	}
1151	slot_cur->func->busno = slot_cur->bus;
1152	slot_cur->func->device = slot_cur->device;
1153	for (i = 0; i < 4; i++)
1154		slot_cur->func->irq[i] = slot_cur->irq[i];
1155
1156	debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1157					slot_cur->bus, slot_cur->device);
1158
1159	if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1160		err("configure_card was unsuccessful...\n");
1161		/* true because don't need to actually deallocate resources,
1162		 * just remove references */
1163		ibmphp_unconfigure_card(&slot_cur, 1);
1164		debug("after unconfigure_card\n");
1165		slot_cur->func = NULL;
1166		rc = -ENOMEM;
1167		goto error_power;
1168	}
1169
1170	function = 0x00;
1171	do {
1172		tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1173							function++);
1174		if (tmp_func && !(tmp_func->dev))
1175			ibm_configure_device(tmp_func);
1176	} while (tmp_func);
1177
1178	attn_off(slot_cur);
1179	if (slot_update(&slot_cur)) {
1180		rc = -EFAULT;
1181		goto exit;
1182	}
1183	ibmphp_print_test();
1184	rc = ibmphp_update_slot_info(slot_cur);
1185exit:
1186	ibmphp_unlock_operations();
1187	return rc;
1188
1189error_nopower:
1190	attn_off(slot_cur);	/* need to turn off if was blinking b4 */
1191	attn_on(slot_cur);
1192error_cont:
1193	rcpr = slot_update(&slot_cur);
1194	if (rcpr) {
1195		rc = rcpr;
1196		goto exit;
1197	}
1198	ibmphp_update_slot_info(slot_cur);
1199	goto exit;
1200
1201error_power:
1202	attn_off(slot_cur);	/* need to turn off if was blinking b4 */
1203	attn_on(slot_cur);
1204	rcpr = power_off(slot_cur);
1205	if (rcpr) {
1206		rc = rcpr;
1207		goto exit;
1208	}
1209	goto error_cont;
1210}
1211
1212/**************************************************************
1213* HOT REMOVING ADAPTER CARD                                   *
1214* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
1215* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
1216          DISABLE POWER ,                                    *
1217**************************************************************/
1218static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1219{
1220	struct slot *slot = hotplug_slot->private;
1221	int rc;
1222
1223	ibmphp_lock_operations();
1224	rc = ibmphp_do_disable_slot(slot);
1225	ibmphp_unlock_operations();
1226	return rc;
1227}
1228
1229int ibmphp_do_disable_slot(struct slot *slot_cur)
1230{
1231	int rc;
1232	u8 flag;
1233
1234	debug("DISABLING SLOT...\n");
1235
1236	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1237		return -ENODEV;
1238	}
1239
1240	flag = slot_cur->flag;
1241	slot_cur->flag = 1;
1242
1243	if (flag == 1) {
1244		rc = validate(slot_cur, DISABLE);
1245			/* checking if powered off already & valid slot # */
1246		if (rc)
1247			goto error;
1248	}
1249	attn_LED_blink(slot_cur);
1250
1251	if (slot_cur->func == NULL) {
1252		/* We need this for fncs's that were there on bootup */
1253		slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1254		if (!slot_cur->func) {
1255			err("out of system memory\n");
1256			rc = -ENOMEM;
1257			goto error;
1258		}
1259		slot_cur->func->busno = slot_cur->bus;
1260		slot_cur->func->device = slot_cur->device;
1261	}
1262
1263	ibm_unconfigure_device(slot_cur->func);
1264
1265	/* If we got here from latch suddenly opening on operating card or
1266	a power fault, there's no power to the card, so cannot
1267	read from it to determine what resources it occupied.  This operation
1268	is forbidden anyhow.  The best we can do is remove it from kernel
1269	lists at least */
1270
1271	if (!flag) {
1272		attn_off(slot_cur);
1273		return 0;
1274	}
1275
1276	rc = ibmphp_unconfigure_card(&slot_cur, 0);
1277	slot_cur->func = NULL;
1278	debug("in disable_slot. after unconfigure_card\n");
1279	if (rc) {
1280		err("could not unconfigure card.\n");
1281		goto error;
1282	}
1283
1284	rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1285	if (rc)
1286		goto error;
1287
1288	attn_off(slot_cur);
1289	rc = slot_update(&slot_cur);
1290	if (rc)
1291		goto exit;
1292
1293	rc = ibmphp_update_slot_info(slot_cur);
1294	ibmphp_print_test();
1295exit:
1296	return rc;
1297
1298error:
1299	/*  Need to turn off if was blinking b4 */
1300	attn_off(slot_cur);
1301	attn_on(slot_cur);
1302	if (slot_update(&slot_cur)) {
1303		rc = -EFAULT;
1304		goto exit;
1305	}
1306	if (flag)
1307		ibmphp_update_slot_info(slot_cur);
1308	goto exit;
1309}
1310
1311struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1312	.owner =			THIS_MODULE,
1313	.set_attention_status =		set_attention_status,
1314	.enable_slot =			enable_slot,
1315	.disable_slot =			ibmphp_disable_slot,
1316	.hardware_test =		NULL,
1317	.get_power_status =		get_power_status,
1318	.get_attention_status =		get_attention_status,
1319	.get_latch_status =		get_latch_status,
1320	.get_adapter_status =		get_adapter_present,
1321	.get_max_bus_speed =		get_max_bus_speed,
1322	.get_cur_bus_speed =		get_cur_bus_speed,
1323/*	.get_max_adapter_speed =	get_max_adapter_speed,
1324	.get_bus_name_status =		get_bus_name,
1325*/
1326};
1327
1328static void ibmphp_unload(void)
1329{
1330	free_slots();
1331	debug("after slots\n");
1332	ibmphp_free_resources();
1333	debug("after resources\n");
1334	ibmphp_free_bus_info_queue();
1335	debug("after bus info\n");
1336	ibmphp_free_ebda_hpc_queue();
1337	debug("after ebda hpc\n");
1338	ibmphp_free_ebda_pci_rsrc_queue();
1339	debug("after ebda pci rsrc\n");
1340	kfree(ibmphp_pci_bus);
1341}
1342
1343static int __init ibmphp_init(void)
1344{
1345	struct pci_bus *bus;
1346	int i = 0;
1347	int rc = 0;
1348
1349	init_flag = 1;
1350
1351	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1352
1353	ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1354	if (!ibmphp_pci_bus) {
1355		err("out of memory\n");
1356		rc = -ENOMEM;
1357		goto exit;
1358	}
1359
1360	bus = pci_find_bus(0, 0);
1361	if (!bus) {
1362		err("Can't find the root pci bus, can not continue\n");
1363		rc = -ENODEV;
1364		goto error;
1365	}
1366	memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1367
1368	ibmphp_debug = debug;
1369
1370	ibmphp_hpc_initvars();
1371
1372	for (i = 0; i < 16; i++)
1373		irqs[i] = 0;
1374
1375	if ((rc = ibmphp_access_ebda()))
1376		goto error;
1377	debug("after ibmphp_access_ebda()\n");
1378
1379	if ((rc = ibmphp_rsrc_init()))
1380		goto error;
1381	debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1382
1383	max_slots = get_max_slots();
1384
1385	if ((rc = ibmphp_register_pci()))
1386		goto error;
1387
1388	if (init_ops()) {
1389		rc = -ENODEV;
1390		goto error;
1391	}
1392
1393	ibmphp_print_test();
1394	if ((rc = ibmphp_hpc_start_poll_thread())) {
1395		goto error;
1396	}
1397
1398	/* lock ourselves into memory with a module
1399	 * count of -1 so that no one can unload us. */
1400	module_put(THIS_MODULE);
1401
1402exit:
1403	return rc;
1404
1405error:
1406	ibmphp_unload();
1407	goto exit;
1408}
1409
1410static void __exit ibmphp_exit(void)
1411{
1412	ibmphp_hpc_stop_poll_thread();
1413	debug("after polling\n");
1414	ibmphp_unload();
1415	debug("done\n");
1416}
1417
1418module_init(ibmphp_init);
1419module_exit(ibmphp_exit);
1420