Commit a217656c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (21 commits)
  pciehp: fix error message about getting hotplug control
  pci/irq: let pci_device_shutdown to call pci_msi_shutdown v2
  pci/irq: restore mask_bits in msi shutdown -v3
  doc: replace yet another dev with pdev for consistency in DMA-mapping.txt
  PCI: don't expose struct pci_vpd to userspace
  doc: fix an incorrect suggestion to pass NULL for PCI like buses
  Consistently use pdev as the variable of type struct pci_dev *.
  pciehp: Fix command write
  shpchp: fix slot name
  make pciehp_acpi_get_hp_hw_control_from_firmware()
  pciehp: Clean up pcie_init()
  pciehp: Mask hotplug interrupt at controller release
  pciehp: Remove useless hotplug interrupt enabling
  pciehp: Fix wrong slot capability check
  pciehp: Fix wrong slot control register access
  pciehp: Add missing memory barrier
  pciehp: Fix interrupt event handlig
  pciehp: fix slot name
  Update MAINTAINERS with location of PCI tree
  PCI: Add Intel SCH PCI IDs
  ...
parents 8f45c1a5 a53edac1
...@@ -315,11 +315,11 @@ you should do: ...@@ -315,11 +315,11 @@ you should do:
dma_addr_t dma_handle; dma_addr_t dma_handle;
cpu_addr = pci_alloc_consistent(dev, size, &dma_handle); cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle);
where dev is a struct pci_dev *. You should pass NULL for PCI like buses where pdev is a struct pci_dev *. This may be called in interrupt context.
where devices don't have struct pci_dev (like ISA, EISA). This may be You should use dma_alloc_coherent (see DMA-API.txt) for buses
called in interrupt context. where devices don't have struct pci_dev (like ISA, EISA).
This argument is needed because the DMA translations may be bus This argument is needed because the DMA translations may be bus
specific (and often is private to the bus which the device is attached specific (and often is private to the bus which the device is attached
...@@ -332,7 +332,7 @@ __get_free_pages (but takes size instead of a page order). If your ...@@ -332,7 +332,7 @@ __get_free_pages (but takes size instead of a page order). If your
driver needs regions sized smaller than a page, you may prefer using driver needs regions sized smaller than a page, you may prefer using
the pci_pool interface, described below. the pci_pool interface, described below.
The consistent DMA mapping interfaces, for non-NULL dev, will by The consistent DMA mapping interfaces, for non-NULL pdev, will by
default return a DMA address which is SAC (Single Address Cycle) default return a DMA address which is SAC (Single Address Cycle)
addressable. Even if the device indicates (via PCI dma mask) that it addressable. Even if the device indicates (via PCI dma mask) that it
may address the upper 32-bits and thus perform DAC cycles, consistent may address the upper 32-bits and thus perform DAC cycles, consistent
...@@ -354,9 +354,9 @@ buffer you receive will not cross a 64K boundary. ...@@ -354,9 +354,9 @@ buffer you receive will not cross a 64K boundary.
To unmap and free such a DMA region, you call: To unmap and free such a DMA region, you call:
pci_free_consistent(dev, size, cpu_addr, dma_handle); pci_free_consistent(pdev, size, cpu_addr, dma_handle);
where dev, size are the same as in the above call and cpu_addr and where pdev, size are the same as in the above call and cpu_addr and
dma_handle are the values pci_alloc_consistent returned to you. dma_handle are the values pci_alloc_consistent returned to you.
This function may not be called in interrupt context. This function may not be called in interrupt context.
...@@ -371,9 +371,9 @@ Create a pci_pool like this: ...@@ -371,9 +371,9 @@ Create a pci_pool like this:
struct pci_pool *pool; struct pci_pool *pool;
pool = pci_pool_create(name, dev, size, align, alloc); pool = pci_pool_create(name, pdev, size, align, alloc);
The "name" is for diagnostics (like a kmem_cache name); dev and size The "name" is for diagnostics (like a kmem_cache name); pdev and size
are as above. The device's hardware alignment requirement for this are as above. The device's hardware alignment requirement for this
type of data is "align" (which is expressed in bytes, and must be a type of data is "align" (which is expressed in bytes, and must be a
power of two). If your device has no boundary crossing restrictions, power of two). If your device has no boundary crossing restrictions,
...@@ -472,11 +472,11 @@ To map a single region, you do: ...@@ -472,11 +472,11 @@ To map a single region, you do:
void *addr = buffer->ptr; void *addr = buffer->ptr;
size_t size = buffer->len; size_t size = buffer->len;
dma_handle = pci_map_single(dev, addr, size, direction); dma_handle = pci_map_single(pdev, addr, size, direction);
and to unmap it: and to unmap it:
pci_unmap_single(dev, dma_handle, size, direction); pci_unmap_single(pdev, dma_handle, size, direction);
You should call pci_unmap_single when the DMA activity is finished, e.g. You should call pci_unmap_single when the DMA activity is finished, e.g.
from the interrupt which told you that the DMA transfer is done. from the interrupt which told you that the DMA transfer is done.
...@@ -493,17 +493,17 @@ Specifically: ...@@ -493,17 +493,17 @@ Specifically:
unsigned long offset = buffer->offset; unsigned long offset = buffer->offset;
size_t size = buffer->len; size_t size = buffer->len;
dma_handle = pci_map_page(dev, page, offset, size, direction); dma_handle = pci_map_page(pdev, page, offset, size, direction);
... ...
pci_unmap_page(dev, dma_handle, size, direction); pci_unmap_page(pdev, dma_handle, size, direction);
Here, "offset" means byte offset within the given page. Here, "offset" means byte offset within the given page.
With scatterlists, you map a region gathered from several regions by: With scatterlists, you map a region gathered from several regions by:
int i, count = pci_map_sg(dev, sglist, nents, direction); int i, count = pci_map_sg(pdev, sglist, nents, direction);
struct scatterlist *sg; struct scatterlist *sg;
for_each_sg(sglist, sg, count, i) { for_each_sg(sglist, sg, count, i) {
...@@ -527,7 +527,7 @@ accessed sg->address and sg->length as shown above. ...@@ -527,7 +527,7 @@ accessed sg->address and sg->length as shown above.
To unmap a scatterlist, just call: To unmap a scatterlist, just call:
pci_unmap_sg(dev, sglist, nents, direction); pci_unmap_sg(pdev, sglist, nents, direction);
Again, make sure DMA activity has already finished. Again, make sure DMA activity has already finished.
...@@ -550,11 +550,11 @@ correct copy of the DMA buffer. ...@@ -550,11 +550,11 @@ correct copy of the DMA buffer.
So, firstly, just map it with pci_map_{single,sg}, and after each DMA So, firstly, just map it with pci_map_{single,sg}, and after each DMA
transfer call either: transfer call either:
pci_dma_sync_single_for_cpu(dev, dma_handle, size, direction); pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction);
or: or:
pci_dma_sync_sg_for_cpu(dev, sglist, nents, direction); pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction);
as appropriate. as appropriate.
...@@ -562,7 +562,7 @@ Then, if you wish to let the device get at the DMA area again, ...@@ -562,7 +562,7 @@ Then, if you wish to let the device get at the DMA area again,
finish accessing the data with the cpu, and then before actually finish accessing the data with the cpu, and then before actually
giving the buffer to the hardware call either: giving the buffer to the hardware call either:
pci_dma_sync_single_for_device(dev, dma_handle, size, direction); pci_dma_sync_single_for_device(pdev, dma_handle, size, direction);
or: or:
...@@ -739,7 +739,7 @@ failure can be determined by: ...@@ -739,7 +739,7 @@ failure can be determined by:
dma_addr_t dma_handle; dma_addr_t dma_handle;
dma_handle = pci_map_single(dev, addr, size, direction); dma_handle = pci_map_single(pdev, addr, size, direction);
if (pci_dma_mapping_error(dma_handle)) { if (pci_dma_mapping_error(dma_handle)) {
/* /*
* reduce current DMA mapping usage, * reduce current DMA mapping usage,
......
...@@ -3114,6 +3114,7 @@ P: Jesse Barnes ...@@ -3114,6 +3114,7 @@ P: Jesse Barnes
M: jbarnes@virtuousgeek.org M: jbarnes@virtuousgeek.org
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
L: linux-pci@atrey.karlin.mff.cuni.cz L: linux-pci@atrey.karlin.mff.cuni.cz
T: git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
S: Supported S: Supported
PCI HOTPLUG CORE PCI HOTPLUG CORE
......
...@@ -93,11 +93,10 @@ struct controller { ...@@ -93,11 +93,10 @@ struct controller {
u8 slot_device_offset; u8 slot_device_offset;
u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
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; u32 slot_cap;
u8 cap_base; u8 cap_base;
struct timer_list poll_timer; struct timer_list poll_timer;
volatile int cmd_busy; volatile int cmd_busy;
spinlock_t lock;
}; };
#define INT_BUTTON_IGNORE 0 #define INT_BUTTON_IGNORE 0
...@@ -137,13 +136,13 @@ struct controller { ...@@ -137,13 +136,13 @@ struct controller {
#define HP_SUPR_RM_SUP 0x00000020 #define HP_SUPR_RM_SUP 0x00000020
#define EMI_PRSN 0x00020000 #define EMI_PRSN 0x00020000
#define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) #define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & ATTN_BUTTN_PRSN)
#define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) #define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PWR_CTRL_PRSN)
#define MRL_SENS(cap) (cap & MRL_SENS_PRSN) #define MRL_SENS(ctrl) ((ctrl)->slot_cap & MRL_SENS_PRSN)
#define ATTN_LED(cap) (cap & ATTN_LED_PRSN) #define ATTN_LED(ctrl) ((ctrl)->slot_cap & ATTN_LED_PRSN)
#define PWR_LED(cap) (cap & PWR_LED_PRSN) #define PWR_LED(ctrl) ((ctrl)->slot_cap & PWR_LED_PRSN)
#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) #define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & HP_SUPR_RM_SUP)
#define EMI(cap) (cap & EMI_PRSN) #define EMI(ctrl) ((ctrl)->slot_cap & EMI_PRSN)
extern int pciehp_sysfs_enable_slot(struct slot *slot); extern int pciehp_sysfs_enable_slot(struct slot *slot);
extern int pciehp_sysfs_disable_slot(struct slot *slot); extern int pciehp_sysfs_disable_slot(struct slot *slot);
......
...@@ -41,6 +41,7 @@ int pciehp_debug; ...@@ -41,6 +41,7 @@ int pciehp_debug;
int pciehp_poll_mode; int pciehp_poll_mode;
int pciehp_poll_time; int pciehp_poll_time;
int pciehp_force; int pciehp_force;
int pciehp_slot_with_bus;
struct workqueue_struct *pciehp_wq; struct workqueue_struct *pciehp_wq;
#define DRIVER_VERSION "0.4" #define DRIVER_VERSION "0.4"
...@@ -55,10 +56,12 @@ module_param(pciehp_debug, bool, 0644); ...@@ -55,10 +56,12 @@ module_param(pciehp_debug, bool, 0644);
module_param(pciehp_poll_mode, bool, 0644); module_param(pciehp_poll_mode, bool, 0644);
module_param(pciehp_poll_time, int, 0644); module_param(pciehp_poll_time, int, 0644);
module_param(pciehp_force, bool, 0644); module_param(pciehp_force, bool, 0644);
module_param(pciehp_slot_with_bus, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
MODULE_PARM_DESC(pciehp_slot_with_bus, "Use bus number in the slot name");
#define PCIE_MODULE_NAME "pciehp" #define PCIE_MODULE_NAME "pciehp"
...@@ -193,8 +196,12 @@ static void release_slot(struct hotplug_slot *hotplug_slot) ...@@ -193,8 +196,12 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
static void make_slot_name(struct slot *slot) static void make_slot_name(struct slot *slot)
{ {
if (pciehp_slot_with_bus)
snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d",
slot->bus, slot->number); slot->bus, slot->number);
else
snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d",
slot->number);
} }
static int init_slots(struct controller *ctrl) static int init_slots(struct controller *ctrl)
...@@ -251,7 +258,7 @@ static int init_slots(struct controller *ctrl) ...@@ -251,7 +258,7 @@ static int init_slots(struct controller *ctrl)
goto error_info; goto error_info;
} }
/* create additional sysfs entries */ /* create additional sysfs entries */
if (EMI(ctrl->ctrlcap)) { if (EMI(ctrl)) {
retval = sysfs_create_file(&hotplug_slot->kobj, retval = sysfs_create_file(&hotplug_slot->kobj,
&hotplug_slot_attr_lock.attr); &hotplug_slot_attr_lock.attr);
if (retval) { if (retval) {
...@@ -284,7 +291,7 @@ static void cleanup_slots(struct controller *ctrl) ...@@ -284,7 +291,7 @@ static void cleanup_slots(struct controller *ctrl)
list_for_each_safe(tmp, next, &ctrl->slot_list) { list_for_each_safe(tmp, next, &ctrl->slot_list) {
slot = list_entry(tmp, struct slot, slot_list); slot = list_entry(tmp, struct slot, slot_list);
list_del(&slot->slot_list); list_del(&slot->slot_list);
if (EMI(ctrl->ctrlcap)) if (EMI(ctrl))
sysfs_remove_file(&slot->hotplug_slot->kobj, sysfs_remove_file(&slot->hotplug_slot->kobj,
&hotplug_slot_attr_lock.attr); &hotplug_slot_attr_lock.attr);
cancel_delayed_work(&slot->work); cancel_delayed_work(&slot->work);
...@@ -305,7 +312,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) ...@@ -305,7 +312,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
hotplug_slot->info->attention_status = status; hotplug_slot->info->attention_status = status;
if (ATTN_LED(slot->ctrl->ctrlcap)) if (ATTN_LED(slot->ctrl))
slot->hpc_ops->set_attention_status(slot, status); slot->hpc_ops->set_attention_status(slot, status);
return 0; return 0;
...@@ -472,7 +479,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -472,7 +479,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
if (rc) /* -ENODEV: shouldn't happen, but deal with it */ if (rc) /* -ENODEV: shouldn't happen, but deal with it */
value = 0; value = 0;
} }
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { if ((POWER_CTRL(ctrl)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
if (rc) if (rc)
goto err_out_free_ctrl_slot; goto err_out_free_ctrl_slot;
......
...@@ -178,7 +178,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) ...@@ -178,7 +178,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
static void set_slot_off(struct controller *ctrl, struct slot * pslot) static void set_slot_off(struct controller *ctrl, struct slot * pslot)
{ {
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/ /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
if (POWER_CTRL(ctrl->ctrlcap)) { if (POWER_CTRL(ctrl)) {
if (pslot->hpc_ops->power_off_slot(pslot)) { if (pslot->hpc_ops->power_off_slot(pslot)) {
err("%s: Issue of Slot Power Off command failed\n", err("%s: Issue of Slot Power Off command failed\n",
__func__); __func__);
...@@ -186,10 +186,10 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) ...@@ -186,10 +186,10 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
} }
} }
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
pslot->hpc_ops->green_led_off(pslot); pslot->hpc_ops->green_led_off(pslot);
if (ATTN_LED(ctrl->ctrlcap)) { if (ATTN_LED(ctrl)) {
if (pslot->hpc_ops->set_attention_status(pslot, 1)) { if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
err("%s: Issue of Set Attention Led command failed\n", err("%s: Issue of Set Attention Led command failed\n",
__func__); __func__);
...@@ -214,14 +214,14 @@ static int board_added(struct slot *p_slot) ...@@ -214,14 +214,14 @@ static int board_added(struct slot *p_slot)
__func__, p_slot->device, __func__, p_slot->device,
ctrl->slot_device_offset, p_slot->hp_slot); ctrl->slot_device_offset, p_slot->hp_slot);
if (POWER_CTRL(ctrl->ctrlcap)) { if (POWER_CTRL(ctrl)) {
/* Power on slot */ /* Power on slot */
retval = p_slot->hpc_ops->power_on_slot(p_slot); retval = p_slot->hpc_ops->power_on_slot(p_slot);
if (retval) if (retval)
return retval; return retval;
} }
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_blink(p_slot); p_slot->hpc_ops->green_led_blink(p_slot);
/* Wait for ~1 second */ /* Wait for ~1 second */
...@@ -254,7 +254,7 @@ static int board_added(struct slot *p_slot) ...@@ -254,7 +254,7 @@ static int board_added(struct slot *p_slot)
*/ */
if (pcie_mch_quirk) if (pcie_mch_quirk)
pci_fixup_device(pci_fixup_final, ctrl->pci_dev); pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_on(p_slot); p_slot->hpc_ops->green_led_on(p_slot);
return 0; return 0;
...@@ -279,7 +279,7 @@ static int remove_board(struct slot *p_slot) ...@@ -279,7 +279,7 @@ static int remove_board(struct slot *p_slot)
dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
if (POWER_CTRL(ctrl->ctrlcap)) { if (POWER_CTRL(ctrl)) {
/* power off slot */ /* power off slot */
retval = p_slot->hpc_ops->power_off_slot(p_slot); retval = p_slot->hpc_ops->power_off_slot(p_slot);
if (retval) { if (retval) {
...@@ -289,7 +289,7 @@ static int remove_board(struct slot *p_slot) ...@@ -289,7 +289,7 @@ static int remove_board(struct slot *p_slot)
} }
} }
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
/* turn off Green LED */ /* turn off Green LED */
p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->green_led_off(p_slot);
...@@ -327,7 +327,7 @@ static void pciehp_power_thread(struct work_struct *work) ...@@ -327,7 +327,7 @@ static void pciehp_power_thread(struct work_struct *work)
case POWERON_STATE: case POWERON_STATE:
mutex_unlock(&p_slot->lock); mutex_unlock(&p_slot->lock);
if (pciehp_enable_slot(p_slot) && if (pciehp_enable_slot(p_slot) &&
PWR_LED(p_slot->ctrl->ctrlcap)) PWR_LED(p_slot->ctrl))
p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->green_led_off(p_slot);
mutex_lock(&p_slot->lock); mutex_lock(&p_slot->lock);
p_slot->state = STATIC_STATE; p_slot->state = STATIC_STATE;
...@@ -409,9 +409,9 @@ static void handle_button_press_event(struct slot *p_slot) ...@@ -409,9 +409,9 @@ static void handle_button_press_event(struct slot *p_slot)
"press.\n", p_slot->name); "press.\n", p_slot->name);
} }
/* blink green LED and turn off amber */ /* blink green LED and turn off amber */
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_blink(p_slot); p_slot->hpc_ops->green_led_blink(p_slot);
if (ATTN_LED(ctrl->ctrlcap)) if (ATTN_LED(ctrl))
p_slot->hpc_ops->set_attention_status(p_slot, 0); p_slot->hpc_ops->set_attention_status(p_slot, 0);
schedule_delayed_work(&p_slot->work, 5*HZ); schedule_delayed_work(&p_slot->work, 5*HZ);
...@@ -427,13 +427,13 @@ static void handle_button_press_event(struct slot *p_slot) ...@@ -427,13 +427,13 @@ static void handle_button_press_event(struct slot *p_slot)
dbg("%s: button cancel\n", __func__); dbg("%s: button cancel\n", __func__);
cancel_delayed_work(&p_slot->work); cancel_delayed_work(&p_slot->work);
if (p_slot->state == BLINKINGOFF_STATE) { if (p_slot->state == BLINKINGOFF_STATE) {
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_on(p_slot); p_slot->hpc_ops->green_led_on(p_slot);
} else { } else {
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->green_led_off(p_slot);
} }
if (ATTN_LED(ctrl->ctrlcap)) if (ATTN_LED(ctrl))
p_slot->hpc_ops->set_attention_status(p_slot, 0); p_slot->hpc_ops->set_attention_status(p_slot, 0);
info("PCI slot #%s - action canceled due to button press\n", info("PCI slot #%s - action canceled due to button press\n",
p_slot->name); p_slot->name);
...@@ -492,16 +492,16 @@ static void interrupt_event_handler(struct work_struct *work) ...@@ -492,16 +492,16 @@ static void interrupt_event_handler(struct work_struct *work)
handle_button_press_event(p_slot); handle_button_press_event(p_slot);
break; break;
case INT_POWER_FAULT: case INT_POWER_FAULT:
if (!POWER_CTRL(ctrl->ctrlcap)) if (!POWER_CTRL(ctrl))
break; break;
if (ATTN_LED(ctrl->ctrlcap)) if (ATTN_LED(ctrl))
p_slot->hpc_ops->set_attention_status(p_slot, 1); p_slot->hpc_ops->set_attention_status(p_slot, 1);
if (PWR_LED(ctrl->ctrlcap)) if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->green_led_off(p_slot);
break; break;
case INT_PRESENCE_ON: case INT_PRESENCE_ON:
case INT_PRESENCE_OFF: case INT_PRESENCE_OFF:
if (!HP_SUPR_RM(ctrl->ctrlcap)) if (!HP_SUPR_RM(ctrl))
break; break;
dbg("Surprise Removal\n"); dbg("Surprise Removal\n");
update_slot_info(p_slot); update_slot_info(p_slot);
...@@ -531,7 +531,7 @@ int pciehp_enable_slot(struct slot *p_slot) ...@@ -531,7 +531,7 @@ int pciehp_enable_slot(struct slot *p_slot)
mutex_unlock(&p_slot->ctrl->crit_sect); mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV; return -ENODEV;
} }
if (MRL_SENS(p_slot->ctrl->ctrlcap)) { if (MRL_SENS(p_slot->ctrl)) {
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(%s)\n", __func__, info("%s: latch open on slot(%s)\n", __func__,
...@@ -541,7 +541,7 @@ int pciehp_enable_slot(struct slot *p_slot) ...@@ -541,7 +541,7 @@ int pciehp_enable_slot(struct slot *p_slot)
} }
} }
if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { if (POWER_CTRL(p_slot->ctrl)) {
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(%s)\n", __func__, info("%s: already enabled on slot(%s)\n", __func__,
...@@ -576,7 +576,7 @@ int pciehp_disable_slot(struct slot *p_slot) ...@@ -576,7 +576,7 @@ int pciehp_disable_slot(struct slot *p_slot)
/* Check to see if (latch closed, card present, power on) */ /* Check to see if (latch closed, card present, power on) */
mutex_lock(&p_slot->ctrl->crit_sect); mutex_lock(&p_slot->ctrl->crit_sect);
if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { if (!HP_SUPR_RM(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (ret || !getstatus) { if (ret || !getstatus) {
info("%s: no adapter on slot(%s)\n", __func__, info("%s: no adapter on slot(%s)\n", __func__,
...@@ -586,7 +586,7 @@ int pciehp_disable_slot(struct slot *p_slot) ...@@ -586,7 +586,7 @@ int pciehp_disable_slot(struct slot *p_slot)
} }
} }
if (MRL_SENS(p_slot->ctrl->ctrlcap)) { if (MRL_SENS(p_slot->ctrl)) {
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(%s)\n", __func__, info("%s: latch open on slot(%s)\n", __func__,
...@@ -596,7 +596,7 @@ int pciehp_disable_slot(struct slot *p_slot) ...@@ -596,7 +596,7 @@ int pciehp_disable_slot(struct slot *p_slot)
} }
} }
if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { if (POWER_CTRL(p_slot->ctrl)) {
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(%s)\n", __func__, info("%s: already disabled slot(%s)\n", __func__,
......
This diff is collapsed.
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
int shpchp_debug; int shpchp_debug;
int shpchp_poll_mode; int shpchp_poll_mode;
int shpchp_poll_time; int shpchp_poll_time;
int shpchp_slot_with_bus;
struct workqueue_struct *shpchp_wq; struct workqueue_struct *shpchp_wq;
#define DRIVER_VERSION "0.4" #define DRIVER_VERSION "0.4"
...@@ -52,9 +53,11 @@ MODULE_LICENSE("GPL"); ...@@ -52,9 +53,11 @@ MODULE_LICENSE("GPL");
module_param(shpchp_debug, bool, 0644); module_param(shpchp_debug, bool, 0644);
module_param(shpchp_poll_mode, bool, 0644); module_param(shpchp_poll_mode, bool, 0644);
module_param(shpchp_poll_time, int, 0644); module_param(shpchp_poll_time, int, 0644);
module_param(shpchp_slot_with_bus, bool, 0644);
MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not"); MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not"); MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds"); MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
MODULE_PARM_DESC(shpchp_slot_with_bus, "Use bus number in the slot name");
#define SHPC_MODULE_NAME "shpchp" #define SHPC_MODULE_NAME "shpchp"
...@@ -100,8 +103,12 @@ static void release_slot(struct hotplug_slot *hotplug_slot) ...@@ -100,8 +103,12 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
static void make_slot_name(struct slot *slot) static void make_slot_name(struct slot *slot)
{ {
if (shpchp_slot_with_bus)
snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d",
slot->bus, slot->number); slot->bus, slot->number);
else
snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d",
slot->number);
} }
static int init_slots(struct controller *ctrl) static int init_slots(struct controller *ctrl)
......
...@@ -123,7 +123,7 @@ static void msix_flush_writes(unsigned int irq) ...@@ -123,7 +123,7 @@ static void msix_flush_writes(unsigned int irq)
} }
} }
static void msi_set_mask_bit(unsigned int irq, int flag) static void msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
{ {
struct msi_desc *entry; struct msi_desc *entry;
...@@ -137,8 +137,8 @@ static void msi_set_mask_bit(unsigned int irq, int flag) ...@@ -137,8 +137,8 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
pos = (long)entry->mask_base; pos = (long)entry->mask_base;
pci_read_config_dword(entry->dev, pos, &mask_bits); pci_read_config_dword(entry->dev, pos, &mask_bits);
mask_bits &= ~(1); mask_bits &= ~(mask);
mask_bits |= flag; mask_bits |= flag & mask;
pci_write_config_dword(entry->dev, pos, mask_bits); pci_write_config_dword(entry->dev, pos, mask_bits);
} else { } else {
msi_set_enable(entry->dev, !flag); msi_set_enable(entry->dev, !flag);
...@@ -241,13 +241,13 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) ...@@ -241,13 +241,13 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
void mask_msi_irq(unsigned int irq) void mask_msi_irq(unsigned int irq)
{ {
msi_set_mask_bit(irq, 1); msi_set_mask_bits(irq, 1, 1);
msix_flush_writes(irq); msix_flush_writes(irq);
} }
void unmask_msi_irq(unsigned int irq) void unmask_msi_irq(unsigned int irq)
{ {
msi_set_mask_bit(irq, 0); msi_set_mask_bits(irq, 1, 0);
msix_flush_writes(irq); msix_flush_writes(irq);
} }
...@@ -291,7 +291,8 @@ static void __pci_restore_msi_state(struct pci_dev *dev) ...@@ -291,7 +291,8 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
msi_set_enable(dev, 0); msi_set_enable(dev, 0);
write_msi_msg(dev->irq, &entry->msg); write_msi_msg(dev->irq, &entry->msg);
if (entry->msi_attrib.maskbit) if (entry->msi_attrib.maskbit)
msi_set_mask_bit(dev->irq, entry->msi_attrib.masked); msi_set_mask_bits(dev->irq, entry->msi_attrib.maskbits_mask,
entry->msi_attrib.masked);
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
...@@ -315,7 +316,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) ...@@ -315,7 +316,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
list_for_each_entry(entry, &dev->msi_list, list) { list_for_each_entry(entry, &dev->msi_list, list) {
write_msi_msg(entry->irq, &entry->msg); write_msi_msg(entry->irq, &entry->msg);
msi_set_mask_bit(entry->irq, entry->msi_attrib.masked); msi_set_mask_bits(entry->irq, 1, entry->msi_attrib.masked);
} }
BUG_ON(list_empty(&dev->msi_list)); BUG_ON(list_empty(&dev->msi_list));
...@@ -382,6 +383,7 @@ static int msi_capability_init(struct pci_dev *dev) ...@@ -382,6 +383,7 @@ static int msi_capability_init(struct pci_dev *dev)
pci_write_config_dword(dev, pci_write_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)), msi_mask_bits_reg(pos, is_64bit_address(control)),
maskbits); maskbits);
entry->msi_attrib.maskbits_mask = temp;
} }
list_add_tail(&entry->list, &dev->msi_list); list_add_tail(&entry->list, &dev->msi_list);
...@@ -569,10 +571,9 @@ int pci_enable_msi(struct pci_dev* dev) ...@@ -569,10 +571,9 @@ int pci_enable_msi(struct pci_dev* dev)
} }
EXPORT_SYMBOL(pci_enable_msi); EXPORT_SYMBOL(pci_enable_msi);
void pci_disable_msi(struct pci_dev* dev) void pci_msi_shutdown(struct pci_dev* dev)
{ {
struct msi_desc *entry; struct msi_desc *entry;
int default_irq;
if (!pci_msi_enable || !dev || !dev->msi_enabled) if (!pci_msi_enable || !dev || !dev->msi_enabled)
return; return;
...@@ -583,15 +584,31 @@ void pci_disable_msi(struct pci_dev* dev) ...@@ -583,15 +584,31 @@ void pci_disable_msi(struct pci_dev* dev)
BUG_ON(list_empty(&dev->msi_list)); BUG_ON(list_empty(&dev->msi_list));
entry = list_entry(dev->msi_list.next, struct msi_desc, list); entry = list_entry(dev->msi_list.next, struct msi_desc, list);
if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { /* Return the the pci reset with msi irqs unmasked */
return; if (entry->msi_attrib.maskbit) {
u32 mask = entry->msi_attrib.maskbits_mask;
msi_set_mask_bits(dev->irq, mask, ~mask);
} }
if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
default_irq = entry->msi_attrib.default_irq; return;
msi_free_irqs(dev);
/* Restore dev->irq to its default pin-assertion irq */ /* Restore dev->irq to its default pin-assertion irq */
dev->irq = default_irq; dev->irq = entry->msi_attrib.default_irq;
}
void pci_disable_msi(struct pci_dev* dev)
{
struct msi_desc *entry;
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;
pci_msi_shutdown(dev);
entry = list_entry(dev->msi_list.next, struct msi_desc, list);
if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
return;
msi_free_irqs(dev);
} }
EXPORT_SYMBOL(pci_disable_msi); EXPORT_SYMBOL(pci_disable_msi);
...@@ -684,7 +701,7 @@ static void msix_free_all_irqs(struct pci_dev *dev) ...@@ -684,7 +701,7 @@ static void msix_free_all_irqs(struct pci_dev *dev)
msi_free_irqs(dev); msi_free_irqs(dev);
} }
void pci_disable_msix(struct pci_dev* dev) void pci_msix_shutdown(struct pci_dev* dev)
{ {
if (!pci_msi_enable || !dev || !dev->msix_enabled) if (!pci_msi_enable || !dev || !dev->msix_enabled)
return; return;
...@@ -692,6 +709,13 @@ void pci_disable_msix(struct pci_dev* dev) ...@@ -692,6 +709,13 @@ void pci_disable_msix(struct pci_dev* dev)
msix_set_enable(dev, 0); msix_set_enable(dev, 0);
pci_intx_for_msi(dev, 1); pci_intx_for_msi(dev, 1);
dev->msix_enabled = 0; dev->msix_enabled = 0;
}
void pci_disable_msix(struct pci_dev* dev)
{
if (!pci_msi_enable || !dev || !dev->msix_enabled)
return;
pci_msix_shutdown(dev);
msix_free_all_irqs(dev); msix_free_all_irqs(dev);
} }
......
...@@ -360,6 +360,8 @@ static void pci_device_shutdown(struct device *dev) ...@@ -360,6 +360,8 @@ static void pci_device_shutdown(struct device *dev)
if (drv && drv->shutdown) if (drv && drv->shutdown)
drv->shutdown(pci_dev); drv->shutdown(pci_dev);
pci_msi_shutdown(pci_dev);
pci_msix_shutdown(pci_dev);
} }
/** /**
......
...@@ -33,7 +33,7 @@ source "drivers/pci/pcie/aer/Kconfig" ...@@ -33,7 +33,7 @@ source "drivers/pci/pcie/aer/Kconfig"
config PCIEASPM config PCIEASPM
bool "PCI Express ASPM support(Experimental)" bool "PCI Express ASPM support(Experimental)"
depends on PCI && EXPERIMENTAL && PCIEPORTBUS depends on PCI && EXPERIMENTAL && PCIEPORTBUS
default y default n
help help
This enables PCI Express ASPM (Active State Power Management) and This enables PCI Express ASPM (Active State Power Management) and
Clock Power Management. ASPM supports state L0/L0s/L1. Clock Power Management. ASPM supports state L0/L0s/L1.
......
...@@ -22,6 +22,7 @@ struct msi_desc { ...@@ -22,6 +22,7 @@ struct msi_desc {
__u8 masked : 1; __u8 masked : 1;
__u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
__u8 pos; /* Location of the msi capability */ __u8 pos; /* Location of the msi capability */
__u32 maskbits_mask; /* mask bits mask */
__u16 entry_nr; /* specific enabled entry */ __u16 entry_nr; /* specific enabled entry */
unsigned default_irq; /* default pre-assigned irq */ unsigned default_irq; /* default pre-assigned irq */
}msi_attrib; }msi_attrib;
......
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
/* Include the pci register defines */ /* Include the pci register defines */
#include <linux/pci_regs.h> #include <linux/pci_regs.h>
struct pci_vpd;
/* /*
* The PCI interface treats multi-function devices as independent * The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded * devices. The slot/function address of each device is encoded
...@@ -131,6 +129,8 @@ struct pci_cap_saved_state { ...@@ -131,6 +129,8 @@ struct pci_cap_saved_state {
}; };
struct pcie_link_state; struct pcie_link_state;
struct pci_vpd;
/* /*
* The pci_dev structure is used to describe PCI devices. * The pci_dev structure is used to describe PCI devices.
*/ */
...@@ -702,6 +702,8 @@ static inline int pci_enable_msi(struct pci_dev *dev) ...@@ -702,6 +702,8 @@ static inline int pci_enable_msi(struct pci_dev *dev)
return -1; return -1;
} }
static inline void pci_msi_shutdown(struct pci_dev *dev)
{ }
static inline void pci_disable_msi(struct pci_dev *dev) static inline void pci_disable_msi(struct pci_dev *dev)
{ } { }
...@@ -711,6 +713,8 @@ static inline int pci_enable_msix(struct pci_dev *dev, ...@@ -711,6 +713,8 @@ static inline int pci_enable_msix(struct pci_dev *dev,
return -1; return -1;
} }
static inline void pci_msix_shutdown(struct pci_dev *dev)
{ }
static inline void pci_disable_msix(struct pci_dev *dev) static inline void pci_disable_msix(struct pci_dev *dev)
{ } { }
...@@ -721,9 +725,11 @@ static inline void pci_restore_msi_state(struct pci_dev *dev) ...@@ -721,9 +725,11 @@ static inline void pci_restore_msi_state(struct pci_dev *dev)
{ } { }
#else #else
extern int pci_enable_msi(struct pci_dev *dev); extern int pci_enable_msi(struct pci_dev *dev);
extern void pci_msi_shutdown(struct pci_dev *dev);
extern void pci_disable_msi(struct pci_dev *dev); extern void pci_disable_msi(struct pci_dev *dev);
extern int pci_enable_msix(struct pci_dev *dev, extern int pci_enable_msix(struct pci_dev *dev,
struct msix_entry *entries, int nvec); struct msix_entry *entries, int nvec);
extern void pci_msix_shutdown(struct pci_dev *dev);
extern void pci_disable_msix(struct pci_dev *dev); extern void pci_disable_msix(struct pci_dev *dev);
extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
extern void pci_restore_msi_state(struct pci_dev *dev); extern void pci_restore_msi_state(struct pci_dev *dev);
......
...@@ -2413,6 +2413,8 @@ ...@@ -2413,6 +2413,8 @@
#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119
#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a
#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 #define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
......
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