···1Accessing PCI device resources through sysfs023sysfs, usually mounted at /sys, provides access to PCI resources on platforms4that support it. For example, a given bus might look like this:···48 binary - file contains binary data49 cpumask - file contains a cpumask type5051-The read only files are informational, writes to them will be ignored.52-Writable files can be used to perform actions on the device (e.g. changing53-config space, detaching a device). mmapable files are available via an54-mmap of the file at offset 0 and can be used to do actual device programming55-from userspace. Note that some platforms don't support mmapping of certain56-resources, so be sure to check the return value from any attempted mmap.0000005758Accessing legacy resources through sysfs05960Legacy I/O port and ISA memory resources are also provided in sysfs if the61underlying platform supports them. They're located in the PCI class heirarchy,···83to access legacy memory space.8485Supporting PCI access on new platforms08687In order to support PCI resource mapping as described above, Linux platform88code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function.
···1Accessing PCI device resources through sysfs2+--------------------------------------------34sysfs, usually mounted at /sys, provides access to PCI resources on platforms5that support it. For example, a given bus might look like this:···47 binary - file contains binary data48 cpumask - file contains a cpumask type4950+The read only files are informational, writes to them will be ignored, with51+the exception of the 'rom' file. Writable files can be used to perform52+actions on the device (e.g. changing config space, detaching a device).53+mmapable files are available via an mmap of the file at offset 0 and can be54+used to do actual device programming from userspace. Note that some platforms55+don't support mmapping of certain resources, so be sure to check the return56+value from any attempted mmap.57+58+The 'rom' file is special in that it provides read-only access to the device's59+ROM file, if available. It's disabled by default, however, so applications60+should write the string "1" to the file to enable it before attempting a read61+call, and disable it following the access by writing "0" to the file.6263Accessing legacy resources through sysfs64+----------------------------------------6566Legacy I/O port and ISA memory resources are also provided in sysfs if the67underlying platform supports them. They're located in the PCI class heirarchy,···75to access legacy memory space.7677Supporting PCI access on new platforms78+--------------------------------------7980In order to support PCI resource mapping as described above, Linux platform81code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function.
···1+2+ PCI Error Recovery3+ ------------------4+ May 31, 20055+6+ Current document maintainer:7+ Linas Vepstas <linas@austin.ibm.com>8+9+10+Some PCI bus controllers are able to detect certain "hard" PCI errors11+on the bus, such as parity errors on the data and address busses, as12+well as SERR and PERR errors. These chipsets are then able to disable13+I/O to/from the affected device, so that, for example, a bad DMA14+address doesn't end up corrupting system memory. These same chipsets15+are also able to reset the affected PCI device, and return it to16+working condition. This document describes a generic API form17+performing error recovery.18+19+The core idea is that after a PCI error has been detected, there must20+be a way for the kernel to coordinate with all affected device drivers21+so that the pci card can be made operational again, possibly after22+performing a full electrical #RST of the PCI card. The API below23+provides a generic API for device drivers to be notified of PCI24+errors, and to be notified of, and respond to, a reset sequence.25+26+Preliminary sketch of API, cut-n-pasted-n-modified email from27+Ben Herrenschmidt, circa 5 april 200528+29+The error recovery API support is exposed to the driver in the form of30+a structure of function pointers pointed to by a new field in struct31+pci_driver. The absence of this pointer in pci_driver denotes an32+"non-aware" driver, behaviour on these is platform dependant.33+Platforms like ppc64 can try to simulate pci hotplug remove/add.34+35+The definition of "pci_error_token" is not covered here. It is based on36+Seto's work on the synchronous error detection. We still need to define37+functions for extracting infos out of an opaque error token. This is38+separate from this API.39+40+This structure has the form:41+42+struct pci_error_handlers43+{44+ int (*error_detected)(struct pci_dev *dev, pci_error_token error);45+ int (*mmio_enabled)(struct pci_dev *dev);46+ int (*resume)(struct pci_dev *dev);47+ int (*link_reset)(struct pci_dev *dev);48+ int (*slot_reset)(struct pci_dev *dev);49+};50+51+A driver doesn't have to implement all of these callbacks. The52+only mandatory one is error_detected(). If a callback is not53+implemented, the corresponding feature is considered unsupported.54+For example, if mmio_enabled() and resume() aren't there, then the55+driver is assumed as not doing any direct recovery and requires56+a reset. If link_reset() is not implemented, the card is assumed as57+not caring about link resets, in which case, if recover is supported,58+the core can try recover (but not slot_reset() unless it really did59+reset the slot). If slot_reset() is not supported, link_reset() can60+be called instead on a slot reset.61+62+At first, the call will always be :63+64+ 1) error_detected()65+66+ Error detected. This is sent once after an error has been detected. At67+this point, the device might not be accessible anymore depending on the68+platform (the slot will be isolated on ppc64). The driver may already69+have "noticed" the error because of a failing IO, but this is the proper70+"synchronisation point", that is, it gives a chance to the driver to71+cleanup, waiting for pending stuff (timers, whatever, etc...) to72+complete; it can take semaphores, schedule, etc... everything but touch73+the device. Within this function and after it returns, the driver74+shouldn't do any new IOs. Called in task context. This is sort of a75+"quiesce" point. See note about interrupts at the end of this doc.76+77+ Result codes:78+ - PCIERR_RESULT_CAN_RECOVER:79+ Driever returns this if it thinks it might be able to recover80+ the HW by just banging IOs or if it wants to be given81+ a chance to extract some diagnostic informations (see82+ below).83+ - PCIERR_RESULT_NEED_RESET:84+ Driver returns this if it thinks it can't recover unless the85+ slot is reset.86+ - PCIERR_RESULT_DISCONNECT:87+ Return this if driver thinks it won't recover at all,88+ (this will detach the driver ? or just leave it89+ dangling ? to be decided)90+91+So at this point, we have called error_detected() for all drivers92+on the segment that had the error. On ppc64, the slot is isolated. What93+happens now typically depends on the result from the drivers. If all94+drivers on the segment/slot return PCIERR_RESULT_CAN_RECOVER, we would95+re-enable IOs on the slot (or do nothing special if the platform doesn't96+isolate slots) and call 2). If not and we can reset slots, we go to 4),97+if neither, we have a dead slot. If it's an hotplug slot, we might98+"simulate" reset by triggering HW unplug/replug though.99+100+>>> Current ppc64 implementation assumes that a device driver will101+>>> *not* schedule or semaphore in this routine; the current ppc64102+>>> implementation uses one kernel thread to notify all devices;103+>>> thus, of one device sleeps/schedules, all devices are affected.104+>>> Doing better requires complex multi-threaded logic in the error105+>>> recovery implementation (e.g. waiting for all notification threads106+>>> to "join" before proceeding with recovery.) This seems excessively107+>>> complex and not worth implementing.108+109+>>> The current ppc64 implementation doesn't much care if the device110+>>> attempts i/o at this point, or not. I/O's will fail, returning111+>>> a value of 0xff on read, and writes will be dropped. If the device112+>>> driver attempts more than 10K I/O's to a frozen adapter, it will113+>>> assume that the device driver has gone into an infinite loop, and114+>>> it will panic the the kernel.115+116+ 2) mmio_enabled()117+118+ This is the "early recovery" call. IOs are allowed again, but DMA is119+not (hrm... to be discussed, I prefer not), with some restrictions. This120+is NOT a callback for the driver to start operations again, only to121+peek/poke at the device, extract diagnostic information, if any, and122+eventually do things like trigger a device local reset or some such,123+but not restart operations. This is sent if all drivers on a segment124+agree that they can try to recover and no automatic link reset was125+performed by the HW. If the platform can't just re-enable IOs without126+a slot reset or a link reset, it doesn't call this callback and goes127+directly to 3) or 4). All IOs should be done _synchronously_ from128+within this callback, errors triggered by them will be returned via129+the normal pci_check_whatever() api, no new error_detected() callback130+will be issued due to an error happening here. However, such an error131+might cause IOs to be re-blocked for the whole segment, and thus132+invalidate the recovery that other devices on the same segment might133+have done, forcing the whole segment into one of the next states,134+that is link reset or slot reset.135+136+ Result codes:137+ - PCIERR_RESULT_RECOVERED138+ Driver returns this if it thinks the device is fully139+ functionnal and thinks it is ready to start140+ normal driver operations again. There is no141+ guarantee that the driver will actually be142+ allowed to proceed, as another driver on the143+ same segment might have failed and thus triggered a144+ slot reset on platforms that support it.145+146+ - PCIERR_RESULT_NEED_RESET147+ Driver returns this if it thinks the device is not148+ recoverable in it's current state and it needs a slot149+ reset to proceed.150+151+ - PCIERR_RESULT_DISCONNECT152+ Same as above. Total failure, no recovery even after153+ reset driver dead. (To be defined more precisely)154+155+>>> The current ppc64 implementation does not implement this callback.156+157+ 3) link_reset()158+159+ This is called after the link has been reset. This is typically160+a PCI Express specific state at this point and is done whenever a161+non-fatal error has been detected that can be "solved" by resetting162+the link. This call informs the driver of the reset and the driver163+should check if the device appears to be in working condition.164+This function acts a bit like 2) mmio_enabled(), in that the driver165+is not supposed to restart normal driver I/O operations right away.166+Instead, it should just "probe" the device to check it's recoverability167+status. If all is right, then the core will call resume() once all168+drivers have ack'd link_reset().169+170+ Result codes:171+ (identical to mmio_enabled)172+173+>>> The current ppc64 implementation does not implement this callback.174+175+ 4) slot_reset()176+177+ This is called after the slot has been soft or hard reset by the178+platform. A soft reset consists of asserting the adapter #RST line179+and then restoring the PCI BARs and PCI configuration header. If the180+platform supports PCI hotplug, then it might instead perform a hard181+reset by toggling power on the slot off/on. This call gives drivers182+the chance to re-initialize the hardware (re-download firmware, etc.),183+but drivers shouldn't restart normal I/O processing operations at184+this point. (See note about interrupts; interrupts aren't guaranteed185+to be delivered until the resume() callback has been called). If all186+device drivers report success on this callback, the patform will call187+resume() to complete the error handling and let the driver restart188+normal I/O processing.189+190+A driver can still return a critical failure for this function if191+it can't get the device operational after reset. If the platform192+previously tried a soft reset, it migh now try a hard reset (power193+cycle) and then call slot_reset() again. It the device still can't194+be recovered, there is nothing more that can be done; the platform195+will typically report a "permanent failure" in such a case. The196+device will be considered "dead" in this case.197+198+ Result codes:199+ - PCIERR_RESULT_DISCONNECT200+ Same as above.201+202+>>> The current ppc64 implementation does not try a power-cycle reset203+>>> if the driver returned PCIERR_RESULT_DISCONNECT. However, it should.204+205+ 5) resume()206+207+ This is called if all drivers on the segment have returned208+PCIERR_RESULT_RECOVERED from one of the 3 prevous callbacks.209+That basically tells the driver to restart activity, tht everything210+is back and running. No result code is taken into account here. If211+a new error happens, it will restart a new error handling process.212+213+That's it. I think this covers all the possibilities. The way those214+callbacks are called is platform policy. A platform with no slot reset215+capability for example may want to just "ignore" drivers that can't216+recover (disconnect them) and try to let other cards on the same segment217+recover. Keep in mind that in most real life cases, though, there will218+be only one driver per segment.219+220+Now, there is a note about interrupts. If you get an interrupt and your221+device is dead or has been isolated, there is a problem :)222+223+After much thinking, I decided to leave that to the platform. That is,224+the recovery API only precies that:225+226+ - There is no guarantee that interrupt delivery can proceed from any227+device on the segment starting from the error detection and until the228+restart callback is sent, at which point interrupts are expected to be229+fully operational.230+231+ - There is no guarantee that interrupt delivery is stopped, that is, ad232+river that gets an interrupts after detecting an error, or that detects233+and error within the interrupt handler such that it prevents proper234+ack'ing of the interrupt (and thus removal of the source) should just235+return IRQ_NOTHANDLED. It's up to the platform to deal with taht236+condition, typically by masking the irq source during the duration of237+the error handling. It is expected that the platform "knows" which238+interrupts are routed to error-management capable slots and can deal239+with temporarily disabling that irq number during error processing (this240+isn't terribly complex). That means some IRQ latency for other devices241+sharing the interrupt, but there is simply no other way. High end242+platforms aren't supposed to share interrupts between many devices243+anyway :)244+245+246+Revised: 31 May 2005 Linas Vepstas <linas@austin.ibm.com>
+7
MAINTAINERS
···1987L: linux-abi-devel@lists.sourceforge.net1988S: Maintained198900000001990PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)1991P: Thomas Sailer1992M: sailer@ife.ee.ethz.ch
···1987L: linux-abi-devel@lists.sourceforge.net1988S: Maintained19891990+PCI ERROR RECOVERY1991+P: Linas Vepstas1992+M: linas@austin.ibm.com1993+L: linux-kernel@vger.kernel.org1994+L: linux-pci@atrey.karlin.mff.cuni.cz1995+S: Supported1996+1997PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)1998P: Thomas Sailer1999M: sailer@ife.ee.ethz.ch
+2-1
arch/alpha/kernel/sys_alcor.c
···254 * motherboard, by looking for a 21040 TULIP in slot 6, which is255 * built into XLT and BRET/MAVERICK, but not available on ALCOR.256 */257- dev = pci_find_device(PCI_VENDOR_ID_DEC,258 PCI_DEVICE_ID_DEC_TULIP,259 NULL);260 if (dev && dev->devfn == PCI_DEVFN(6,0)) {···262 printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",263 __FUNCTION__);264 }0265}266267
···254 * motherboard, by looking for a 21040 TULIP in slot 6, which is255 * built into XLT and BRET/MAVERICK, but not available on ALCOR.256 */257+ dev = pci_get_device(PCI_VENDOR_ID_DEC,258 PCI_DEVICE_ID_DEC_TULIP,259 NULL);260 if (dev && dev->devfn == PCI_DEVFN(6,0)) {···262 printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",263 __FUNCTION__);264 }265+ pci_dev_put(dev);266}267268
+3-3
arch/alpha/kernel/sys_sio.c
···105 struct pci_dev *dev = NULL;106107 /* Iterate through the devices, collecting IRQ levels. */108- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {109 if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&110 (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))111 continue;···229 */230231 dev = NULL;232- while ((dev = pci_find_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {233- if (dev->device == PCI_DEVICE_ID_NCR_53C810234 || dev->device == PCI_DEVICE_ID_NCR_53C815235 || dev->device == PCI_DEVICE_ID_NCR_53C820236 || dev->device == PCI_DEVICE_ID_NCR_53C825) {
···105 struct pci_dev *dev = NULL;106107 /* Iterate through the devices, collecting IRQ levels. */108+ for_each_pci_dev(dev) {109 if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&110 (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))111 continue;···229 */230231 dev = NULL;232+ while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {233+ if (dev->device == PCI_DEVICE_ID_NCR_53C810234 || dev->device == PCI_DEVICE_ID_NCR_53C815235 || dev->device == PCI_DEVICE_ID_NCR_53C820236 || dev->device == PCI_DEVICE_ID_NCR_53C825) {
+2-6
arch/frv/mb93090-mb00/pci-frv.c
···142 u16 command;143 struct resource *r, *pr;144145- while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),146- dev != NULL147- ) {148 pci_read_config_word(dev, PCI_COMMAND, &command);149 for(idx = 0; idx < 6; idx++) {150 r = &dev->resource[idx];···186 int idx;187 struct resource *r;188189- while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),190- dev != NULL191- ) {192 int class = dev->class >> 8;193194 /* Don't touch classless devices and host bridges */
···142 u16 command;143 struct resource *r, *pr;144145+ for_each_pci_dev(dev) {00146 pci_read_config_word(dev, PCI_COMMAND, &command);147 for(idx = 0; idx < 6; idx++) {148 r = &dev->resource[idx];···188 int idx;189 struct resource *r;190191+ for_each_pci_dev(dev) {00192 int class = dev->class >> 8;193194 /* Don't touch classless devices and host bridges */
···53 * don't use pci_enable_device().54 */55 printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");56- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)57 acpi_pci_irq_enable(dev);58 } else59 printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\". If it helps, post a report\n");
···53 * don't use pci_enable_device().54 */55 printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");56+ for_each_pci_dev(dev)57 acpi_pci_irq_enable(dev);58 } else59 printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\". If it helps, post a report\n");
···527{528 struct pci_dev *pdev = start;529530+ while ((pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev)))531+ if (pdev->device == PCI_DEVICE_ID_SUN_EBUS ||532+ pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)00533 break;0534535+ *is_rio_p = !!(pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS));000536537 return pdev;538}···637 ebus->is_rio = is_rio;638 ++num_ebus;639 }640+ pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */641642#ifdef CONFIG_SUN_AUXIO643 auxio_probe();
+3-4
drivers/acpi/pci_irq.c
···361362 if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {363 /* PC card has the same IRQ as its cardbridge */364- pci_read_config_byte(bridge, PCI_INTERRUPT_PIN,365- &bridge_pin);366 if (!bridge_pin) {367 ACPI_DEBUG_PRINT((ACPI_DB_INFO,368 "No interrupt pin configured for device %s\n",···411 if (!dev)412 return_VALUE(-EINVAL);413414- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);415 if (!pin) {416 ACPI_DEBUG_PRINT((ACPI_DB_INFO,417 "No interrupt pin configured for device %s\n",···502 if (!dev || !dev->bus)503 return_VOID;504505- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);506 if (!pin)507 return_VOID;508 pin--;
···361362 if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {363 /* PC card has the same IRQ as its cardbridge */364+ bridge_pin = bridge->pin;0365 if (!bridge_pin) {366 ACPI_DEBUG_PRINT((ACPI_DB_INFO,367 "No interrupt pin configured for device %s\n",···412 if (!dev)413 return_VALUE(-EINVAL);414415+ pin = dev->pin;416 if (!pin) {417 ACPI_DEBUG_PRINT((ACPI_DB_INFO,418 "No interrupt pin configured for device %s\n",···503 if (!dev || !dev->bus)504 return_VOID;505506+ pin = dev->pin;507 if (!pin)508 return_VOID;509 pin--;
+1-1
drivers/block/DAC960.c
···7179{7180 int ret;71817182- ret = pci_module_init(&DAC960_pci_driver);7183#ifdef DAC960_GAM_MINOR7184 if (!ret)7185 DAC960_gam_init();
···7179{7180 int ret;71817182+ ret = pci_register_driver(&DAC960_pci_driver);7183#ifdef DAC960_GAM_MINOR7184 if (!ret)7185 DAC960_gam_init();
···2630 hold_mem_node = NULL;2631 }26322633- /* If we have prefetchable memory resources copy them and 2634- * fill in the bridge's memory range registers. Otherwise,2635- * fill in the range registers with values that disable them. */2636- if (p_mem_node) {2637- memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));2638- p_mem_node->next = NULL;26392640- /* set Pre Mem base and Limit registers */2641- temp_word = p_mem_node->base >> 16;2642- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);26432644- temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;2645- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);2646- } else {2647- temp_word = 0xFFFF;2648- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);2649-2650- temp_word = 0x0000;2651- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);2652-2653- kfree(hold_p_mem_node);2654- hold_p_mem_node = NULL;2655- }26562657 /* Adjust this to compensate for extra adjustment in first loop */2658 irqs.barber_pole--;
···2630 hold_mem_node = NULL;2631 }26322633+ memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));2634+ p_mem_node->next = NULL;000026352636+ /* set Pre Mem base and Limit registers */2637+ temp_word = p_mem_node->base >> 16;2638+ rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);26392640+ temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;2641+ rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);000000000026422643 /* Adjust this to compensate for extra adjustment in first loop */2644 irqs.barber_pole--;
+116-22
drivers/pci/hotplug/cpqphp_sysfs.c
···33#include <linux/proc_fs.h>34#include <linux/workqueue.h>35#include <linux/pci.h>036#include "cpqphp.h"3738-39-/* A few routines that create sysfs entries for the hot plug controller */40-41-static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)42{43- struct pci_dev *pci_dev;44- struct controller *ctrl;45- char * out = buf;46 int index;47 struct pci_resource *res;48-49- pci_dev = container_of (dev, struct pci_dev, dev);50- ctrl = pci_get_drvdata(pci_dev);5152 out += sprintf(buf, "Free resources: memory\n");53 index = 11;···7374 return out - buf;75}76-static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);7778-static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)79{80- struct pci_dev *pci_dev;81- struct controller *ctrl;82 char * out = buf;83 int index;84 struct pci_resource *res;85 struct pci_func *new_slot;86 struct slot *slot;8788- pci_dev = container_of (dev, struct pci_dev, dev);89- ctrl = pci_get_drvdata(pci_dev);90-91- slot=ctrl->slot;9293 while (slot) {94 new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);···121122 return out - buf;123}124-static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);125126-void cpqhp_create_ctrl_files (struct controller *ctrl)127{128- device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);129- device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);000130}000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
···33#include <linux/proc_fs.h>34#include <linux/workqueue.h>35#include <linux/pci.h>36+#include <linux/debugfs.h>37#include "cpqphp.h"3839+static int show_ctrl (struct controller *ctrl, char *buf)00040{41+ char *out = buf;0042 int index;43 struct pci_resource *res;0004445 out += sprintf(buf, "Free resources: memory\n");46 index = 11;···8081 return out - buf;82}08384+static int show_dev (struct controller *ctrl, char *buf)85{0086 char * out = buf;87 int index;88 struct pci_resource *res;89 struct pci_func *new_slot;90 struct slot *slot;9192+ slot = ctrl->slot;0009394 while (slot) {95 new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);···134135 return out - buf;136}0137138+static int spew_debug_info(struct controller *ctrl, char *data, int size)139{140+ int used;141+142+ used = size - show_ctrl(ctrl, data);143+ used = (size - used) - show_dev(ctrl, &data[used]);144+ return used;145}146+147+struct ctrl_dbg {148+ int size;149+ char *data;150+ struct controller *ctrl;151+};152+153+#define MAX_OUTPUT (4*PAGE_SIZE)154+155+static int open(struct inode *inode, struct file *file)156+{157+ struct controller *ctrl = inode->u.generic_ip;158+ struct ctrl_dbg *dbg;159+ int retval = -ENOMEM;160+161+ lock_kernel();162+ dbg = kmalloc(sizeof(*dbg), GFP_KERNEL);163+ if (!dbg)164+ goto exit;165+ dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL);166+ if (!dbg->data) {167+ kfree(dbg);168+ goto exit;169+ }170+ dbg->size = spew_debug_info(ctrl, dbg->data, MAX_OUTPUT);171+ file->private_data = dbg;172+ retval = 0;173+exit:174+ unlock_kernel();175+ return retval;176+}177+178+static loff_t lseek(struct file *file, loff_t off, int whence)179+{180+ struct ctrl_dbg *dbg;181+ loff_t new = -1;182+183+ lock_kernel();184+ dbg = file->private_data;185+186+ switch (whence) {187+ case 0:188+ new = off;189+ break;190+ case 1:191+ new = file->f_pos + off;192+ break;193+ }194+ if (new < 0 || new > dbg->size) {195+ unlock_kernel();196+ return -EINVAL;197+ }198+ unlock_kernel();199+ return (file->f_pos = new);200+}201+202+static ssize_t read(struct file *file, char __user *buf,203+ size_t nbytes, loff_t *ppos)204+{205+ struct ctrl_dbg *dbg = file->private_data;206+ return simple_read_from_buffer(buf, nbytes, ppos, dbg->data, dbg->size);207+}208+209+static int release(struct inode *inode, struct file *file)210+{211+ struct ctrl_dbg *dbg = file->private_data;212+213+ kfree(dbg->data);214+ kfree(dbg);215+ return 0;216+}217+218+static struct file_operations debug_ops = {219+ .owner = THIS_MODULE,220+ .open = open,221+ .llseek = lseek,222+ .read = read,223+ .release = release,224+};225+226+static struct dentry *root;227+228+void cpqhp_initialize_debugfs(void)229+{230+ if (!root)231+ root = debugfs_create_dir("cpqhp", NULL);232+}233+234+void cpqhp_shutdown_debugfs(void)235+{236+ debugfs_remove(root);237+}238+239+void cpqhp_create_debugfs_files(struct controller *ctrl)240+{241+ ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);242+}243+244+void cpqhp_remove_debugfs_files(struct controller *ctrl)245+{246+ if (ctrl->dentry)247+ debugfs_remove(ctrl->dentry);248+ ctrl->dentry = NULL;249+}250+
···787788 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;789790+ /* Enable detection that we turned off at slot power-off time */791 if (!pciehp_poll_mode)792+ slot_cmd = slot_cmd |793+ PWR_FAULT_DETECT_ENABLE |794+ MRL_DETECT_ENABLE |795+ PRSN_DETECT_ENABLE |796+ HP_INTR_ENABLE;797798 retval = pcie_write_cmd(slot, slot_cmd);799···833834 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;835836+ /*837+ * If we get MRL or presence detect interrupts now, the isr838+ * will notice the sticky power-fault bit too and issue power839+ * indicator change commands. This will lead to an endless loop840+ * of command completions, since the power-fault bit remains on841+ * till the slot is powered on again.842+ */843 if (!pciehp_poll_mode)844+ slot_cmd = (slot_cmd &845+ ~PWR_FAULT_DETECT_ENABLE &846+ ~MRL_DETECT_ENABLE &847+ ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE;848849 retval = pcie_write_cmd(slot, slot_cmd);850
+28-24
drivers/pci/hotplug/pciehp_pci.c
···34#include "../pci.h"35#include "pciehp.h"3600000000000000000000000003738int pciehp_configure_device(struct slot *p_slot)39{···80 }8182 for (fn = 0; fn < 8; fn++) {83- if (!(dev = pci_find_slot(p_slot->bus,84- PCI_DEVFN(p_slot->device, fn))))85 continue;86 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {87 err("Cannot hot-add display device %s\n",···90 }91 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||92 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {93- /* Find an unused bus number for the new bridge */94- struct pci_bus *child;95- unsigned char busnr, start = parent->secondary;96- unsigned char end = parent->subordinate;97- for (busnr = start; busnr <= end; busnr++) {98- if (!pci_find_bus(pci_domain_nr(parent),99- busnr))100- break;101- }102- if (busnr >= end) {103- err("No free bus for hot-added bridge\n");104- continue;105- }106- child = pci_add_new_bus(parent, dev, busnr);107- if (!child) {108- err("Cannot add new bus for %s\n",109- pci_name(dev));110- continue;111- }112- child->subordinate = pci_do_scan_bus(child);113- pci_bus_size_bridges(child);114 }115 /* TBD: program firmware provided _HPP values */116 /* program_fw_provided_values(dev); */···9899 pci_bus_assign_resources(parent);100 pci_bus_add_devices(parent);101- pci_enable_bridges(parent);102 return 0;103}104
···34#include "../pci.h"35#include "pciehp.h"3637+static int pciehp_add_bridge(struct pci_dev *dev)38+{39+ struct pci_bus *parent = dev->bus;40+ int pass, busnr, start = parent->secondary;41+ int end = parent->subordinate;42+43+ for (busnr = start; busnr <= end; busnr++) {44+ if (!pci_find_bus(pci_domain_nr(parent), busnr))45+ break;46+ }47+ if (busnr-- > end) {48+ err("No bus number available for hot-added bridge %s\n",49+ pci_name(dev));50+ return -1;51+ }52+ for (pass = 0; pass < 2; pass++)53+ busnr = pci_scan_bridge(parent, dev, busnr, pass);54+ if (!dev->subordinate)55+ return -1;56+ pci_bus_size_bridges(dev->subordinate);57+ pci_bus_assign_resources(parent);58+ pci_enable_bridges(parent);59+ pci_bus_add_devices(parent);60+ return 0;61+}6263int pciehp_configure_device(struct slot *p_slot)64{···55 }5657 for (fn = 0; fn < 8; fn++) {58+ dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));59+ if (!dev)60 continue;61 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {62 err("Cannot hot-add display device %s\n",···65 }66 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||67 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {68+ pciehp_add_bridge(dev);0000000000000000000069 }70 /* TBD: program firmware provided _HPP values */71 /* program_fw_provided_values(dev); */···9394 pci_bus_assign_resources(parent);95 pci_bus_add_devices(parent);096 return 0;97}98
+8-5
drivers/pci/hotplug/pciehprm_acpi.c
···174 acpi_status status;175 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));176 struct pci_dev *pdev = dev;0177 u8 *path_name;0178 /*179 * Per PCI firmware specification, we should run the ACPI _OSC180 * method to get control of hotplug hardware before using it.···192 */193 if (!pdev || !pdev->bus->parent)194 break;0195 dbg("Could not find %s in acpi namespace, trying parent\n",196 pci_name(pdev));197- if (!pdev->bus->parent->self)198 /* Parent must be a host bridge */199 handle = acpi_get_pci_rootbridge_handle(200- pci_domain_nr(pdev->bus->parent),201- pdev->bus->parent->number);202 else203 handle = DEVICE_ACPI_HANDLE(204- &(pdev->bus->parent->self->dev));205- pdev = pdev->bus->parent->self;206 }207208 while (handle) {
···174 acpi_status status;175 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));176 struct pci_dev *pdev = dev;177+ struct pci_bus *parent;178 u8 *path_name;179+180 /*181 * Per PCI firmware specification, we should run the ACPI _OSC182 * method to get control of hotplug hardware before using it.···190 */191 if (!pdev || !pdev->bus->parent)192 break;193+ parent = pdev->bus->parent;194 dbg("Could not find %s in acpi namespace, trying parent\n",195 pci_name(pdev));196+ if (!parent->self)197 /* Parent must be a host bridge */198 handle = acpi_get_pci_rootbridge_handle(199+ pci_domain_nr(parent),200+ parent->number);201 else202 handle = DEVICE_ACPI_HANDLE(203+ &(parent->self->dev));204+ pdev = parent->self;205 }206207 while (handle) {
+3-24
drivers/pci/hotplug/rpadlpar_core.c
···112 return NULL;113}114115-static void rpadlpar_claim_one_bus(struct pci_bus *b)116-{117- struct list_head *ld;118- struct pci_bus *child_bus;119-120- for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {121- struct pci_dev *dev = pci_dev_b(ld);122- int i;123-124- for (i = 0; i < PCI_NUM_RESOURCES; i++) {125- struct resource *r = &dev->resource[i];126-127- if (r->parent || !r->start || !r->flags)128- continue;129- rpaphp_claim_resource(dev, i);130- }131- }132-133- list_for_each_entry(child_bus, &b->children, node)134- rpadlpar_claim_one_bus(child_bus);135-}136-137static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,138 struct device_node *dev_dn)139{···132 struct pci_controller *phb = pdn->phb;133 struct pci_dev *dev = NULL;134135- rpaphp_eeh_init_nodes(dn);0136 /* Add EADS device to PHB bus, adding new entry to bus->devices */137 dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);138 if (!dev) {···149 rpaphp_init_new_devs(dev->subordinate);150151 /* Claim new bus resources */152- rpadlpar_claim_one_bus(dev->bus);153154 /* ioremap() for child bus, which may or may not succeed */155 (void) remap_bus_range(dev->bus);
···112 return NULL;113}1140000000000000000000000115static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,116 struct device_node *dev_dn)117{···154 struct pci_controller *phb = pdn->phb;155 struct pci_dev *dev = NULL;156157+ eeh_add_device_tree_early(dn);158+159 /* Add EADS device to PHB bus, adding new entry to bus->devices */160 dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);161 if (!dev) {···170 rpaphp_init_new_devs(dev->subordinate);171172 /* Claim new bus resources */173+ pcibios_claim_one_bus(dev->bus);174175 /* ioremap() for child bus, which may or may not succeed */176 (void) remap_bus_range(dev->bus);
+7-40
drivers/pci/hotplug/rpaphp_pci.c
···62}63EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);6465-int rpaphp_claim_resource(struct pci_dev *dev, int resource)66-{67- struct resource *res = &dev->resource[resource];68- struct resource *root = pci_find_parent_resource(dev, res);69- char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";70- int err = -EINVAL;71-72- if (root != NULL) {73- err = request_resource(root, res);74- }75-76- if (err) {77- err("PCI: %s region %d of %s %s [%lx:%lx]\n",78- root ? "Address space collision on" :79- "No parent found for",80- resource, dtype, pci_name(dev), res->start, res->end);81- }82- return err;83-}84-85-EXPORT_SYMBOL_GPL(rpaphp_claim_resource);86-87static int rpaphp_get_sensor_state(struct slot *slot, int *state)88{89 int rc;···155156 if (r->parent || !r->start || !r->flags)157 continue;158- rpaphp_claim_resource(dev, i);159 }160 }161 }···265 return dev;266}267268-void rpaphp_eeh_init_nodes(struct device_node *dn)269-{270- struct device_node *sib;271-272- for (sib = dn->child; sib; sib = sib->sibling) 273- rpaphp_eeh_init_nodes(sib);274- eeh_add_device_early(dn);275- return;276-277-}278-EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);279-280static void print_slot_pci_funcs(struct pci_bus *bus)281{282 struct device_node *dn;···290 if (!dn)291 goto exit;292293- rpaphp_eeh_init_nodes(dn);294 dev = rpaphp_pci_config_slot(bus);295 if (!dev) {296 err("%s: can't find any devices.\n", __FUNCTION__);···336337static int setup_pci_hotplug_slot_info(struct slot *slot)338{00339 dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",340 __FUNCTION__);341- rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status);342 rpaphp_get_pci_adapter_status(slot, 1,343- &slot->hotplug_slot->info->344- adapter_status);345- if (slot->hotplug_slot->info->adapter_status == NOT_VALID) {346 err("%s: NOT_VALID: skip dn->full_name=%s\n",347 __FUNCTION__, slot->dn->full_name);348 return -EINVAL;
···62}63EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);64000000000000000000000065static int rpaphp_get_sensor_state(struct slot *slot, int *state)66{67 int rc;···177178 if (r->parent || !r->start || !r->flags)179 continue;180+ pci_claim_resource(dev, i);181 }182 }183 }···287 return dev;288}289000000000000290static void print_slot_pci_funcs(struct pci_bus *bus)291{292 struct device_node *dn;···324 if (!dn)325 goto exit;326327+ eeh_add_device_tree_early(dn);328 dev = rpaphp_pci_config_slot(bus);329 if (!dev) {330 err("%s: can't find any devices.\n", __FUNCTION__);···370371static int setup_pci_hotplug_slot_info(struct slot *slot)372{373+ struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info;374+375 dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",376 __FUNCTION__);377+ rpaphp_get_power_status(slot, &hotplug_slot_info->power_status);378 rpaphp_get_pci_adapter_status(slot, 1,379+ &hotplug_slot_info->adapter_status);380+ if (hotplug_slot_info->adapter_status == NOT_VALID) {0381 err("%s: NOT_VALID: skip dn->full_name=%s\n",382 __FUNCTION__, slot->dn->full_name);383 return -EINVAL;
+4
drivers/pci/hotplug/shpchp.h
···98 enum pci_bus_speed speed;99 u32 first_slot; /* First physical slot number */100 u8 slot_bus; /* Bus where the slots handled by this controller sit */0000101};102103struct hotplug_params {
···98 enum pci_bus_speed speed;99 u32 first_slot; /* First physical slot number */100 u8 slot_bus; /* Bus where the slots handled by this controller sit */101+ u32 cap_offset;102+ unsigned long mmio_base;103+ unsigned long mmio_size;104+ volatile int cmd_busy;105};106107struct hotplug_params {
···248 up(&ctrl->crit_sect);249 return WRONG_BUS_FREQUENCY;250 }251- wait_for_ctrl_irq (ctrl);252253 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {254 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",···329 up(&ctrl->crit_sect);330 return -1;331 }332-333- /* Wait for the command to complete */334- wait_for_ctrl_irq (ctrl);335336 rc = p_slot->hpc_ops->check_cmd_status(ctrl);337 if (rc) {···348 up(&ctrl->crit_sect);349 return WRONG_BUS_FREQUENCY;350 }351- wait_for_ctrl_irq (ctrl);352353 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {354 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",···362 up(&ctrl->crit_sect);363 return rc;364 }365- wait_for_ctrl_irq (ctrl);366367 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {368 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);···488 up(&ctrl->crit_sect);489 return rc;490 }491- wait_for_ctrl_irq (ctrl);492493 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {494 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);···525526 p_slot->hpc_ops->green_led_on(p_slot);527528- /* Wait for the command to complete */529- wait_for_ctrl_irq (ctrl);530-531 /* Done with exclusive hardware access */532 up(&ctrl->crit_sect);533···542 up(&ctrl->crit_sect);543 return rc;544 }545- /* Wait for the command to complete */546- wait_for_ctrl_irq (ctrl);547548 rc = p_slot->hpc_ops->check_cmd_status(ctrl);549 if (rc) {···591 up(&ctrl->crit_sect);592 return rc;593 }594- /* Wait for the command to complete */595- wait_for_ctrl_irq (ctrl);596597 rc = p_slot->hpc_ops->check_cmd_status(ctrl);598 if (rc) {···607 up(&ctrl->crit_sect);608 return rc;609 }610- /* Wait for the command to complete */611- wait_for_ctrl_irq (ctrl);612613 /* Done with exclusive hardware access */614 up(&ctrl->crit_sect);···659 down(&p_slot->ctrl->crit_sect);660661 p_slot->hpc_ops->green_led_off(p_slot);662-663- /* Wait for the command to complete */664- wait_for_ctrl_irq (p_slot->ctrl);665666 /* Done with exclusive hardware access */667 up(&p_slot->ctrl->crit_sect);···771 down(&ctrl->crit_sect);772773 p_slot->hpc_ops->green_led_on(p_slot);774- /* Wait for the command to complete */775- wait_for_ctrl_irq (ctrl);776777 p_slot->hpc_ops->set_attention_status(p_slot, 0);778-779- /* Wait for the command to complete */780- wait_for_ctrl_irq (ctrl);781782 /* Done with exclusive hardware access */783 up(&ctrl->crit_sect);···782 down(&ctrl->crit_sect);783784 p_slot->hpc_ops->green_led_off(p_slot);785- /* Wait for the command to complete */786- wait_for_ctrl_irq (ctrl);787788 p_slot->hpc_ops->set_attention_status(p_slot, 0);789- /* Wait for the command to complete */790- wait_for_ctrl_irq (ctrl);791792 /* Done with exclusive hardware access */793 up(&ctrl->crit_sect);···817818 /* blink green LED and turn off amber */819 p_slot->hpc_ops->green_led_blink(p_slot);820- /* Wait for the command to complete */821- wait_for_ctrl_irq (ctrl);822823 p_slot->hpc_ops->set_attention_status(p_slot, 0);824-825- /* Wait for the command to complete */826- wait_for_ctrl_irq (ctrl);827828 /* Done with exclusive hardware access */829 up(&ctrl->crit_sect);···837 down(&ctrl->crit_sect);838839 p_slot->hpc_ops->set_attention_status(p_slot, 1);840- /* Wait for the command to complete */841- wait_for_ctrl_irq (ctrl);842843 p_slot->hpc_ops->green_led_off(p_slot);844- /* Wait for the command to complete */845- wait_for_ctrl_irq (ctrl);846847 /* Done with exclusive hardware access */848 up(&ctrl->crit_sect);
···248 up(&ctrl->crit_sect);249 return WRONG_BUS_FREQUENCY;250 }0251252 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {253 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",···330 up(&ctrl->crit_sect);331 return -1;332 }000333334 rc = p_slot->hpc_ops->check_cmd_status(ctrl);335 if (rc) {···352 up(&ctrl->crit_sect);353 return WRONG_BUS_FREQUENCY;354 }0355356 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {357 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",···367 up(&ctrl->crit_sect);368 return rc;369 }0370371 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {372 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);···494 up(&ctrl->crit_sect);495 return rc;496 }0497498 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {499 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);···532533 p_slot->hpc_ops->green_led_on(p_slot);534000535 /* Done with exclusive hardware access */536 up(&ctrl->crit_sect);537···552 up(&ctrl->crit_sect);553 return rc;554 }00555556 rc = p_slot->hpc_ops->check_cmd_status(ctrl);557 if (rc) {···603 up(&ctrl->crit_sect);604 return rc;605 }00606607 rc = p_slot->hpc_ops->check_cmd_status(ctrl);608 if (rc) {···621 up(&ctrl->crit_sect);622 return rc;623 }00624625 /* Done with exclusive hardware access */626 up(&ctrl->crit_sect);···675 down(&p_slot->ctrl->crit_sect);676677 p_slot->hpc_ops->green_led_off(p_slot);000678679 /* Done with exclusive hardware access */680 up(&p_slot->ctrl->crit_sect);···790 down(&ctrl->crit_sect);791792 p_slot->hpc_ops->green_led_on(p_slot);00793794 p_slot->hpc_ops->set_attention_status(p_slot, 0);000795796 /* Done with exclusive hardware access */797 up(&ctrl->crit_sect);···806 down(&ctrl->crit_sect);807808 p_slot->hpc_ops->green_led_off(p_slot);00809810 p_slot->hpc_ops->set_attention_status(p_slot, 0);00811812 /* Done with exclusive hardware access */813 up(&ctrl->crit_sect);···845846 /* blink green LED and turn off amber */847 p_slot->hpc_ops->green_led_blink(p_slot);00848849 p_slot->hpc_ops->set_attention_status(p_slot, 0);000850851 /* Done with exclusive hardware access */852 up(&ctrl->crit_sect);···870 down(&ctrl->crit_sect);871872 p_slot->hpc_ops->set_attention_status(p_slot, 1);00873874 p_slot->hpc_ops->green_led_off(p_slot);00875876 /* Done with exclusive hardware access */877 up(&ctrl->crit_sect);
···275 return;276}277278+static inline int shpc_wait_cmd(struct controller *ctrl)279+{280+ int retval = 0;281+ unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;282+ unsigned long timeout = msecs_to_jiffies(timeout_msec);283+ int rc = wait_event_interruptible_timeout(ctrl->queue,284+ !ctrl->cmd_busy, timeout);285+ if (!rc) {286+ retval = -EIO;287+ err("Command not completed in %d msec\n", timeout_msec);288+ } else if (rc < 0) {289+ retval = -EINTR;290+ info("Command was interrupted by a signal\n");291+ }292+ ctrl->cmd_busy = 0;293+294+ return retval;295+}296+297static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)298{299 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;···314 /* To make sure the Controller Busy bit is 0 before we send out the315 * command. 316 */317+ slot->ctrl->cmd_busy = 1;318 writew(temp_word, php_ctlr->creg + CMD);319+320+ /*321+ * Wait for command completion.322+ */323+ retval = shpc_wait_cmd(slot->ctrl);324325 DBG_LEAVE_ROUTINE 326 return retval;···604 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);605606 if (pi == 2) {607+ *mode = (sec_bus_status & 0x0100) >> 8;608 } else {609 retval = -1;610 }···791 }792 if (php_ctlr->pci_dev) {793 iounmap(php_ctlr->creg);794+ release_mem_region(ctrl->mmio_base, ctrl->mmio_size);795 php_ctlr->pci_dev = NULL;796 }797···1058 if (intr_loc & 0x0001) {1059 /* 1060 * Command Complete Interrupt Pending 1061+ * RO only - clear by writing 1 to the Command Completion1062 * Detect bit in Controller SERR-INT register1063 */1064 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);1065+ temp_dword &= 0xfffdffff;1066 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);1067+ ctrl->cmd_busy = 0;1068 wake_up_interruptible(&ctrl->queue);1069 }1070···1121 int retval = 0;1122 u8 pi;1123 u32 slot_avail1, slot_avail2;011241125 DBG_ENTER_ROUTINE 1126···1140 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);11411142 if (pi == 2) {1143+ if (slot_avail2 & SLOT_133MHZ_PCIX_533)1144 bus_speed = PCIX_133MHZ_533;1145+ else if (slot_avail2 & SLOT_100MHZ_PCIX_533)1146 bus_speed = PCIX_100MHZ_533;1147+ else if (slot_avail2 & SLOT_66MHZ_PCIX_533)1148 bus_speed = PCIX_66MHZ_533;1149+ else if (slot_avail2 & SLOT_133MHZ_PCIX_266)1150 bus_speed = PCIX_133MHZ_266;1151+ else if (slot_avail2 & SLOT_100MHZ_PCIX_266)1152 bus_speed = PCIX_100MHZ_266;1153+ else if (slot_avail2 & SLOT_66MHZ_PCIX_266)1154 bus_speed = PCIX_66MHZ_266;1155+ else if (slot_avail1 & SLOT_133MHZ_PCIX)1156 bus_speed = PCIX_133MHZ;1157+ else if (slot_avail1 & SLOT_100MHZ_PCIX)1158 bus_speed = PCIX_100MHZ;1159+ else if (slot_avail1 & SLOT_66MHZ_PCIX)1160 bus_speed = PCIX_66MHZ;1161+ else if (slot_avail2 & SLOT_66MHZ)1162 bus_speed = PCI_66MHZ;1163+ else if (slot_avail1 & SLOT_33MHZ)1164 bus_speed = PCI_33MHZ;1165 else bus_speed = PCI_SPEED_UNKNOWN;1166 } else {1167+ if (slot_avail1 & SLOT_133MHZ_PCIX)1168 bus_speed = PCIX_133MHZ;1169+ else if (slot_avail1 & SLOT_100MHZ_PCIX)1170 bus_speed = PCIX_100MHZ;1171+ else if (slot_avail1 & SLOT_66MHZ_PCIX)1172 bus_speed = PCIX_66MHZ;1173+ else if (slot_avail2 & SLOT_66MHZ)1174 bus_speed = PCI_66MHZ;1175+ else if (slot_avail1 & SLOT_33MHZ)1176 bus_speed = PCI_33MHZ;1177 else bus_speed = PCI_SPEED_UNKNOWN;1178 }···1321 .check_cmd_status = hpc_check_cmd_status,1322};13231324+inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,1325+ u32 *value)1326+{1327+ int rc;1328+ u32 cap_offset = ctrl->cap_offset;1329+ struct pci_dev *pdev = ctrl->pci_dev;1330+1331+ rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index);1332+ if (rc)1333+ return rc;1334+ return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value);1335+}1336+1337int shpc_init(struct controller * ctrl, struct pci_dev * pdev)1338{1339 struct php_ctlr_state_s *php_ctlr, *p;1340 void *instance_id = ctrl;1341+ int rc, num_slots = 0;1342 u8 hp_slot;1343 static int first = 1;1344+ u32 shpc_base_offset;1345 u32 tempdword, slot_reg;1346 u8 i;13471348 DBG_ENTER_ROUTINE1349+1350+ ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */13511352 spin_lock_init(&list_lock);1353 php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);···13481349 if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==1350 PCI_DEVICE_ID_AMD_GOLAM_7450)) {1351+ /* amd shpc driver doesn't use Base Offset; assume 0 */1352+ ctrl->mmio_base = pci_resource_start(pdev, 0);1353+ ctrl->mmio_size = pci_resource_len(pdev, 0);1354 } else {1355+ ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);1356+ if (!ctrl->cap_offset) {1357+ err("%s : cap_offset == 0\n", __FUNCTION__);1358 goto abort_free_ctlr;1359 }1360+ dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);1361+1362+ rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset);1363 if (rc) {1364+ err("%s: cannot read base_offset\n", __FUNCTION__);0000001365 goto abort_free_ctlr;1366 }13671368+ rc = shpc_indirect_creg_read(ctrl, 3, &tempdword);1369+ if (rc) {1370+ err("%s: cannot read slot config\n", __FUNCTION__);1371+ goto abort_free_ctlr;1372+ }1373+ num_slots = tempdword & SLOT_NUM;1374+ dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);1375+1376+ for (i = 0; i < 9 + num_slots; i++) {1377+ rc = shpc_indirect_creg_read(ctrl, i, &tempdword);1378 if (rc) {1379+ err("%s: cannot read creg (index = %d)\n",1380+ __FUNCTION__, i);000001381 goto abort_free_ctlr;1382 }1383 dbg("%s: offset %d: value %x\n", __FUNCTION__,i,1384 tempdword);1385 }1386+1387+ ctrl->mmio_base =1388+ pci_resource_start(pdev, 0) + shpc_base_offset;1389+ ctrl->mmio_size = 0x24 + 0x4 * num_slots;1390 }13911392 if (first) {···1396 if (pci_enable_device(pdev))1397 goto abort_free_ctlr;13981399+ if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {1400 err("%s: cannot reserve MMIO region\n", __FUNCTION__);1401 goto abort_free_ctlr;1402 }14031404+ php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);1405 if (!php_ctlr->creg) {1406+ err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,1407+ ctrl->mmio_size, ctrl->mmio_base);1408+ release_mem_region(ctrl->mmio_base, ctrl->mmio_size);1409 goto abort_free_ctlr;1410 }1411 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+14-5
drivers/pci/hotplug/shpchp_pci.c
···89 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;90 int num, fn;9192- dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));93 if (dev) {94 err("Device %s already exists at %x:%x, cannot hot-add\n",95 pci_name(dev), p_slot->bus, p_slot->device);096 return -EINVAL;97 }98···104 }105106 for (fn = 0; fn < 8; fn++) {107- if (!(dev = pci_find_slot(p_slot->bus,108- PCI_DEVFN(p_slot->device, fn))))109 continue;110 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {111 err("Cannot hot-add display device %s\n",112 pci_name(dev));0113 continue;114 }115 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||···126 }127 if (busnr >= end) {128 err("No free bus for hot-added bridge\n");0129 continue;130 }131 child = pci_add_new_bus(parent, dev, busnr);132 if (!child) {133 err("Cannot add new bus for %s\n",134 pci_name(dev));0135 continue;136 }137 child->subordinate = pci_do_scan_bus(child);138 pci_bus_size_bridges(child);139 }140 program_fw_provided_values(dev);0141 }142143 pci_bus_assign_resources(parent);···154 int rc = 0;155 int j;156 u8 bctl = 0;157-0158 dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);159160 for (j=0; j<8 ; j++) {161- struct pci_dev* temp = pci_find_slot(p_slot->bus,162 (p_slot->device << 3) | j);163 if (!temp)164 continue;165 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {166 err("Cannot remove display device %s\n",167 pci_name(temp));0168 continue;169 }170 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {···174 if (bctl & PCI_BRIDGE_CTL_VGA) {175 err("Cannot remove display device %s\n",176 pci_name(temp));0177 continue;178 }179 }180 pci_remove_bus_device(temp);0181 }182 return rc;183}
···89 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;90 int num, fn;9192+ dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));93 if (dev) {94 err("Device %s already exists at %x:%x, cannot hot-add\n",95 pci_name(dev), p_slot->bus, p_slot->device);96+ pci_dev_put(dev);97 return -EINVAL;98 }99···103 }104105 for (fn = 0; fn < 8; fn++) {106+ dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));107+ if (!dev)108 continue;109 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {110 err("Cannot hot-add display device %s\n",111 pci_name(dev));112+ pci_dev_put(dev);113 continue;114 }115 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||···124 }125 if (busnr >= end) {126 err("No free bus for hot-added bridge\n");127+ pci_dev_put(dev);128 continue;129 }130 child = pci_add_new_bus(parent, dev, busnr);131 if (!child) {132 err("Cannot add new bus for %s\n",133 pci_name(dev));134+ pci_dev_put(dev);135 continue;136 }137 child->subordinate = pci_do_scan_bus(child);138 pci_bus_size_bridges(child);139 }140 program_fw_provided_values(dev);141+ pci_dev_put(dev);142 }143144 pci_bus_assign_resources(parent);···149 int rc = 0;150 int j;151 u8 bctl = 0;152+ struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;153+154 dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);155156 for (j=0; j<8 ; j++) {157+ struct pci_dev* temp = pci_get_slot(parent,158 (p_slot->device << 3) | j);159 if (!temp)160 continue;161 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {162 err("Cannot remove display device %s\n",163 pci_name(temp));164+ pci_dev_put(temp);165 continue;166 }167 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {···167 if (bctl & PCI_BRIDGE_CTL_VGA) {168 err("Cannot remove display device %s\n",169 pci_name(temp));170+ pci_dev_put(temp);171 continue;172 }173 }174 pci_remove_bus_device(temp);175+ pci_dev_put(temp);176 }177 return rc;178}
+4-3
drivers/pci/pci.c
···19#include <asm/dma.h> /* isa_dma_bridge_buggy */20#include "pci.h"2102223/**24 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children···63 }64 return max;65}006667static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)68{···590{591 u8 pin;592593- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);594 if (!pin)595 return -1;596 pin--;···920EXPORT_SYMBOL(pci_enable_device_bars);921EXPORT_SYMBOL(pci_enable_device);922EXPORT_SYMBOL(pci_disable_device);923-EXPORT_SYMBOL(pci_max_busnr);924-EXPORT_SYMBOL(pci_bus_max_busnr);925EXPORT_SYMBOL(pci_find_capability);926EXPORT_SYMBOL(pci_bus_find_capability);927EXPORT_SYMBOL(pci_release_regions);
···19#include <asm/dma.h> /* isa_dma_bridge_buggy */20#include "pci.h"2122+#if 02324/**25 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children···62 }63 return max;64}65+66+#endif /* 0 */6768static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)69{···587{588 u8 pin;589590+ pin = dev->pin;591 if (!pin)592 return -1;593 pin--;···917EXPORT_SYMBOL(pci_enable_device_bars);918EXPORT_SYMBOL(pci_enable_device);919EXPORT_SYMBOL(pci_disable_device);00920EXPORT_SYMBOL(pci_find_capability);921EXPORT_SYMBOL(pci_bus_find_capability);922EXPORT_SYMBOL(pci_release_regions);
-5
drivers/pci/pci.h
···26#ifdef CONFIG_PROC_FS27extern int pci_proc_attach_device(struct pci_dev *dev);28extern int pci_proc_detach_device(struct pci_dev *dev);29-extern int pci_proc_attach_bus(struct pci_bus *bus);30extern int pci_proc_detach_bus(struct pci_bus *bus);31#else32static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }33static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; }34-static inline int pci_proc_attach_bus(struct pci_bus *bus) { return 0; }35static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }36#endif3738/* Functions for PCI Hotplug drivers to use */39extern unsigned int pci_do_scan_bus(struct pci_bus *bus);40-extern int pci_remove_device_safe(struct pci_dev *dev);41-extern unsigned char pci_max_busnr(void);42-extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);43extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);4445extern void pci_remove_legacy_files(struct pci_bus *bus);
···26#ifdef CONFIG_PROC_FS27extern int pci_proc_attach_device(struct pci_dev *dev);28extern int pci_proc_detach_device(struct pci_dev *dev);029extern int pci_proc_detach_bus(struct pci_bus *bus);30#else31static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }32static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; }033static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }34#endif3536/* Functions for PCI Hotplug drivers to use */37extern unsigned int pci_do_scan_bus(struct pci_bus *bus);00038extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);3940extern void pci_remove_legacy_files(struct pci_bus *bus);
···48 * in question is not being used by a driver.49 * Returns 0 on success.50 */051int pci_remove_device_safe(struct pci_dev *dev)52{53 if (pci_dev_driver(dev))···56 pci_destroy_dev(dev);57 return 0;58}59-EXPORT_SYMBOL(pci_remove_device_safe);6061void pci_remove_bus(struct pci_bus *pci_bus)62{
···48 * in question is not being used by a driver.49 * Returns 0 on success.50 */51+#if 052int pci_remove_device_safe(struct pci_dev *dev)53{54 if (pci_dev_driver(dev))···55 pci_destroy_dev(dev);56 return 0;57}58+#endif /* 0 */5960void pci_remove_bus(struct pci_bus *pci_bus)61{
···78#define PCI_UNKNOWN ((pci_power_t __force) 5)79#define PCI_POWER_ERROR ((pci_power_t __force) -1)800000000000000000081/*82 * The pci_dev structure is used to describe PCI devices.83 */···115 unsigned int class; /* 3 bytes: (base,sub,prog-if) */116 u8 hdr_type; /* PCI header type (`multi' flag masked out) */117 u8 rom_base_reg; /* which config register controls the ROM */0118119 struct pci_driver *driver; /* which driver has allocated this device */120 u64 dma_mask; /* Mask of the bits of bus address this···128 this is D0-D3, D0 being fully functional,129 and D3 being off. */1300131 struct device dev; /* Generic device interface */132133 /* device is compatible with these IDs */···251 unsigned int use_driver_data:1; /* pci_driver->driver_data is used */252};253000000000000000000000000000000000000000000000000254struct module;255struct pci_driver {256 struct list_head node;···311 int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */312 void (*shutdown) (struct pci_dev *dev);3130314 struct device_driver driver;315 struct pci_dynids dynids;316};···516517void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),518 void *userdata);0519520/* kmem_cache style wrapper around pci_alloc_consistent() */521
···78#define PCI_UNKNOWN ((pci_power_t __force) 5)79#define PCI_POWER_ERROR ((pci_power_t __force) -1)8081+/** The pci_channel state describes connectivity between the CPU and82+ * the pci device. If some PCI bus between here and the pci device83+ * has crashed or locked up, this info is reflected here.84+ */85+typedef unsigned int __bitwise pci_channel_state_t;86+87+enum pci_channel_state {88+ /* I/O channel is in normal state */89+ pci_channel_io_normal = (__force pci_channel_state_t) 1,90+91+ /* I/O to channel is blocked */92+ pci_channel_io_frozen = (__force pci_channel_state_t) 2,93+94+ /* PCI card is dead */95+ pci_channel_io_perm_failure = (__force pci_channel_state_t) 3,96+};97+98/*99 * The pci_dev structure is used to describe PCI devices.100 */···98 unsigned int class; /* 3 bytes: (base,sub,prog-if) */99 u8 hdr_type; /* PCI header type (`multi' flag masked out) */100 u8 rom_base_reg; /* which config register controls the ROM */101+ u8 pin; /* which interrupt pin this device uses */102103 struct pci_driver *driver; /* which driver has allocated this device */104 u64 dma_mask; /* Mask of the bits of bus address this···110 this is D0-D3, D0 being fully functional,111 and D3 being off. */112113+ pci_channel_state_t error_state; /* current connectivity state */114 struct device dev; /* Generic device interface */115116 /* device is compatible with these IDs */···232 unsigned int use_driver_data:1; /* pci_driver->driver_data is used */233};234235+/* ---------------------------------------------------------------- */236+/** PCI Error Recovery System (PCI-ERS). If a PCI device driver provides237+ * a set fof callbacks in struct pci_error_handlers, then that device driver238+ * will be notified of PCI bus errors, and will be driven to recovery239+ * when an error occurs.240+ */241+242+typedef unsigned int __bitwise pci_ers_result_t;243+244+enum pci_ers_result {245+ /* no result/none/not supported in device driver */246+ PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1,247+248+ /* Device driver can recover without slot reset */249+ PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2,250+251+ /* Device driver wants slot to be reset. */252+ PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3,253+254+ /* Device has completely failed, is unrecoverable */255+ PCI_ERS_RESULT_DISCONNECT = (__force pci_ers_result_t) 4,256+257+ /* Device driver is fully recovered and operational */258+ PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5,259+};260+261+/* PCI bus error event callbacks */262+struct pci_error_handlers263+{264+ /* PCI bus error detected on this device */265+ pci_ers_result_t (*error_detected)(struct pci_dev *dev,266+ enum pci_channel_state error);267+268+ /* MMIO has been re-enabled, but not DMA */269+ pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev);270+271+ /* PCI Express link has been reset */272+ pci_ers_result_t (*link_reset)(struct pci_dev *dev);273+274+ /* PCI slot has been reset */275+ pci_ers_result_t (*slot_reset)(struct pci_dev *dev);276+277+ /* Device driver may resume normal operations */278+ void (*resume)(struct pci_dev *dev);279+};280+281+/* ---------------------------------------------------------------- */282+283struct module;284struct pci_driver {285 struct list_head node;···244 int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */245 void (*shutdown) (struct pci_dev *dev);246247+ struct pci_error_handlers *err_handler;248 struct device_driver driver;249 struct pci_dynids dynids;250};···448449void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),450 void *userdata);451+int pci_cfg_space_size(struct pci_dev *dev);452453/* kmem_cache style wrapper around pci_alloc_consistent() */454
+1-1
sound/oss/ad1889.c
···10891090static int __init ad1889_init_module(void)1091{1092- return pci_module_init(&ad1889_driver);1093}10941095static void ad1889_exit_module(void)
···10891090static int __init ad1889_init_module(void)1091{1092+ return pci_register_driver(&ad1889_driver);1093}10941095static void ad1889_exit_module(void)
+1-1
sound/oss/btaudio.c
···1101 digital ? "digital" : "",1102 analog && digital ? "+" : "",1103 analog ? "analog" : "");1104- return pci_module_init(&btaudio_pci_driver);1105}11061107static void btaudio_cleanup_module(void)
···1101 digital ? "digital" : "",1102 analog && digital ? "+" : "",1103 analog ? "analog" : "");1104+ return pci_register_driver(&btaudio_pci_driver);1105}11061107static void btaudio_cleanup_module(void)
+1-1
sound/oss/cmpci.c
···3366static int __init init_cmpci(void)3367{3368 printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n");3369- return pci_module_init(&cm_driver);3370}33713372static void __exit cleanup_cmpci(void)
···3366static int __init init_cmpci(void)3367{3368 printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n");3369+ return pci_register_driver(&cm_driver);3370}33713372static void __exit cleanup_cmpci(void)
···2045static int __init init_vrc5477_ac97(void)2046{2047 printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");2048- return pci_module_init(&vrc5477_ac97_driver);2049}20502051static void __exit cleanup_vrc5477_ac97(void)
···2045static int __init init_vrc5477_ac97(void)2046{2047 printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");2048+ return pci_register_driver(&vrc5477_ac97_driver);2049}20502051static void __exit cleanup_vrc5477_ac97(void)
+1-1
sound/oss/nm256_audio.c
···1644static int __init do_init_nm256(void)1645{1646 printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n");1647- return pci_module_init(&nm256_pci_driver);1648}16491650static void __exit cleanup_nm256 (void)
···1644static int __init do_init_nm256(void)1645{1646 printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n");1647+ return pci_register_driver(&nm256_pci_driver);1648}16491650static void __exit cleanup_nm256 (void)