2 * CompactPCI Hot Plug Driver PCI functions
4 * Copyright (C) 2002 by SOMA Networks, Inc.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Send feedback to <scottm@somanetworks.com>
26 #include <linux/config.h>
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/pci.h>
30 #include <linux/proc_fs.h>
32 #include "pci_hotplug.h"
33 #include "cpci_hotplug.h"
36 #define MY_NAME "cpci_hotplug"
38 #define MY_NAME THIS_MODULE->name
41 extern int cpci_debug
;
43 #define dbg(format, arg...) \
46 printk (KERN_DEBUG "%s: " format "\n", \
49 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
50 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
51 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
53 #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
56 u8
cpci_get_attention_status(struct slot
* slot
)
61 hs_cap
= pci_bus_find_capability(slot
->bus
,
68 if(pci_bus_read_config_word(slot
->bus
,
74 return hs_csr
& 0x0008 ? 1 : 0;
77 int cpci_set_attention_status(struct slot
* slot
, int status
)
82 hs_cap
= pci_bus_find_capability(slot
->bus
,
89 if(pci_bus_read_config_word(slot
->bus
,
98 hs_csr
&= ~HS_CSR_LOO
;
100 if(pci_bus_write_config_word(slot
->bus
,
109 u16
cpci_get_hs_csr(struct slot
* slot
)
114 hs_cap
= pci_bus_find_capability(slot
->bus
,
121 if(pci_bus_read_config_word(slot
->bus
,
131 u16
cpci_set_hs_csr(struct slot
* slot
, u16 hs_csr
)
136 hs_cap
= pci_bus_find_capability(slot
->bus
,
143 /* Write out the new value */
144 if(pci_bus_write_config_word(slot
->bus
,
151 /* Read back what we just wrote out */
152 if(pci_bus_read_config_word(slot
->bus
,
162 int cpci_check_and_clear_ins(struct slot
* slot
)
168 hs_cap
= pci_bus_find_capability(slot
->bus
,
174 if(pci_bus_read_config_word(slot
->bus
,
180 if(hs_csr
& HS_CSR_INS
) {
181 /* Clear INS (by setting it) */
182 if(pci_bus_write_config_word(slot
->bus
,
193 int cpci_check_ext(struct slot
* slot
)
199 hs_cap
= pci_bus_find_capability(slot
->bus
,
205 if(pci_bus_read_config_word(slot
->bus
,
211 if(hs_csr
& HS_CSR_EXT
) {
217 int cpci_clear_ext(struct slot
* slot
)
222 hs_cap
= pci_bus_find_capability(slot
->bus
,
228 if(pci_bus_read_config_word(slot
->bus
,
234 if(hs_csr
& HS_CSR_EXT
) {
235 /* Clear EXT (by setting it) */
236 if(pci_bus_write_config_word(slot
->bus
,
246 int cpci_led_on(struct slot
* slot
)
251 hs_cap
= pci_bus_find_capability(slot
->bus
,
257 if(pci_bus_read_config_word(slot
->bus
,
263 if((hs_csr
& HS_CSR_LOO
) != HS_CSR_LOO
) {
265 hs_csr
|= HS_CSR_LOO
;
266 if(pci_bus_write_config_word(slot
->bus
,
270 err("Could not set LOO for slot %s",
271 slot
->hotplug_slot
->name
);
278 int cpci_led_off(struct slot
* slot
)
283 hs_cap
= pci_bus_find_capability(slot
->bus
,
289 if(pci_bus_read_config_word(slot
->bus
,
295 if(hs_csr
& HS_CSR_LOO
) {
297 hs_csr
&= ~HS_CSR_LOO
;
298 if(pci_bus_write_config_word(slot
->bus
,
302 err("Could not clear LOO for slot %s",
303 slot
->hotplug_slot
->name
);
312 * Device configuration functions
315 static int cpci_configure_dev(struct pci_bus
*bus
, struct pci_dev
*dev
)
320 dbg("%s - enter", __FUNCTION__
);
322 /* NOTE: device already setup from prior scan */
324 /* FIXME: How would we know if we need to enable the expansion ROM? */
325 pci_write_config_word(dev
, PCI_ROM_ADDRESS
, 0x00L
);
327 /* Assign resources */
328 dbg("assigning resources for %02x:%02x.%x",
329 dev
->bus
->number
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
));
330 for (r
= 0; r
< 6; r
++) {
331 struct resource
*res
= dev
->resource
+ r
;
333 pci_assign_resource(dev
, r
);
335 dbg("finished assigning resources for %02x:%02x.%x",
336 dev
->bus
->number
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
));
338 /* Does this function have an interrupt at all? */
339 dbg("checking for function interrupt");
340 pci_read_config_byte(dev
, PCI_INTERRUPT_PIN
, &irq_pin
);
342 dbg("function uses interrupt pin %d", irq_pin
);
346 * Need to explicitly set irq field to 0 so that it'll get assigned
347 * by the pcibios platform dependent code called by pci_enable_device.
351 dbg("enabling device");
352 pci_enable_device(dev
); /* XXX check return */
353 dbg("now dev->irq = %d", dev
->irq
);
354 if(irq_pin
&& dev
->irq
) {
355 pci_write_config_byte(dev
, PCI_INTERRUPT_LINE
, dev
->irq
);
358 /* Can't use pci_insert_device at the moment, do it manually for now */
359 pci_proc_attach_device(dev
);
360 dbg("notifying drivers");
361 //pci_announce_device_to_drivers(dev);
362 dbg("%s - exit", __FUNCTION__
);
366 static int cpci_configure_bridge(struct pci_bus
* bus
, struct pci_dev
* dev
)
369 struct pci_bus
* child
;
374 dbg("%s - enter", __FUNCTION__
);
376 /* Do basic bridge initialization */
377 rc
= pci_write_config_byte(dev
, PCI_LATENCY_TIMER
, 0x40);
379 printk(KERN_ERR
"%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__
);
381 rc
= pci_write_config_byte(dev
, PCI_SEC_LATENCY_TIMER
, 0x40);
383 printk(KERN_ERR
"%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__
);
385 rc
= pci_write_config_byte(dev
, PCI_CACHE_LINE_SIZE
, L1_CACHE_BYTES
/ 4);
387 printk(KERN_ERR
"%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__
);
391 * Set parent bridge's subordinate field so that configuration space
392 * access will work in pci_scan_bridge and friends.
394 max
= pci_max_busnr();
395 bus
->subordinate
= max
+ 1;
396 pci_write_config_byte(bus
->self
, PCI_SUBORDINATE_BUS
, max
+ 1);
398 /* Scan behind bridge */
399 n
= pci_scan_bridge(bus
, dev
, max
, 2);
400 child
= pci_find_bus(0, max
+ 1);
403 pci_proc_attach_bus(child
);
406 * Update parent bridge's subordinate field if there were more bridges
407 * behind the bridge that was scanned.
410 bus
->subordinate
= n
;
411 pci_write_config_byte(bus
->self
, PCI_SUBORDINATE_BUS
, n
);
415 * Update the bridge resources of the bridge to accommodate devices
418 pci_bus_size_bridges(child
);
419 pci_bus_assign_resources(child
);
421 /* Enable resource mapping via command register */
422 command
= PCI_COMMAND_MASTER
| PCI_COMMAND_INVALIDATE
| PCI_COMMAND_PARITY
| PCI_COMMAND_SERR
;
423 r
= child
->resource
[0];
425 command
|= PCI_COMMAND_IO
;
427 r
= child
->resource
[1];
429 command
|= PCI_COMMAND_MEMORY
;
431 r
= child
->resource
[2];
433 command
|= PCI_COMMAND_MEMORY
;
435 rc
= pci_write_config_word(dev
, PCI_COMMAND
, command
);
437 err("Error setting command register");
441 /* Set bridge control register */
442 command
= PCI_BRIDGE_CTL_PARITY
| PCI_BRIDGE_CTL_SERR
| PCI_BRIDGE_CTL_NO_ISA
;
443 rc
= pci_write_config_word(dev
, PCI_BRIDGE_CONTROL
, command
);
445 err("Error setting bridge control register");
448 dbg("%s - exit", __FUNCTION__
);
452 static int configure_visit_pci_dev(struct pci_dev_wrapped
*wrapped_dev
,
453 struct pci_bus_wrapped
*wrapped_bus
)
456 struct pci_dev
*dev
= wrapped_dev
->dev
;
457 struct pci_bus
*bus
= wrapped_bus
->bus
;
460 dbg("%s - enter", __FUNCTION__
);
463 * We need to fix up the hotplug representation with the Linux
466 if(wrapped_dev
->data
) {
467 slot
= (struct slot
*) wrapped_dev
->data
;
471 /* If it's a bridge, scan behind it for devices */
472 if(dev
->hdr_type
== PCI_HEADER_TYPE_BRIDGE
) {
473 rc
= cpci_configure_bridge(bus
, dev
);
478 /* Actually configure device */
480 rc
= cpci_configure_dev(bus
, dev
);
484 dbg("%s - exit", __FUNCTION__
);
488 static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped
*wrapped_dev
,
489 struct pci_bus_wrapped
*wrapped_bus
)
491 struct pci_dev
*dev
= wrapped_dev
->dev
;
494 dbg("%s - enter", __FUNCTION__
);
498 /* Remove the Linux representation */
499 if(pci_remove_device_safe(dev
)) {
500 err("Could not remove device\n");
505 * Now remove the hotplug representation.
507 if(wrapped_dev
->data
) {
508 slot
= (struct slot
*) wrapped_dev
->data
;
511 dbg("No hotplug representation for %02x:%02x.%x",
512 dev
->bus
->number
, PCI_SLOT(dev
->devfn
), PCI_FUNC(dev
->devfn
));
514 dbg("%s - exit", __FUNCTION__
);
518 static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped
*wrapped_bus
,
519 struct pci_dev_wrapped
*wrapped_dev
)
521 struct pci_bus
*bus
= wrapped_bus
->bus
;
522 struct pci_bus
*parent
= bus
->self
->bus
;
524 dbg("%s - enter", __FUNCTION__
);
526 /* The cleanup code for proc entries regarding buses should be in the kernel... */
528 dbg("detach_pci_bus %s", bus
->procdir
->name
);
529 pci_proc_detach_bus(bus
);
531 /* The cleanup code should live in the kernel... */
532 bus
->self
->subordinate
= NULL
;
534 /* unlink from parent bus */
535 list_del(&bus
->node
);
541 /* Update parent's subordinate field */
543 u8 n
= pci_bus_max_busnr(parent
);
544 if(n
< parent
->subordinate
) {
545 parent
->subordinate
= n
;
546 pci_write_config_byte(parent
->self
, PCI_SUBORDINATE_BUS
, n
);
549 dbg("%s - exit", __FUNCTION__
);
553 static struct pci_visit configure_functions
= {
554 .visit_pci_dev
= configure_visit_pci_dev
,
557 static struct pci_visit unconfigure_functions_phase2
= {
558 .post_visit_pci_bus
= unconfigure_visit_pci_bus_phase2
,
559 .post_visit_pci_dev
= unconfigure_visit_pci_dev_phase2
563 int cpci_configure_slot(struct slot
* slot
)
567 dbg("%s - enter", __FUNCTION__
);
569 if(slot
->dev
== NULL
) {
570 dbg("pci_dev null, finding %02x:%02x:%x",
571 slot
->bus
->number
, PCI_SLOT(slot
->devfn
), PCI_FUNC(slot
->devfn
));
572 slot
->dev
= pci_find_slot(slot
->bus
->number
, slot
->devfn
);
575 /* Still NULL? Well then scan for it! */
576 if(slot
->dev
== NULL
) {
578 dbg("pci_dev still null");
581 * This will generate pci_dev structures for all functions, but
582 * we will only call this case when lookup fails.
584 n
= pci_scan_slot(slot
->bus
, slot
->devfn
);
585 dbg("%s: pci_scan_slot returned %d", __FUNCTION__
, n
);
587 pci_bus_add_devices(slot
->bus
);
588 slot
->dev
= pci_find_slot(slot
->bus
->number
, slot
->devfn
);
589 if(slot
->dev
== NULL
) {
590 err("Could not find PCI device for slot %02x", slot
->number
);
594 dbg("slot->dev = %p", slot
->dev
);
597 struct pci_dev_wrapped wrapped_dev
;
598 struct pci_bus_wrapped wrapped_bus
;
601 memset(&wrapped_dev
, 0, sizeof (struct pci_dev_wrapped
));
602 memset(&wrapped_bus
, 0, sizeof (struct pci_bus_wrapped
));
604 for (i
= 0; i
< 8; i
++) {
605 dev
= pci_find_slot(slot
->bus
->number
,
606 PCI_DEVFN(PCI_SLOT(slot
->dev
->devfn
), i
));
609 wrapped_dev
.dev
= dev
;
610 wrapped_bus
.bus
= slot
->dev
->bus
;
612 wrapped_dev
.data
= NULL
;
614 wrapped_dev
.data
= (void*) slot
;
615 rc
= pci_visit_dev(&configure_functions
, &wrapped_dev
, &wrapped_bus
);
619 dbg("%s - exit, rc = %d", __FUNCTION__
, rc
);
623 int cpci_unconfigure_slot(struct slot
* slot
)
627 struct pci_dev_wrapped wrapped_dev
;
628 struct pci_bus_wrapped wrapped_bus
;
631 dbg("%s - enter", __FUNCTION__
);
634 err("No device for slot %02x\n", slot
->number
);
638 memset(&wrapped_dev
, 0, sizeof (struct pci_dev_wrapped
));
639 memset(&wrapped_bus
, 0, sizeof (struct pci_bus_wrapped
));
641 for (i
= 0; i
< 8; i
++) {
642 dev
= pci_find_slot(slot
->bus
->number
,
643 PCI_DEVFN(PCI_SLOT(slot
->devfn
), i
));
645 wrapped_dev
.dev
= dev
;
646 wrapped_bus
.bus
= dev
->bus
;
648 wrapped_dev
.data
= NULL
;
650 wrapped_dev
.data
= (void*) slot
;
651 dbg("%s - unconfigure phase 2", __FUNCTION__
);
652 rc
= pci_visit_dev(&unconfigure_functions_phase2
,
659 dbg("%s - exit, rc = %d", __FUNCTION__
, rc
);