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 Corp.
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 
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/types.h>
32 #include <linux/proc_fs.h>
33 #include <linux/slab.h>
34 #include <linux/workqueue.h>
35 #include <linux/pci.h>
36 #include <linux/pci_hotplug.h>
37 #include <asm/uaccess.h>
38 #include "cpqphp.h"
39 #include "cpqphp_nvram.h"
40 
41 
42 #define ROM_INT15_PHY_ADDR		0x0FF859
43 #define READ_EV				0xD8A4
44 #define WRITE_EV			0xD8A5
45 
46 struct register_foo {
47 	union {
48 		unsigned long lword;		/* eax */
49 		unsigned short word;		/* ax */
50 
51 		struct {
52 			unsigned char low;	/* al */
53 			unsigned char high;	/* ah */
54 		} byte;
55 	} data;
56 
57 	unsigned char opcode;	/* see below */
58 	unsigned long length;	/* if the reg. is a pointer, how much data */
59 } __attribute__ ((packed));
60 
61 struct all_reg {
62 	struct register_foo eax_reg;
63 	struct register_foo ebx_reg;
64 	struct register_foo ecx_reg;
65 	struct register_foo edx_reg;
66 	struct register_foo edi_reg;
67 	struct register_foo esi_reg;
68 	struct register_foo eflags_reg;
69 } __attribute__ ((packed));
70 
71 
72 struct ev_hrt_header {
73 	u8 Version;
74 	u8 num_of_ctrl;
75 	u8 next;
76 };
77 
78 struct ev_hrt_ctrl {
79 	u8 bus;
80 	u8 device;
81 	u8 function;
82 	u8 mem_avail;
83 	u8 p_mem_avail;
84 	u8 io_avail;
85 	u8 bus_avail;
86 	u8 next;
87 };
88 
89 
90 static u8 evbuffer_init;
91 static u8 evbuffer_length;
92 static u8 evbuffer[1024];
93 
94 static void __iomem *compaq_int15_entry_point;
95 
96 /* lock for ordering int15_bios_call() */
97 static spinlock_t int15_lock;
98 
99 
100 /* This is a series of function that deals with
101  * setting & getting the hotplug resource table in some environment variable.
102  */
103 
104 /*
105  * We really shouldn't be doing this unless there is a _very_ good reason to!!!
106  * greg k-h
107  */
108 
109 
110 static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
111 {
112 	u8 **tByte;
113 
114 	if ((*used + 1) > *avail)
115 		return(1);
116 
117 	*((u8*)*p_buffer) = value;
118 	tByte = (u8**)p_buffer;
119 	(*tByte)++;
120 	*used+=1;
121 	return(0);
122 }
123 
124 
125 static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail)
126 {
127 	if ((*used + 4) > *avail)
128 		return(1);
129 
130 	**p_buffer = value;
131 	(*p_buffer)++;
132 	*used+=4;
133 	return(0);
134 }
135 
136 
137 /*
138  * check_for_compaq_ROM
139  *
140  * this routine verifies that the ROM OEM string is 'COMPAQ'
141  *
142  * returns 0 for non-Compaq ROM, 1 for Compaq ROM
143  */
144 static int check_for_compaq_ROM (void __iomem *rom_start)
145 {
146 	u8 temp1, temp2, temp3, temp4, temp5, temp6;
147 	int result = 0;
148 
149 	temp1 = readb(rom_start + 0xffea + 0);
150 	temp2 = readb(rom_start + 0xffea + 1);
151 	temp3 = readb(rom_start + 0xffea + 2);
152 	temp4 = readb(rom_start + 0xffea + 3);
153 	temp5 = readb(rom_start + 0xffea + 4);
154 	temp6 = readb(rom_start + 0xffea + 5);
155 	if ((temp1 == 'C') &&
156 	    (temp2 == 'O') &&
157 	    (temp3 == 'M') &&
158 	    (temp4 == 'P') &&
159 	    (temp5 == 'A') &&
160 	    (temp6 == 'Q')) {
161 		result = 1;
162 	}
163 	dbg ("%s - returned %d\n", __func__, result);
164 	return result;
165 }
166 
167 
168 static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
169 {
170 	unsigned long flags;
171 	int op = operation;
172 	int ret_val;
173 
174 	if (!compaq_int15_entry_point)
175 		return -ENODEV;
176 
177 	spin_lock_irqsave(&int15_lock, flags);
178 	__asm__ (
179 		"xorl   %%ebx,%%ebx\n" \
180 		"xorl    %%edx,%%edx\n" \
181 		"pushf\n" \
182 		"push %%cs\n" \
183 		"cli\n" \
184 		"call *%6\n"
185 		: "=c" (*buf_size), "=a" (ret_val)
186 		: "a" (op), "c" (*buf_size), "S" (ev_name),
187 		"D" (buffer), "m" (compaq_int15_entry_point)
188 		: "%ebx", "%edx");
189 	spin_unlock_irqrestore(&int15_lock, flags);
190 
191 	return((ret_val & 0xFF00) >> 8);
192 }
193 
194 
195 /*
196  * load_HRT
197  *
198  * Read the hot plug Resource Table from NVRAM
199  */
200 static int load_HRT (void __iomem *rom_start)
201 {
202 	u32 available;
203 	u32 temp_dword;
204 	u8 temp_byte = 0xFF;
205 	u32 rc;
206 
207 	if (!check_for_compaq_ROM(rom_start)) {
208 		return -ENODEV;
209 	}
210 
211 	available = 1024;
212 
213 	/* Now load the EV */
214 	temp_dword = available;
215 
216 	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
217 
218 	evbuffer_length = temp_dword;
219 
220 	/* We're maintaining the resource lists so write FF to invalidate old
221 	 * info
222 	 */
223 	temp_dword = 1;
224 
225 	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
226 
227 	return rc;
228 }
229 
230 
231 /*
232  * store_HRT
233  *
234  * Save the hot plug Resource Table in NVRAM
235  */
236 static u32 store_HRT (void __iomem *rom_start)
237 {
238 	u32 *buffer;
239 	u32 *pFill;
240 	u32 usedbytes;
241 	u32 available;
242 	u32 temp_dword;
243 	u32 rc;
244 	u8 loop;
245 	u8 numCtrl = 0;
246 	struct controller *ctrl;
247 	struct pci_resource *resNode;
248 	struct ev_hrt_header *p_EV_header;
249 	struct ev_hrt_ctrl *p_ev_ctrl;
250 
251 	available = 1024;
252 
253 	if (!check_for_compaq_ROM(rom_start)) {
254 		return(1);
255 	}
256 
257 	buffer = (u32*) evbuffer;
258 
259 	if (!buffer)
260 		return(1);
261 
262 	pFill = buffer;
263 	usedbytes = 0;
264 
265 	p_EV_header = (struct ev_hrt_header *) pFill;
266 
267 	ctrl = cpqhp_ctrl_list;
268 
269 	/* The revision of this structure */
270 	rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
271 	if (rc)
272 		return(rc);
273 
274 	/* The number of controllers */
275 	rc = add_byte( &pFill, 1, &usedbytes, &available);
276 	if (rc)
277 		return(rc);
278 
279 	while (ctrl) {
280 		p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;
281 
282 		numCtrl++;
283 
284 		/* The bus number */
285 		rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
286 		if (rc)
287 			return(rc);
288 
289 		/* The device Number */
290 		rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
291 		if (rc)
292 			return(rc);
293 
294 		/* The function Number */
295 		rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
296 		if (rc)
297 			return(rc);
298 
299 		/* Skip the number of available entries */
300 		rc = add_dword( &pFill, 0, &usedbytes, &available);
301 		if (rc)
302 			return(rc);
303 
304 		/* Figure out memory Available */
305 
306 		resNode = ctrl->mem_head;
307 
308 		loop = 0;
309 
310 		while (resNode) {
311 			loop ++;
312 
313 			/* base */
314 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
315 			if (rc)
316 				return(rc);
317 
318 			/* length */
319 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
320 			if (rc)
321 				return(rc);
322 
323 			resNode = resNode->next;
324 		}
325 
326 		/* Fill in the number of entries */
327 		p_ev_ctrl->mem_avail = loop;
328 
329 		/* Figure out prefetchable memory Available */
330 
331 		resNode = ctrl->p_mem_head;
332 
333 		loop = 0;
334 
335 		while (resNode) {
336 			loop ++;
337 
338 			/* base */
339 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
340 			if (rc)
341 				return(rc);
342 
343 			/* length */
344 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
345 			if (rc)
346 				return(rc);
347 
348 			resNode = resNode->next;
349 		}
350 
351 		/* Fill in the number of entries */
352 		p_ev_ctrl->p_mem_avail = loop;
353 
354 		/* Figure out IO Available */
355 
356 		resNode = ctrl->io_head;
357 
358 		loop = 0;
359 
360 		while (resNode) {
361 			loop ++;
362 
363 			/* base */
364 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
365 			if (rc)
366 				return(rc);
367 
368 			/* length */
369 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
370 			if (rc)
371 				return(rc);
372 
373 			resNode = resNode->next;
374 		}
375 
376 		/* Fill in the number of entries */
377 		p_ev_ctrl->io_avail = loop;
378 
379 		/* Figure out bus Available */
380 
381 		resNode = ctrl->bus_head;
382 
383 		loop = 0;
384 
385 		while (resNode) {
386 			loop ++;
387 
388 			/* base */
389 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
390 			if (rc)
391 				return(rc);
392 
393 			/* length */
394 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
395 			if (rc)
396 				return(rc);
397 
398 			resNode = resNode->next;
399 		}
400 
401 		/* Fill in the number of entries */
402 		p_ev_ctrl->bus_avail = loop;
403 
404 		ctrl = ctrl->next;
405 	}
406 
407 	p_EV_header->num_of_ctrl = numCtrl;
408 
409 	/* Now store the EV */
410 
411 	temp_dword = usedbytes;
412 
413 	rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);
414 
415 	dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);
416 
417 	evbuffer_length = temp_dword;
418 
419 	if (rc) {
420 		err(msg_unable_to_save);
421 		return(1);
422 	}
423 
424 	return(0);
425 }
426 
427 
428 void compaq_nvram_init (void __iomem *rom_start)
429 {
430 	if (rom_start) {
431 		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
432 	}
433 	dbg("int15 entry  = %p\n", compaq_int15_entry_point);
434 
435 	/* initialize our int15 lock */
436 	spin_lock_init(&int15_lock);
437 }
438 
439 
440 int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
441 {
442 	u8 bus, device, function;
443 	u8 nummem, numpmem, numio, numbus;
444 	u32 rc;
445 	u8 *p_byte;
446 	struct pci_resource *mem_node;
447 	struct pci_resource *p_mem_node;
448 	struct pci_resource *io_node;
449 	struct pci_resource *bus_node;
450 	struct ev_hrt_ctrl *p_ev_ctrl;
451 	struct ev_hrt_header *p_EV_header;
452 
453 	if (!evbuffer_init) {
454 		/* Read the resource list information in from NVRAM */
455 		if (load_HRT(rom_start))
456 			memset (evbuffer, 0, 1024);
457 
458 		evbuffer_init = 1;
459 	}
460 
461 	/* If we saved information in NVRAM, use it now */
462 	p_EV_header = (struct ev_hrt_header *) evbuffer;
463 
464 	/* The following code is for systems where version 1.0 of this
465 	 * driver has been loaded, but doesn't support the hardware.
466 	 * In that case, the driver would incorrectly store something
467 	 * in NVRAM.
468 	 */
469 	if ((p_EV_header->Version == 2) ||
470 	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
471 		p_byte = &(p_EV_header->next);
472 
473 		p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);
474 
475 		p_byte += 3;
476 
477 		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
478 			return 2;
479 
480 		bus = p_ev_ctrl->bus;
481 		device = p_ev_ctrl->device;
482 		function = p_ev_ctrl->function;
483 
484 		while ((bus != ctrl->bus) ||
485 		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
486 		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
487 			nummem = p_ev_ctrl->mem_avail;
488 			numpmem = p_ev_ctrl->p_mem_avail;
489 			numio = p_ev_ctrl->io_avail;
490 			numbus = p_ev_ctrl->bus_avail;
491 
492 			p_byte += 4;
493 
494 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
495 				return 2;
496 
497 			/* Skip forward to the next entry */
498 			p_byte += (nummem + numpmem + numio + numbus) * 8;
499 
500 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
501 				return 2;
502 
503 			p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
504 
505 			p_byte += 3;
506 
507 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
508 				return 2;
509 
510 			bus = p_ev_ctrl->bus;
511 			device = p_ev_ctrl->device;
512 			function = p_ev_ctrl->function;
513 		}
514 
515 		nummem = p_ev_ctrl->mem_avail;
516 		numpmem = p_ev_ctrl->p_mem_avail;
517 		numio = p_ev_ctrl->io_avail;
518 		numbus = p_ev_ctrl->bus_avail;
519 
520 		p_byte += 4;
521 
522 		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
523 			return 2;
524 
525 		while (nummem--) {
526 			mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
527 
528 			if (!mem_node)
529 				break;
530 
531 			mem_node->base = *(u32*)p_byte;
532 			dbg("mem base = %8.8x\n",mem_node->base);
533 			p_byte += 4;
534 
535 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
536 				kfree(mem_node);
537 				return 2;
538 			}
539 
540 			mem_node->length = *(u32*)p_byte;
541 			dbg("mem length = %8.8x\n",mem_node->length);
542 			p_byte += 4;
543 
544 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
545 				kfree(mem_node);
546 				return 2;
547 			}
548 
549 			mem_node->next = ctrl->mem_head;
550 			ctrl->mem_head = mem_node;
551 		}
552 
553 		while (numpmem--) {
554 			p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
555 
556 			if (!p_mem_node)
557 				break;
558 
559 			p_mem_node->base = *(u32*)p_byte;
560 			dbg("pre-mem base = %8.8x\n",p_mem_node->base);
561 			p_byte += 4;
562 
563 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
564 				kfree(p_mem_node);
565 				return 2;
566 			}
567 
568 			p_mem_node->length = *(u32*)p_byte;
569 			dbg("pre-mem length = %8.8x\n",p_mem_node->length);
570 			p_byte += 4;
571 
572 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
573 				kfree(p_mem_node);
574 				return 2;
575 			}
576 
577 			p_mem_node->next = ctrl->p_mem_head;
578 			ctrl->p_mem_head = p_mem_node;
579 		}
580 
581 		while (numio--) {
582 			io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
583 
584 			if (!io_node)
585 				break;
586 
587 			io_node->base = *(u32*)p_byte;
588 			dbg("io base = %8.8x\n",io_node->base);
589 			p_byte += 4;
590 
591 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
592 				kfree(io_node);
593 				return 2;
594 			}
595 
596 			io_node->length = *(u32*)p_byte;
597 			dbg("io length = %8.8x\n",io_node->length);
598 			p_byte += 4;
599 
600 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
601 				kfree(io_node);
602 				return 2;
603 			}
604 
605 			io_node->next = ctrl->io_head;
606 			ctrl->io_head = io_node;
607 		}
608 
609 		while (numbus--) {
610 			bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
611 
612 			if (!bus_node)
613 				break;
614 
615 			bus_node->base = *(u32*)p_byte;
616 			p_byte += 4;
617 
618 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
619 				kfree(bus_node);
620 				return 2;
621 			}
622 
623 			bus_node->length = *(u32*)p_byte;
624 			p_byte += 4;
625 
626 			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
627 				kfree(bus_node);
628 				return 2;
629 			}
630 
631 			bus_node->next = ctrl->bus_head;
632 			ctrl->bus_head = bus_node;
633 		}
634 
635 		/* If all of the following fail, we don't have any resources for
636 		 * hot plug add
637 		 */
638 		rc = 1;
639 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
640 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
641 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
642 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
643 
644 		if (rc)
645 			return(rc);
646 	} else {
647 		if ((evbuffer[0] != 0) && (!ctrl->push_flag))
648 			return 1;
649 	}
650 
651 	return 0;
652 }
653 
654 
655 int compaq_nvram_store (void __iomem *rom_start)
656 {
657 	int rc = 1;
658 
659 	if (rom_start == NULL)
660 		return -ENODEV;
661 
662 	if (evbuffer_init) {
663 		rc = store_HRT(rom_start);
664 		if (rc) {
665 			err(msg_unable_to_save);
666 		}
667 	}
668 	return rc;
669 }
670 
671