diff options
| author | Irene Zubarev <zubarev@us.ibm.com> | 2002-09-09 00:40:30 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <greg@kroah.com> | 2002-09-09 00:40:30 -0700 |
| commit | ef7f120ab49379a4745574dddf480c845ea2c7ab (patch) | |
| tree | 05fd1489349c7677423289d7ec1c44daf5a21265 /drivers/hotplug | |
| parent | 9adaeddf526a83c4ad09b33588f20679bec85e22 (diff) | |
[PATCH] IBM PCI Hotplug driver update for PCI based controllers
Diffstat (limited to 'drivers/hotplug')
| -rw-r--r-- | drivers/hotplug/ibmphp.h | 1 | ||||
| -rw-r--r-- | drivers/hotplug/ibmphp_core.c | 5 | ||||
| -rw-r--r-- | drivers/hotplug/ibmphp_ebda.c | 71 | ||||
| -rw-r--r-- | drivers/hotplug/ibmphp_hpc.c | 26 |
4 files changed, 97 insertions, 6 deletions
diff --git a/drivers/hotplug/ibmphp.h b/drivers/hotplug/ibmphp.h index a45b1c7e821b..3828441ce748 100644 --- a/drivers/hotplug/ibmphp.h +++ b/drivers/hotplug/ibmphp.h @@ -737,6 +737,7 @@ struct slot { struct controller { struct ebda_hpc_slot *slots; struct ebda_hpc_bus *buses; + struct pci_dev *ctrl_dev; /* in case where controller is PCI */ u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/ u8 ending_slot_num; u8 revision; diff --git a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c index 72907414443f..713943370a76 100644 --- a/drivers/hotplug/ibmphp_core.c +++ b/drivers/hotplug/ibmphp_core.c @@ -1636,6 +1636,11 @@ static int __init ibmphp_init (void) max_slots = get_max_slots (); + if ((rc = ibmphp_register_pci ())) { + ibmphp_unload (); + return rc; + } + if (init_ops ()) { ibmphp_unload (); return -ENODEV; diff --git a/drivers/hotplug/ibmphp_ebda.c b/drivers/hotplug/ibmphp_ebda.c index 3fba419e7d07..86a88433da5f 100644 --- a/drivers/hotplug/ibmphp_ebda.c +++ b/drivers/hotplug/ibmphp_ebda.c @@ -131,6 +131,7 @@ static void free_ebda_hpc (struct controller *controller) controller->slots = NULL; kfree (controller->buses); controller->buses = NULL; + controller->ctrl_dev = NULL; kfree (controller); } @@ -798,6 +799,8 @@ static char *create_file_name (struct slot * slot_cur) return NULL; } +static struct pci_driver ibmphp_driver; + /* * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of * each hpc from physical address to a list of hot plug controllers based on @@ -929,6 +932,7 @@ static int __init ebda_rsrc_controller (void) hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1); hpc_ptr->irq = readb (io_mem + addr + 2); addr += 3; + debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq); break; case 0: @@ -954,12 +958,6 @@ static int __init ebda_rsrc_controller (void) return -ENODEV; } - /* following 3 line: Now our driver only supports I2c/ISA ctlrType */ - if ((hpc_ptr->ctlr_type != 2) && (hpc_ptr->ctlr_type != 4) && (hpc_ptr->ctlr_type != 0)) { - err ("Please run this driver on IBM xSeries440 or xSeries 235\n "); - return -ENODEV; - } - //reorganize chassis' linked list combine_wpg_for_chassis (); combine_wpg_for_expansion (); @@ -1213,11 +1211,16 @@ void ibmphp_free_ebda_hpc_queue (void) struct controller *controller = NULL; struct list_head *list; struct list_head *next; + int pci_flag = 0; list_for_each_safe (list, next, &ebda_hpc_head) { controller = list_entry (list, struct controller, ebda_hpc_list); if (controller->ctlr_type == 0) release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1)); + else if ((controller->ctlr_type == 1) && (!pci_flag)) { + ++pci_flag; + pci_unregister_driver (&ibmphp_driver); + } free_ebda_hpc (controller); } } @@ -1234,3 +1237,59 @@ void ibmphp_free_ebda_pci_rsrc_queue (void) resource = NULL; } } + +static struct pci_device_id id_table[] __devinitdata = { + { + vendor: PCI_VENDOR_ID_IBM, + device: HPC_DEVICE_ID, + subvendor: PCI_VENDOR_ID_IBM, + subdevice: HPC_SUBSYSTEM_ID, + class: ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00), + }, {} +}; + +MODULE_DEVICE_TABLE(pci, id_table); + +static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *); +static struct pci_driver ibmphp_driver = { + name: "ibmphp", + id_table: id_table, + probe: ibmphp_probe, +}; + +int ibmphp_register_pci (void) +{ + struct controller *ctrl; + struct list_head *tmp; + int rc = 0; + + list_for_each (tmp, &ebda_hpc_head) { + ctrl = list_entry (tmp, struct controller, ebda_hpc_list); + if (ctrl->ctlr_type == 1) { + rc = pci_module_init (&ibmphp_driver); + break; + } + } + return rc; +} +static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids) +{ + struct controller *ctrl; + struct list_head *tmp; + + debug ("inside ibmphp_probe \n"); + + list_for_each (tmp, &ebda_hpc_head) { + ctrl = list_entry (tmp, struct controller, ebda_hpc_list); + if (ctrl->ctlr_type == 1) { + if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) { + ctrl->ctrl_dev = dev; + debug ("found device!!! \n"); + debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device); + return 0; + } + } + } + return -ENODEV; +} + diff --git a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c index de70037b449a..ae959809e8a8 100644 --- a/drivers/hotplug/ibmphp_hpc.c +++ b/drivers/hotplug/ibmphp_hpc.c @@ -379,6 +379,26 @@ static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data) outb (data, port_address); } +static u8 pci_ctrl_read (struct controller *ctrl, u8 offset) +{ + u8 data = 0x00; + debug ("inside pci_ctrl_read\n"); + if (ctrl->ctrl_dev) + pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data); + return data; +} + +static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data) +{ + u8 rc = -ENODEV; + debug ("inside pci_ctrl_write\n"); + if (ctrl->ctrl_dev) { + pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data); + rc = 0; + } + return rc; +} + static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset) { u8 rc; @@ -386,6 +406,9 @@ static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset) case 0: rc = isa_ctrl_read (ctlr, offset); break; + case 1: + rc = pci_ctrl_read (ctlr, offset); + break; case 2: case 4: rc = i2c_ctrl_read (ctlr, base, offset); @@ -403,6 +426,9 @@ static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data) case 0: isa_ctrl_write(ctlr, offset, data); break; + case 1: + rc = pci_ctrl_write (ctlr, offset, data); + break; case 2: case 4: rc = i2c_ctrl_write(ctlr, base, offset, data); |
