Commit 3d620cd7 authored by Tony Luck's avatar Tony Luck
parents a1ecf7f6 30121624
...@@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061 ...@@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061
S: USA S: USA
N: Randy Dunlap N: Randy Dunlap
E: rddunlap@osdl.org E: rdunlap@xenotime.net
W: http://www.xenotime.net/linux/linux.html W: http://www.xenotime.net/linux/linux.html
W: http://www.linux-usb.org W: http://www.linux-usb.org
D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
D: x86 SMP, ACPI, bootflag hacking D: x86 SMP, ACPI, bootflag hacking
S: 12725 SW Millikan Way, Suite 400 S: (ask for current address)
S: Beaverton, Oregon 97005
S: USA S: USA
N: Bob Dunlop N: Bob Dunlop
......
...@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci ...@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci
#define MAX_PCIEROOT 6 #define MAX_PCIEROOT 6
static int quirk_aspm_offset[MAX_PCIEROOT << 3]; static int quirk_aspm_offset[MAX_PCIEROOT << 3];
#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b) #define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7))
static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{ {
......
...@@ -753,6 +753,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -753,6 +753,8 @@ void __init setup_arch(char **cmdline_p)
strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line; *cmdline_p = cmd_line;
parse_early_param();
/* set up the bootmem stuff with available memory */ /* set up the bootmem stuff with available memory */
do_init_bootmem(); do_init_bootmem();
if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
......
...@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp, ...@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
{ {
struct block_device *bdev = filp->private_data; struct block_device *bdev = filp->private_data;
return blkdev_ioctl(bdev->bd_inode, filp, command, arg); return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
} }
static void bind_device(struct raw_config_request *rq) static void bind_device(struct raw_config_request *rq)
......
...@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, ...@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
if ((buffer_size - length <= 0) || (i >= num_envp)) if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM; return -ENOMEM;
envp[i++] = scratch;
length += scnprintf (scratch, buffer_size - length,
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device,
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
(u8)(pdev->class));
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
envp[i] = NULL; envp[i] = NULL;
return 0; return 0;
} }
static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
{
struct list_head *ln;
struct pci_dev *dev;
struct pci_dev_wrapped wrapped_dev;
int result = 0;
pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus),
wrapped_bus->bus->number);
if (fn->pre_visit_pci_bus) {
result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
if (result)
return result;
}
ln = wrapped_bus->bus->devices.next;
while (ln != &wrapped_bus->bus->devices) {
dev = pci_dev_b(ln);
ln = ln->next;
memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
wrapped_dev.dev = dev;
result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
if (result)
return result;
}
if (fn->post_visit_pci_bus)
result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
return result;
}
static int pci_visit_bridge (struct pci_visit * fn,
struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent)
{
struct pci_bus *bus;
struct pci_bus_wrapped wrapped_bus;
int result = 0;
pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev));
if (fn->visit_pci_dev) {
result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
if (result)
return result;
}
bus = wrapped_dev->dev->subordinate;
if (bus) {
memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
wrapped_bus.bus = bus;
result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
}
return result;
}
/**
* pci_visit_dev - scans the pci buses.
* @fn: callback functions that are called while visiting
* @wrapped_dev: the device to scan
* @wrapped_parent: the bus where @wrapped_dev is connected to
*
* Every bus and every function is presented to a custom
* function that can act upon it.
*/
int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent)
{
struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
int result = 0;
if (!dev)
return 0;
if (fn->pre_visit_pci_dev) {
result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
if (result)
return result;
}
switch (dev->class >> 8) {
case PCI_CLASS_BRIDGE_PCI:
result = pci_visit_bridge(fn, wrapped_dev,
wrapped_parent);
if (result)
return result;
break;
default:
pr_debug("PCI: Scanning device %s\n", pci_name(dev));
if (fn->visit_pci_dev) {
result = fn->visit_pci_dev (wrapped_dev,
wrapped_parent);
if (result)
return result;
}
}
if (fn->post_visit_pci_dev)
result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
return result;
}
EXPORT_SYMBOL(pci_visit_dev);
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.h> #include <linux/pci.h>
/* PICMG 2.12 R2.0 HS CSR bits: */ /* PICMG 2.1 R2.0 HS CSR bits: */
#define HS_CSR_INS 0x0080 #define HS_CSR_INS 0x0080
#define HS_CSR_EXT 0x0040 #define HS_CSR_EXT 0x0040
#define HS_CSR_PI 0x0030 #define HS_CSR_PI 0x0030
......
...@@ -33,11 +33,11 @@ ...@@ -33,11 +33,11 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <asm/atomic.h>
#include <linux/delay.h> #include <linux/delay.h>
#include "pci_hotplug.h" #include "pci_hotplug.h"
#include "cpci_hotplug.h" #include "cpci_hotplug.h"
#define DRIVER_VERSION "0.2"
#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
#define DRIVER_DESC "CompactPCI Hot Plug Core" #define DRIVER_DESC "CompactPCI Hot Plug Core"
...@@ -54,9 +54,10 @@ ...@@ -54,9 +54,10 @@
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
/* local variables */ /* local variables */
static spinlock_t list_lock; static DECLARE_RWSEM(list_rwsem);
static LIST_HEAD(slot_list); static LIST_HEAD(slot_list);
static int slots; static int slots;
static atomic_t extracting;
int cpci_debug; int cpci_debug;
static struct cpci_hp_controller *controller; static struct cpci_hp_controller *controller;
static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
...@@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot); ...@@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot);
static int set_attention_status(struct hotplug_slot *slot, u8 value); static int set_attention_status(struct hotplug_slot *slot, u8 value);
static int get_power_status(struct hotplug_slot *slot, u8 * value); static int get_power_status(struct hotplug_slot *slot, u8 * value);
static int get_attention_status(struct hotplug_slot *slot, u8 * value); static int get_attention_status(struct hotplug_slot *slot, u8 * value);
static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
static int get_latch_status(struct hotplug_slot *slot, u8 * value);
static struct hotplug_slot_ops cpci_hotplug_slot_ops = { static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = { ...@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
.set_attention_status = set_attention_status, .set_attention_status = set_attention_status,
.get_power_status = get_power_status, .get_power_status = get_power_status,
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_adapter_status = get_adapter_status,
.get_latch_status = get_latch_status,
}; };
static int static int
...@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot) ...@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot)
warn("failure to update adapter file"); warn("failure to update adapter file");
} }
slot->extracting = 0; if(slot->extracting) {
slot->extracting = 0;
atomic_dec(&extracting);
}
return retval; return retval;
} }
...@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) ...@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
return cpci_set_attention_status(hotplug_slot->private, status); return cpci_set_attention_status(hotplug_slot->private, status);
} }
static int
get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
{
*value = hotplug_slot->info->adapter_status;
return 0;
}
static int
get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
{
*value = hotplug_slot->info->latch_status;
return 0;
}
static void release_slot(struct hotplug_slot *hotplug_slot) static void release_slot(struct hotplug_slot *hotplug_slot)
{ {
struct slot *slot = hotplug_slot->private; struct slot *slot = hotplug_slot->private;
...@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) ...@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
} }
/* Add slot to our internal list */ /* Add slot to our internal list */
spin_lock(&list_lock); down_write(&list_rwsem);
list_add(&slot->slot_list, &slot_list); list_add(&slot->slot_list, &slot_list);
slots++; slots++;
spin_unlock(&list_lock); up_write(&list_rwsem);
} }
return 0; return 0;
error_name: error_name:
...@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus) ...@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
struct list_head *next; struct list_head *next;
int status; int status;
spin_lock(&list_lock); down_write(&list_rwsem);
if(!slots) { if(!slots) {
spin_unlock(&list_lock); up_write(&list_rwsem);
return -1; return -1;
} }
list_for_each_safe(tmp, next, &slot_list) { list_for_each_safe(tmp, next, &slot_list) {
...@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus) ...@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
slots--; slots--;
} }
} }
spin_unlock(&list_lock); up_write(&list_rwsem);
return 0; return 0;
} }
...@@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) ...@@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
} }
/* /*
* According to PICMG 2.12 R2.0, section 6.3.2, upon * According to PICMG 2.1 R2.0, section 6.3.2, upon
* initialization, the system driver shall clear the * initialization, the system driver shall clear the
* INS bits of the cold-inserted devices. * INS bits of the cold-inserted devices.
*/ */
...@@ -359,9 +380,9 @@ init_slots(void) ...@@ -359,9 +380,9 @@ init_slots(void)
struct pci_dev* dev; struct pci_dev* dev;
dbg("%s - enter", __FUNCTION__); dbg("%s - enter", __FUNCTION__);
spin_lock(&list_lock); down_read(&list_rwsem);
if(!slots) { if(!slots) {
spin_unlock(&list_lock); up_read(&list_rwsem);
return -1; return -1;
} }
list_for_each(tmp, &slot_list) { list_for_each(tmp, &slot_list) {
...@@ -386,7 +407,7 @@ init_slots(void) ...@@ -386,7 +407,7 @@ init_slots(void)
} }
} }
} }
spin_unlock(&list_lock); up_read(&list_rwsem);
dbg("%s - exit", __FUNCTION__); dbg("%s - exit", __FUNCTION__);
return 0; return 0;
} }
...@@ -398,10 +419,11 @@ check_slots(void) ...@@ -398,10 +419,11 @@ check_slots(void)
struct list_head *tmp; struct list_head *tmp;
int extracted; int extracted;
int inserted; int inserted;
u16 hs_csr;
spin_lock(&list_lock); down_read(&list_rwsem);
if(!slots) { if(!slots) {
spin_unlock(&list_lock); up_read(&list_rwsem);
err("no slots registered, shutting down"); err("no slots registered, shutting down");
return -1; return -1;
} }
...@@ -411,8 +433,6 @@ check_slots(void) ...@@ -411,8 +433,6 @@ check_slots(void)
dbg("%s - looking at slot %s", dbg("%s - looking at slot %s",
__FUNCTION__, slot->hotplug_slot->name); __FUNCTION__, slot->hotplug_slot->name);
if(cpci_check_and_clear_ins(slot)) { if(cpci_check_and_clear_ins(slot)) {
u16 hs_csr;
/* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
if(slot->dev) { if(slot->dev) {
warn("slot %s already inserted", slot->hotplug_slot->name); warn("slot %s already inserted", slot->hotplug_slot->name);
...@@ -462,8 +482,6 @@ check_slots(void) ...@@ -462,8 +482,6 @@ check_slots(void)
inserted++; inserted++;
} else if(cpci_check_ext(slot)) { } else if(cpci_check_ext(slot)) {
u16 hs_csr;
/* Process extraction request */ /* Process extraction request */
dbg("%s - slot %s extracted", dbg("%s - slot %s extracted",
__FUNCTION__, slot->hotplug_slot->name); __FUNCTION__, slot->hotplug_slot->name);
...@@ -476,20 +494,40 @@ check_slots(void) ...@@ -476,20 +494,40 @@ check_slots(void)
if(!slot->extracting) { if(!slot->extracting) {
if(update_latch_status(slot->hotplug_slot, 0)) { if(update_latch_status(slot->hotplug_slot, 0)) {
warn("failure to update latch file"); warn("failure to update latch file");
} }
atomic_inc(&extracting);
slot->extracting = 1; slot->extracting = 1;
} }
extracted++; extracted++;
} else if(slot->extracting) {
hs_csr = cpci_get_hs_csr(slot);
if(hs_csr == 0xffff) {
/*
* Hmmm, we're likely hosed at this point, should we
* bother trying to tell the driver or not?
*/
err("card in slot %s was improperly removed",
slot->hotplug_slot->name);
if(update_adapter_status(slot->hotplug_slot, 0)) {
warn("failure to update adapter file");
}
slot->extracting = 0;
atomic_dec(&extracting);
}
} }
} }
spin_unlock(&list_lock); up_read(&list_rwsem);
dbg("inserted=%d, extracted=%d, extracting=%d",
inserted, extracted, atomic_read(&extracting));
if(inserted || extracted) { if(inserted || extracted) {
return extracted; return extracted;
} }
else { else if(!atomic_read(&extracting)) {
err("cannot find ENUM# source, shutting down"); err("cannot find ENUM# source, shutting down");
return -1; return -1;
} }
return 0;
} }
/* This is the interrupt mode worker thread body */ /* This is the interrupt mode worker thread body */
...@@ -497,8 +535,6 @@ static int ...@@ -497,8 +535,6 @@ static int
event_thread(void *data) event_thread(void *data)
{ {
int rc; int rc;
struct slot *slot;
struct list_head *tmp;
lock_kernel(); lock_kernel();
daemonize("cpci_hp_eventd"); daemonize("cpci_hp_eventd");
...@@ -512,39 +548,22 @@ event_thread(void *data) ...@@ -512,39 +548,22 @@ event_thread(void *data)
thread_finished); thread_finished);
if(thread_finished || signal_pending(current)) if(thread_finished || signal_pending(current))
break; break;
while(controller->ops->query_enum()) { do {
rc = check_slots(); rc = check_slots();
if (rc > 0) if (rc > 0) {
/* Give userspace a chance to handle extraction */ /* Give userspace a chance to handle extraction */
msleep(500); msleep(500);
else if (rc < 0) { } else if (rc < 0) {
dbg("%s - error checking slots", __FUNCTION__); dbg("%s - error checking slots", __FUNCTION__);
thread_finished = 1; thread_finished = 1;
break; break;
} }
} } while(atomic_read(&extracting) != 0);
/* Check for someone yanking out a board */
list_for_each(tmp, &slot_list) {
slot = list_entry(tmp, struct slot, slot_list);
if(slot->extracting) {
/*
* Hmmm, we're likely hosed at this point, should we
* bother trying to tell the driver or not?
*/
err("card in slot %s was improperly removed",
slot->hotplug_slot->name);
if(update_adapter_status(slot->hotplug_slot, 0)) {
warn("failure to update adapter file");
}
slot->extracting = 0;
}
}
/* Re-enable ENUM# interrupt */ /* Re-enable ENUM# interrupt */
dbg("%s - re-enabling irq", __FUNCTION__); dbg("%s - re-enabling irq", __FUNCTION__);
controller->ops->enable_irq(); controller->ops->enable_irq();
} }
dbg("%s - event thread signals exit", __FUNCTION__); dbg("%s - event thread signals exit", __FUNCTION__);
up(&thread_exit); up(&thread_exit);
return 0; return 0;
...@@ -555,8 +574,6 @@ static int ...@@ -555,8 +574,6 @@ static int
poll_thread(void *data) poll_thread(void *data)
{ {
int rc; int rc;
struct slot *slot;
struct list_head *tmp;
lock_kernel(); lock_kernel();
daemonize("cpci_hp_polld"); daemonize("cpci_hp_polld");
...@@ -565,35 +582,19 @@ poll_thread(void *data) ...@@ -565,35 +582,19 @@ poll_thread(void *data)
while(1) { while(1) {
if(thread_finished || signal_pending(current)) if(thread_finished || signal_pending(current))
break; break;
if(controller->ops->query_enum()) {
while(controller->ops->query_enum()) { do {
rc = check_slots(); rc = check_slots();
if(rc > 0) if(rc > 0) {
/* Give userspace a chance to handle extraction */ /* Give userspace a chance to handle extraction */
msleep(500); msleep(500);
else if (rc < 0) { } else if(rc < 0) {
dbg("%s - error checking slots", __FUNCTION__); dbg("%s - error checking slots", __FUNCTION__);
thread_finished = 1; thread_finished = 1;
break; break;
}
}
/* Check for someone yanking out a board */
list_for_each(tmp, &slot_list) {
slot = list_entry(tmp, struct slot, slot_list);
if(slot->extracting) {
/*
* Hmmm, we're likely hosed at this point, should we
* bother trying to tell the driver or not?
*/
err("card in slot %s was improperly removed",
slot->hotplug_slot->name);
if(update_adapter_status(slot->hotplug_slot, 0)) {
warn("failure to update adapter file");
} }
slot->extracting = 0; } while(atomic_read(&extracting) != 0);
}
} }
msleep(100); msleep(100);
} }
dbg("poll thread signals exit"); dbg("poll thread signals exit");
...@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) ...@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
int status = 0; int status = 0;
if(controller) { if(controller) {
if(atomic_read(&extracting) != 0) {
return -EBUSY;
}
if(!thread_finished) { if(!thread_finished) {
cpci_stop_thread(); cpci_stop_thread();
} }
...@@ -691,12 +695,12 @@ cpci_hp_start(void) ...@@ -691,12 +695,12 @@ cpci_hp_start(void)
return -ENODEV; return -ENODEV;
} }
spin_lock(&list_lock); down_read(&list_rwsem);
if(!slots) { if(list_empty(&slot_list)) {
spin_unlock(&list_lock); up_read(&list_rwsem);
return -ENODEV; return -ENODEV;
} }
spin_unlock(&list_lock); up_read(&list_rwsem);
if(first) { if(first) {
status = init_slots(); status = init_slots();
...@@ -727,7 +731,9 @@ cpci_hp_stop(void) ...@@ -727,7 +731,9 @@ cpci_hp_stop(void)
if(!controller) { if(!controller) {
return -ENODEV; return -ENODEV;
} }
if(atomic_read(&extracting) != 0) {
return -EBUSY;
}
if(controller->irq) { if(controller->irq) {
/* Stop enum interrupt processing */ /* Stop enum interrupt processing */
dbg("%s - disabling irq", __FUNCTION__); dbg("%s - disabling irq", __FUNCTION__);
...@@ -747,7 +753,7 @@ cleanup_slots(void) ...@@ -747,7 +753,7 @@ cleanup_slots(void)
* Unregister all of our slots with the pci_hotplug subsystem, * Unregister all of our slots with the pci_hotplug subsystem,
* and free up all memory that we had allocated. * and free up all memory that we had allocated.
*/ */
spin_lock(&list_lock); down_write(&list_rwsem);
if(!slots) { if(!slots) {
goto null_cleanup; goto null_cleanup;
} }
...@@ -761,17 +767,14 @@ cleanup_slots(void) ...@@ -761,17 +767,14 @@ cleanup_slots(void)
kfree(slot); kfree(slot);
} }
null_cleanup: null_cleanup:
spin_unlock(&list_lock); up_write(&list_rwsem);
return; return;
} }
int __init int __init
cpci_hotplug_init(int debug) cpci_hotplug_init(int debug)
{ {
spin_lock_init(&list_lock);
cpci_debug = debug; cpci_debug = debug;
info(DRIVER_DESC " version: " DRIVER_VERSION);
return 0; return 0;
} }
......
...@@ -32,11 +32,7 @@ ...@@ -32,11 +32,7 @@
#include "pci_hotplug.h" #include "pci_hotplug.h"
#include "cpci_hotplug.h" #include "cpci_hotplug.h"
#if !defined(MODULE)
#define MY_NAME "cpci_hotplug" #define MY_NAME "cpci_hotplug"
#else
#define MY_NAME THIS_MODULE->name
#endif
extern int cpci_debug; extern int cpci_debug;
...@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot) ...@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot)
return hs_csr; return hs_csr;
} }
#if 0
u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
{
int hs_cap;
u16 new_hs_csr;
hs_cap = pci_bus_find_capability(slot->bus,
slot->devfn,
PCI_CAP_ID_CHSWP);
if(!hs_cap) {
return 0xFFFF;
}
/* Write out the new value */
if(pci_bus_write_config_word(slot->bus,
slot->devfn,
hs_cap + 2,
hs_csr)) {
return 0xFFFF;
}
/* Read back what we just wrote out */
if(pci_bus_read_config_word(slot->bus,
slot->devfn,
hs_cap + 2,
&new_hs_csr)) {
return 0xFFFF;
}
return new_hs_csr;
}
#endif
int cpci_check_and_clear_ins(struct slot* slot) int cpci_check_and_clear_ins(struct slot* slot)
{ {
int hs_cap; int hs_cap;
...@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot) ...@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot)
return -ENODEV; return -ENODEV;
} }
if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
/* Set LOO */
hs_csr |= HS_CSR_LOO; hs_csr |= HS_CSR_LOO;
if(pci_bus_write_config_word(slot->bus, if(pci_bus_write_config_word(slot->bus,
slot->devfn, slot->devfn,
...@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot) ...@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot)
return -ENODEV; return -ENODEV;
} }
if(hs_csr & HS_CSR_LOO) { if(hs_csr & HS_CSR_LOO) {
/* Clear LOO */
hs_csr &= ~HS_CSR_LOO; hs_csr &= ~HS_CSR_LOO;
if(pci_bus_write_config_word(slot->bus, if(pci_bus_write_config_word(slot->bus,
slot->devfn, slot->devfn,
...@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot) ...@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot)
* Device configuration functions * Device configuration functions
*/ */
static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev) static void cpci_enable_device(struct pci_dev *dev)
{
u8 irq_pin;
int r;
dbg("%s - enter", __FUNCTION__);
/* NOTE: device already setup from prior scan */
/* FIXME: How would we know if we need to enable the expansion ROM? */
pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
/* Assign resources */
dbg("assigning resources for %02x:%02x.%x",
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
for (r = 0; r < 6; r++) {
struct resource *res = dev->resource + r;
if(res->flags)
pci_assign_resource(dev, r);
}
dbg("finished assigning resources for %02x:%02x.%x",
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
/* Does this function have an interrupt at all? */
dbg("checking for function interrupt");
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
if(irq_pin) {
dbg("function uses interrupt pin %d", irq_pin);
}
/*
* Need to explicitly set irq field to 0 so that it'll get assigned
* by the pcibios platform dependent code called by pci_enable_device.
*/
dev->irq = 0;
dbg("enabling device");
pci_enable_device(dev); /* XXX check return */
dbg("now dev->irq = %d", dev->irq);
if(irq_pin && dev->irq) {
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
/* Can't use pci_insert_device at the moment, do it manually for now */
pci_proc_attach_device(dev);
dbg("notifying drivers");
//pci_announce_device_to_drivers(dev);
dbg("%s - exit", __FUNCTION__);
return 0;
}
static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
{ {
int rc; struct pci_bus *bus;
struct pci_bus* child;
struct resource* r;
u8 max, n;
u16 command;
dbg("%s - enter", __FUNCTION__);
/* Do basic bridge initialization */ pci_enable_device(dev);
rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
if(rc) {
printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
}
rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
if(rc) {
printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
}
rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
if(rc) {
printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
}
/*
* Set parent bridge's subordinate field so that configuration space
* access will work in pci_scan_bridge and friends.
*/
max = pci_max_busnr();
bus->subordinate = max + 1;
pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
/* Scan behind bridge */
n = pci_scan_bridge(bus, dev, max, 2);
child = pci_find_bus(0, max + 1);
if (!child)
return -ENODEV;
pci_proc_attach_bus(child);
/*
* Update parent bridge's subordinate field if there were more bridges
* behind the bridge that was scanned.
*/
if(n > max) {
bus->subordinate = n;
pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
}
/*
* Update the bridge resources of the bridge to accommodate devices
* behind it.
*/
pci_bus_size_bridges(child);
pci_bus_assign_resources(child);
/* Enable resource mapping via command register */
command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
r = child->resource[0];
if(r && r->start) {
command |= PCI_COMMAND_IO;
}
r = child->resource[1];
if(r && r->start) {
command |= PCI_COMMAND_MEMORY;
}
r = child->resource[2];
if(r && r->start) {
command |= PCI_COMMAND_MEMORY;
}
rc = pci_write_config_word(dev, PCI_COMMAND, command);
if(rc) {
err("Error setting command register");
return rc;
}
/* Set bridge control register */
command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
if(rc) {
err("Error setting bridge control register");
return rc;
}
dbg("%s - exit", __FUNCTION__);
return 0;
}
static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_bus)
{
int rc;
struct pci_dev *dev = wrapped_dev->dev;
struct pci_bus *bus = wrapped_bus->bus;
struct slot* slot;
dbg("%s - enter", __FUNCTION__);
/*
* We need to fix up the hotplug representation with the Linux
* representation.
*/
if(wrapped_dev->data) {
slot = (struct slot*) wrapped_dev->data;
slot->dev = dev;
}
/* If it's a bridge, scan behind it for devices */
if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
rc = cpci_configure_bridge(bus, dev); bus = dev->subordinate;
if(rc) list_for_each_entry(dev, &bus->devices, bus_list) {
return rc; cpci_enable_device(dev);
}
/* Actually configure device */
if(dev) {
rc = cpci_configure_dev(bus, dev);
if(rc)
return rc;
}
dbg("%s - exit", __FUNCTION__);
return 0;
}
static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_bus)
{
struct pci_dev *dev = wrapped_dev->dev;
struct slot* slot;
dbg("%s - enter", __FUNCTION__);
if(!dev)
return -ENODEV;
/* Remove the Linux representation */
if(pci_remove_device_safe(dev)) {
err("Could not remove device\n");
return -1;
}
/*
* Now remove the hotplug representation.
*/
if(wrapped_dev->data) {
slot = (struct slot*) wrapped_dev->data;
slot->dev = NULL;
} else {
dbg("No hotplug representation for %02x:%02x.%x",
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
}
dbg("%s - exit", __FUNCTION__);
return 0;
}
static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
struct pci_dev_wrapped *wrapped_dev)
{
struct pci_bus *bus = wrapped_bus->bus;
struct pci_bus *parent = bus->self->bus;
dbg("%s - enter", __FUNCTION__);
/* The cleanup code for proc entries regarding buses should be in the kernel... */
if(bus->procdir)
dbg("detach_pci_bus %s", bus->procdir->name);
pci_proc_detach_bus(bus);
/* The cleanup code should live in the kernel... */
bus->self->subordinate = NULL;
/* unlink from parent bus */
list_del(&bus->node);
/* Now, remove */
if(bus)
kfree(bus);
/* Update parent's subordinate field */
if(parent) {
u8 n = pci_bus_max_busnr(parent);
if(n < parent->subordinate) {
parent->subordinate = n;
pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
} }
} }
dbg("%s - exit", __FUNCTION__);
return 0;
} }
static struct pci_visit configure_functions = {
.visit_pci_dev = configure_visit_pci_dev,
};
static struct pci_visit unconfigure_functions_phase2 = {
.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
};
int cpci_configure_slot(struct slot* slot) int cpci_configure_slot(struct slot* slot)
{ {
int rc = 0; unsigned char busnr;
struct pci_bus *child;
dbg("%s - enter", __FUNCTION__); dbg("%s - enter", __FUNCTION__);
...@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot) ...@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot)
slot->dev = pci_find_slot(slot->bus->number, slot->devfn); slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
if(slot->dev == NULL) { if(slot->dev == NULL) {
err("Could not find PCI device for slot %02x", slot->number); err("Could not find PCI device for slot %02x", slot->number);
return 0; return 1;
} }
} }
dbg("slot->dev = %p", slot->dev);
if(slot->dev) { if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
struct pci_dev *dev; pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr);
struct pci_dev_wrapped wrapped_dev; child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr);
struct pci_bus_wrapped wrapped_bus; pci_do_scan_bus(child);
int i; pci_bus_size_bridges(child);
memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
for (i = 0; i < 8; i++) {
dev = pci_find_slot(slot->bus->number,
PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
if(!dev)
continue;
wrapped_dev.dev = dev;
wrapped_bus.bus = slot->dev->bus;
if(i)
wrapped_dev.data = NULL;
else
wrapped_dev.data = (void*) slot;
rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
}
} }
dbg("%s - exit, rc = %d", __FUNCTION__, rc); pci_bus_assign_resources(slot->dev->bus);
return rc;
cpci_enable_device(slot->dev);
dbg("%s - exit", __FUNCTION__);
return 0;
} }
int cpci_unconfigure_slot(struct slot* slot) int cpci_unconfigure_slot(struct slot* slot)
{ {
int rc = 0;
int i; int i;
struct pci_dev_wrapped wrapped_dev;
struct pci_bus_wrapped wrapped_bus;
struct pci_dev *dev; struct pci_dev *dev;
dbg("%s - enter", __FUNCTION__); dbg("%s - enter", __FUNCTION__);
if(!slot->dev) { if(!slot->dev) {
err("No device for slot %02x\n", slot->number); err("No device for slot %02x\n", slot->number);
return -ENODEV; return -ENODEV;
} }
memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
dev = pci_find_slot(slot->bus->number, dev = pci_find_slot(slot->bus->number,
PCI_DEVFN(PCI_SLOT(slot->devfn), i)); PCI_DEVFN(PCI_SLOT(slot->devfn), i));
if(dev) { if(dev) {
wrapped_dev.dev = dev; pci_remove_bus_device(dev);
wrapped_bus.bus = dev->bus; slot->dev = NULL;
if(i)
wrapped_dev.data = NULL;
else
wrapped_dev.data = (void*) slot;
dbg("%s - unconfigure phase 2", __FUNCTION__);
rc = pci_visit_dev(&unconfigure_functions_phase2,
&wrapped_dev,
&wrapped_bus);
if(rc)
break;
} }
} }
dbg("%s - exit, rc = %d", __FUNCTION__, rc); dbg("%s - exit", __FUNCTION__);
return rc; return 0;
} }
...@@ -130,6 +130,7 @@ struct controller { ...@@ -130,6 +130,7 @@ struct controller {
u8 slot_bus; /* Bus where the slots handled by this controller sit */ u8 slot_bus; /* Bus where the slots handled by this controller sit */
u8 ctrlcap; u8 ctrlcap;
u16 vendor_id; u16 vendor_id;
u8 cap_base;
}; };
struct irq_mapping { struct irq_mapping {
......
...@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev) ...@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev)
static struct pcie_port_service_id port_pci_ids[] = { { static struct pcie_port_service_id port_pci_ids[] = { {
.vendor = PCI_ANY_ID, .vendor = PCI_ANY_ID,
.device = PCI_ANY_ID, .device = PCI_ANY_ID,
.port_type = PCIE_RC_PORT, .port_type = PCIE_ANY_PORT,
.service_type = PCIE_PORT_SERVICE_HP, .service_type = PCIE_PORT_SERVICE_HP,
.driver_data = 0, .driver_data = 0,
}, { /* end: all zeroes */ } }, { /* end: all zeroes */ }
......
...@@ -109,20 +109,20 @@ enum ctrl_offsets { ...@@ -109,20 +109,20 @@ enum ctrl_offsets {
}; };
static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */
#define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID ) #define PCIE_CAP_ID(cb) ( cb + PCIECAPID )
#define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR ) #define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR )
#define CAP_REG ( pcie_cap_base + CAPREG ) #define CAP_REG(cb) ( cb + CAPREG )
#define DEV_CAP ( pcie_cap_base + DEVCAP ) #define DEV_CAP(cb) ( cb + DEVCAP )
#define DEV_CTRL ( pcie_cap_base + DEVCTRL ) #define DEV_CTRL(cb) ( cb + DEVCTRL )
#define DEV_STATUS ( pcie_cap_base + DEVSTATUS ) #define DEV_STATUS(cb) ( cb + DEVSTATUS )
#define LNK_CAP ( pcie_cap_base + LNKCAP ) #define LNK_CAP(cb) ( cb + LNKCAP )
#define LNK_CTRL ( pcie_cap_base + LNKCTRL ) #define LNK_CTRL(cb) ( cb + LNKCTRL )
#define LNK_STATUS ( pcie_cap_base + LNKSTATUS ) #define LNK_STATUS(cb) ( cb + LNKSTATUS )
#define SLOT_CAP ( pcie_cap_base + SLOTCAP ) #define SLOT_CAP(cb) ( cb + SLOTCAP )
#define SLOT_CTRL ( pcie_cap_base + SLOTCTRL ) #define SLOT_CTRL(cb) ( cb + SLOTCTRL )
#define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS ) #define SLOT_STATUS(cb) ( cb + SLOTSTATUS )
#define ROOT_CTRL ( pcie_cap_base + ROOTCTRL ) #define ROOT_CTRL(cb) ( cb + ROOTCTRL )
#define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS ) #define ROOT_STATUS(cb) ( cb + ROOTSTATUS )
#define hp_register_read_word(pdev, reg , value) \ #define hp_register_read_word(pdev, reg , value) \
pci_read_config_word(pdev, reg, &value) pci_read_config_word(pdev, reg, &value)
...@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return retval; return retval;
...@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
} }
dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE); retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
if (retval) { if (retval) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
...@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl) ...@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
...@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) ...@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl); dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
...@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) ...@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl); dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
pwr_state = (slot_ctrl & PWR_CTRL) >> 10; pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
...@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) ...@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
...@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) ...@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
...@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot) ...@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
...@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) ...@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
err("%s: Invalid HPC slot number!\n", __FUNCTION__); err("%s: Invalid HPC slot number!\n", __FUNCTION__);
return -1; return -1;
} }
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
...@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) ...@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
return rc; return rc;
} }
...@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot) ...@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot)
return ; return ;
} }
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
...@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot) ...@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot)
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
return; return;
} }
...@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot) ...@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot)
return ; return ;
} }
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
...@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot) ...@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot)
if (!pciehp_poll_mode) if (!pciehp_poll_mode)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
return; return;
} }
...@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot) ...@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
return ; return ;
} }
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
...@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot) ...@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
slot_cmd = slot_cmd | HP_INTR_ENABLE; slot_cmd = slot_cmd | HP_INTR_ENABLE;
pcie_write_cmd(slot, slot_cmd); pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
return; return;
} }
...@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl, ...@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl,
*first_device_num = 0; *first_device_num = 0;
*num_ctlr_slots = 1; *num_ctlr_slots = 1;
rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap); rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
if (rc) { if (rc) {
err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
...@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL, dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
slot_ctrl); slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
...@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot)
err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
return -1; return -1;
} }
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
DBG_LEAVE_ROUTINE DBG_LEAVE_ROUTINE
...@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot) ...@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s: Invalid HPC slot number!\n", __FUNCTION__); err("%s: Invalid HPC slot number!\n", __FUNCTION__);
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) { if (retval) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval; return retval;
} }
dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL, dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
slot_ctrl); slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
...@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot) ...@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s: Write command failed!\n", __FUNCTION__); err("%s: Write command failed!\n", __FUNCTION__);
return -1; return -1;
} }
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
DBG_LEAVE_ROUTINE DBG_LEAVE_ROUTINE
...@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE; return IRQ_NONE;
} }
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
/* Mask Hot-plug Interrupt Enable */ /* Mask Hot-plug Interrupt Enable */
if (!pciehp_poll_mode) { if (!pciehp_poll_mode) {
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Clear command complete interrupt caused by this write */ /* Clear command complete interrupt caused by this write */
temp_word = 0x1f; temp_word = 0x1f;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Clear all events after serving them */ /* Clear all events after serving them */
temp_word = 0x1F; temp_word = 0x1F;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
/* Unmask Hot-plug Interrupt Enable */ /* Unmask Hot-plug Interrupt Enable */
if (!pciehp_poll_mode) { if (!pciehp_poll_mode) {
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
} }
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) ...@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Clear command complete interrupt caused by this write */ /* Clear command complete interrupt caused by this write */
temp_word = 0x1F; temp_word = 0x1F;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE; return IRQ_NONE;
...@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) ...@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
return -1; return -1;
} }
retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap); retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
if (retval) { if (retval) {
err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
...@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value ...@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value
return -1; return -1;
} }
retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap); retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
if (retval) { if (retval) {
err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
...@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) ...@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
...@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value ...@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value
return -1; return -1;
} }
retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
if (retval) { if (retval) {
err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
...@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl, ...@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl,
goto abort_free_ctlr; goto abort_free_ctlr;
} }
pcie_cap_base = cap_base; ctrl->cap_base = cap_base;
dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
rc = hp_register_read_word(pdev, CAP_REG, cap_reg); rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg);
if (rc) { if (rc) {
err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg); dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg);
if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){ if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040)
&& ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__); dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap); rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
if (rc) { if (rc) {
err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap); dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap);
if (!(slot_cap & HP_CAP)) { if (!(slot_cap & HP_CAP)) {
dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
/* For debugging purpose */ /* For debugging purpose */
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl); dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
if (first) { if (first) {
spin_lock_init(&hpc_event_lock); spin_lock_init(&hpc_event_lock);
...@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl, ...@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl,
php_ctlr->num_slots = 1; php_ctlr->num_slots = 1;
/* Mask Hot-plug Interrupt Enable */ /* Mask Hot-plug Interrupt Enable */
rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word); rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word); dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
, slot_status);
temp_word = 0x1F; /* Clear all events */ temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
if (pciehp_poll_mode) {/* Install interrupt polling code */ if (pciehp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */ /* Install and start the interrupt polling timer */
...@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl, ...@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl,
} }
} }
rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word); rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap); dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
intr_enable = intr_enable | PRSN_DETECT_ENABLE; intr_enable = intr_enable | PRSN_DETECT_ENABLE;
...@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl, ...@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl,
dbg("%s: temp_word %x\n", __FUNCTION__, temp_word); dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) { if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
SLOT_STATUS, slot_status); SLOT_STATUS(ctrl->cap_base), slot_status);
temp_word = 0x1F; /* Clear all events */ temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
if (rc) { if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr; goto abort_free_ctlr;
} }
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
/* Add this HPC instance into the HPC list */ /* Add this HPC instance into the HPC list */
spin_lock(&list_lock); spin_lock(&list_lock);
......
...@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { ...@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
*/ */
static void release_slot(struct hotplug_slot *hotplug_slot) static void release_slot(struct hotplug_slot *hotplug_slot)
{ {
struct slot *slot = (struct slot *)hotplug_slot->private; struct slot *slot = hotplug_slot->private;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......
...@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot)
func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
if (!func) { if (!func) {
dbg("%s: Error! slot NULL\n", __FUNCTION__); dbg("%s: Error! slot NULL\n", __FUNCTION__);
return 1; return -ENODEV;
} }
/* Check to see if (latch closed, card present, power off) */ /* Check to see if (latch closed, card present, power off) */
...@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot)
if (rc || !getstatus) { if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) { if (rc || getstatus) {
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
...@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot)
func = shpchp_slot_create(p_slot->bus); func = shpchp_slot_create(p_slot->bus);
if (func == NULL) if (func == NULL)
return 1; return -ENOMEM;
func->bus = p_slot->bus; func->bus = p_slot->bus;
func->device = p_slot->device; func->device = p_slot->device;
...@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot) ...@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot)
/* Setup slot structure with entry for empty slot */ /* Setup slot structure with entry for empty slot */
func = shpchp_slot_create(p_slot->bus); func = shpchp_slot_create(p_slot->bus);
if (func == NULL) if (func == NULL)
return (1); /* Out of memory */ return -ENOMEM; /* Out of memory */
func->bus = p_slot->bus; func->bus = p_slot->bus;
func->device = p_slot->device; func->device = p_slot->device;
...@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot)
struct pci_func *func; struct pci_func *func;
if (!p_slot->ctrl) if (!p_slot->ctrl)
return 1; return -ENODEV;
pci_bus = p_slot->ctrl->pci_dev->subordinate; pci_bus = p_slot->ctrl->pci_dev->subordinate;
...@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot)
if (ret || !getstatus) { if (ret || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (ret || getstatus) { if (ret || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (ret || !getstatus) { if (ret || !getstatus) {
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
return 1; return -ENODEV;
} }
up(&p_slot->ctrl->crit_sect); up(&p_slot->ctrl->crit_sect);
...@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot)
/* Check the Class Code */ /* Check the Class Code */
rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (rc) if (rc)
return rc; return -ENODEV;
if (class_code == PCI_BASE_CLASS_DISPLAY) { if (class_code == PCI_BASE_CLASS_DISPLAY) {
/* Display/Video adapter (not supported) */ /* Display/Video adapter (not supported) */
...@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot)
/* See if it's a bridge */ /* See if it's a bridge */
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return -ENODEV;
/* If it's a bridge, check the VGA Enable bit */ /* If it's a bridge, check the VGA Enable bit */
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
if (rc) if (rc)
return rc; return -ENODEV;
/* If the VGA Enable bit is set, remove isn't supported */ /* If the VGA Enable bit is set, remove isn't supported */
if (BCR & PCI_BRIDGE_CTL_VGA) { if (BCR & PCI_BRIDGE_CTL_VGA) {
...@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot) ...@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot)
if ((func != NULL) && !rc) { if ((func != NULL) && !rc) {
rc = remove_board(func, p_slot->ctrl); rc = remove_board(func, p_slot->ctrl);
} else if (!rc) } else if (!rc)
rc = 1; rc = -ENODEV;
if (p_slot) if (p_slot)
update_slot_info(p_slot); update_slot_info(p_slot);
return(rc); return rc;
} }
......
...@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf) ...@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf)
return (str - buf); return (str - buf);
} }
static ssize_t modalias_show(struct device *dev, char *buf)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
pci_dev->vendor, pci_dev->device,
pci_dev->subsystem_vendor, pci_dev->subsystem_device,
(u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
(u8)(pci_dev->class));
}
struct device_attribute pci_dev_attrs[] = { struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(resource), __ATTR_RO(resource),
__ATTR_RO(vendor), __ATTR_RO(vendor),
...@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = { ...@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(class), __ATTR_RO(class),
__ATTR_RO(irq), __ATTR_RO(irq),
__ATTR_RO(local_cpus), __ATTR_RO(local_cpus),
__ATTR_RO(modalias),
__ATTR_NULL, __ATTR_NULL,
}; };
......
...@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void); ...@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void);
extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
struct pci_dev_wrapped {
struct pci_dev *dev;
void *data;
};
struct pci_bus_wrapped {
struct pci_bus *bus;
void *data;
};
struct pci_visit {
int (* pre_visit_pci_bus) (struct pci_bus_wrapped *,
struct pci_dev_wrapped *);
int (* post_visit_pci_bus) (struct pci_bus_wrapped *,
struct pci_dev_wrapped *);
int (* pre_visit_pci_dev) (struct pci_dev_wrapped *,
struct pci_bus_wrapped *);
int (* visit_pci_dev) (struct pci_dev_wrapped *,
struct pci_bus_wrapped *);
int (* post_visit_pci_dev) (struct pci_dev_wrapped *,
struct pci_bus_wrapped *);
};
extern int pci_visit_dev(struct pci_visit *fn,
struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent);
extern void pci_remove_legacy_files(struct pci_bus *bus); extern void pci_remove_legacy_files(struct pci_bus *bus);
/* Lock for read/write access to pci device and bus lists */ /* Lock for read/write access to pci device and bus lists */
......
...@@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) ...@@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
driver->id_table->vendor != pciedev->id.vendor) || driver->id_table->vendor != pciedev->id.vendor) ||
(driver->id_table->device != PCI_ANY_ID && (driver->id_table->device != PCI_ANY_ID &&
driver->id_table->device != pciedev->id.device) || driver->id_table->device != pciedev->id.device) ||
driver->id_table->port_type != pciedev->id.port_type || (driver->id_table->port_type != PCIE_ANY_PORT &&
driver->id_table->port_type != pciedev->id.port_type) ||
driver->id_table->service_type != pciedev->id.service_type ) driver->id_table->service_type != pciedev->id.service_type )
return 0; return 0;
......
...@@ -1253,11 +1253,11 @@ void __sata_phy_reset(struct ata_port *ap) ...@@ -1253,11 +1253,11 @@ void __sata_phy_reset(struct ata_port *ap)
unsigned long timeout = jiffies + (HZ * 5); unsigned long timeout = jiffies + (HZ * 5);
if (ap->flags & ATA_FLAG_SATA_RESET) { if (ap->flags & ATA_FLAG_SATA_RESET) {
scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */ /* issue phy wake/reset */
scr_read(ap, SCR_STATUS); /* dummy read; flush */ scr_write_flush(ap, SCR_CONTROL, 0x301);
udelay(400); /* FIXME: a guess */ udelay(400); /* FIXME: a guess */
} }
scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */ scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
/* wait for phy to become ready, if necessary */ /* wait for phy to become ready, if necessary */
do { do {
...@@ -2539,7 +2539,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, ...@@ -2539,7 +2539,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
qc->dma_dir = DMA_FROM_DEVICE; qc->dma_dir = DMA_FROM_DEVICE;
memset(&qc->cdb, 0, sizeof(ap->cdb_len)); memset(&qc->cdb, 0, ap->cdb_len);
qc->cdb[0] = REQUEST_SENSE; qc->cdb[0] = REQUEST_SENSE;
qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
...@@ -2811,6 +2811,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) ...@@ -2811,6 +2811,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
/* call completion callback */ /* call completion callback */
rc = qc->complete_fn(qc, drv_stat); rc = qc->complete_fn(qc, drv_stat);
qc->flags &= ~ATA_QCFLAG_ACTIVE;
/* if callback indicates not to complete command (non-zero), /* if callback indicates not to complete command (non-zero),
* return immediately * return immediately
...@@ -3229,7 +3230,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ...@@ -3229,7 +3230,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN))) if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
(qc->flags & ATA_QCFLAG_ACTIVE))
handled |= ata_host_intr(ap, qc); handled |= ata_host_intr(ap, qc);
} }
} }
......
...@@ -347,7 +347,10 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ...@@ -347,7 +347,10 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
*/ */
if ((dev->flags & ATA_DFLAG_LBA48) && if ((dev->flags & ATA_DFLAG_LBA48) &&
((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
sdev->host->max_sectors = 2048; /*
* do not overwrite sdev->host->max_sectors, since
* other drives on this host may not support LBA48
*/
blk_queue_max_sectors(sdev->request_queue, 2048); blk_queue_max_sectors(sdev->request_queue, 2048);
} }
} }
......
...@@ -395,7 +395,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e ...@@ -395,7 +395,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* Clear a magic bit in SCR1 according to Darwin, those help /* Clear a magic bit in SCR1 according to Darwin, those help
* some funky seagate drives (though so far, those were already * some funky seagate drives (though so far, those were already
* set by the firmware on the machines I had access to * set by the firmware on the machines I had access to)
*/ */
writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000, writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
mmio_base + K2_SATA_SICR1_OFFSET); mmio_base + K2_SATA_SICR1_OFFSET);
......
...@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function, ...@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function,
int errno) int errno)
{ {
char nbuf[16]; char nbuf[16];
const char *errstr = ext3_decode_error(sb, errno, nbuf); const char *errstr;
/* Special case: if the error is EROFS, and we're not already
* inside a transaction, then there's really no point in logging
* an error. */
if (errno == -EROFS && journal_current_handle() == NULL &&
(sb->s_flags & MS_RDONLY))
return;
errstr = ext3_decode_error(sb, errno, nbuf);
printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n", printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
sb->s_id, function, errstr); sb->s_id, function, errstr);
......
...@@ -584,6 +584,13 @@ static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val) ...@@ -584,6 +584,13 @@ static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val)
ap->ops->scr_write(ap, reg, val); ap->ops->scr_write(ap, reg, val);
} }
static inline void scr_write_flush(struct ata_port *ap, unsigned int reg,
u32 val)
{
ap->ops->scr_write(ap, reg, val);
(void) ap->ops->scr_read(ap, reg);
}
static inline unsigned int sata_dev_present(struct ata_port *ap) static inline unsigned int sata_dev_present(struct ata_port *ap)
{ {
return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment