From 08dfd4707538d913897a5f458904d63d3157ac0c Mon Sep 17 00:00:00 2001 From: Dely Sy Date: Fri, 4 Jun 2004 01:01:07 -0700 Subject: [PATCH] Fixes for hot-plug drivers (updated) Here is the updated patch (against 2.6.7-rc1) for the shpchp and pciehp drivers that fixes the following issues: - proper LED status when latch is open or card is not present while the user tries to power up the slot; (reported by D. Keck) - check if kmalloc() return NULL before proceeding in acpi_get__hpp(); (provided by L. Capitulino) - add up(&ctrl->crit_sect) before return in error cases in several places; - proper handling of resources when there are other onboard devices behind the p2p bridge that has the hot-plug capabaility; - need to check negotiated link width in check_lnk_status(); - cleanup board_added() in pciehp Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_ctrl.c | 147 +++++++++++---------------------- drivers/pci/hotplug/pciehp_hpc.c | 4 +- drivers/pci/hotplug/pciehprm_acpi.c | 22 +++-- drivers/pci/hotplug/pciehprm_nonacpi.c | 18 ++-- drivers/pci/hotplug/shpchp.h | 1 + drivers/pci/hotplug/shpchp_ctrl.c | 60 ++++++-------- drivers/pci/hotplug/shpchp_pci.c | 1 + drivers/pci/hotplug/shpchprm_acpi.c | 22 +++-- drivers/pci/hotplug/shpchprm_nonacpi.c | 18 ++-- 9 files changed, 137 insertions(+), 156 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 4c5bb2f812af..44ad38fe7693 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -1058,6 +1058,34 @@ static int is_bridge(struct pci_func * func) hotplug controller logic */ +static void set_slot_off(struct controller *ctrl, struct slot * pslot) +{ + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + /* turn off slot, turn on Amber LED, turn off Green LED */ + if (pslot->hpc_ops->power_off_slot(pslot)) { + err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); + return; + } + wait_for_ctrl_irq (ctrl); + + pslot->hpc_ops->green_led_off(pslot); + + wait_for_ctrl_irq (ctrl); + + /* turn on Amber LED */ + if (pslot->hpc_ops->set_attention_status(pslot, 1)) { + err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); + return; + } + wait_for_ctrl_irq (ctrl); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); +} /** * board_added - Called after a board has been added to the system. @@ -1071,7 +1099,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) u8 hp_slot; int index; u32 temp_register = 0xFFFFFFFF; - u32 retval, rc = 0; + u32 rc = 0; struct pci_func *new_func = NULL; struct slot *p_slot; struct resource_lists res_lists; @@ -1086,8 +1114,10 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) /* Power on slot */ rc = p_slot->hpc_ops->power_on_slot(p_slot); - if (rc) + if (rc) { + up(&ctrl->crit_sect); return -1; + } /* Wait for the command to complete */ wait_for_ctrl_irq (ctrl); @@ -1105,11 +1135,12 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) wait_for_ctrl_irq (ctrl); dbg("%s: afterlong_delay\n", __FUNCTION__); - /* Make this to check for link training status */ + /* Check link training status */ rc = p_slot->hpc_ops->check_lnk_status(ctrl); if (rc) { err("%s: Failed to check link status\n", __FUNCTION__); - return -1; + set_slot_off(ctrl, p_slot); + return rc; } dbg("%s: func status = %x\n", __FUNCTION__, func->status); @@ -1159,36 +1190,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) pciehp_resource_sort_and_combine(&(ctrl->bus_head)); if (rc) { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - /* In PCI Express, just power off slot */ - if (retval) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* turn on Amber LED */ - retval = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (retval) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - + set_slot_off(ctrl, p_slot); return rc; } pciehp_save_slot_config(ctrl, func); @@ -1223,37 +1225,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) up(&ctrl->crit_sect); } else { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - /* In PCI Express, just power off slot */ - if (retval) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* turn on Amber LED */ - retval = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (retval) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - return rc; + set_slot_off(ctrl, p_slot); + return -1; } return 0; } @@ -1320,6 +1293,7 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) rc = p_slot->hpc_ops->power_off_slot(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return rc; } /* Wait for the command to complete */ @@ -1406,7 +1380,6 @@ static void pciehp_pushbutton_thread(unsigned long slot) { struct slot *p_slot = (struct slot *) slot; u8 getstatus; - int rc; pushbutton_pending = 0; @@ -1420,23 +1393,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) p_slot->state = POWEROFF_STATE; dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); - if (pciehp_disable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - down(&p_slot->ctrl->crit_sect); - - /* Turn on the Attention LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - up(&p_slot->ctrl->crit_sect); - } + pciehp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; @@ -1446,15 +1403,6 @@ static void pciehp_pushbutton_thread(unsigned long slot) /* Wait for exclusive access to hardware */ down(&p_slot->ctrl->crit_sect); - /* Turn off the green LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - p_slot->hpc_ops->green_led_off(p_slot); /* Wait for the command to complete */ @@ -1664,7 +1612,10 @@ static void interrupt_event_handler(struct controller *ctrl) down(&ctrl->crit_sect); p_slot->hpc_ops->set_attention_status(p_slot, 1); + wait_for_ctrl_irq (ctrl); + p_slot->hpc_ops->green_led_off(p_slot); + wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -1701,21 +1652,21 @@ int pciehp_enable_slot(struct slot *p_slot) if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } up(&p_slot->ctrl->crit_sect); @@ -1788,21 +1739,21 @@ int pciehp_disable_slot(struct slot *p_slot) if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return 0; + return 1; } up(&p_slot->ctrl->crit_sect); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 2a68ace53938..1505b9ce3ad8 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -349,7 +349,9 @@ static int hpc_check_lnk_status(struct controller *ctrl) return retval; } - if ( (lnk_status & (LNK_TRN | LNK_TRN_ERR)) == 0x0C00) { + dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status); + if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || + !(lnk_status & NEG_LINK_WD)) { err("%s : Link Training Error occurs \n", __FUNCTION__); retval = -1; return retval; diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c index ff19a806f593..b127575ec985 100644 --- a/drivers/pci/hotplug/pciehprm_acpi.c +++ b/drivers/pci/hotplug/pciehprm_acpi.c @@ -218,6 +218,10 @@ static void acpi_get__hpp ( struct acpi_bridge *ab) } ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); + if (!ab->_hpp) { + err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); + goto free_and_return; + } memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); ab->_hpp->cache_line_size = nui[0]; @@ -1393,7 +1397,7 @@ static int configure_existing_function( static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -1411,11 +1415,19 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) if (vid != 0xFFFFFFFF) { dbg("%s: vid = %x\n", __FUNCTION__, vid); func = pciehp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + pciehprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + pciehprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - pciehprm_dump_func_res(func); } } } diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c index 3ace44220f59..79a0aa6238ef 100644 --- a/drivers/pci/hotplug/pciehprm_nonacpi.c +++ b/drivers/pci/hotplug/pciehprm_nonacpi.c @@ -276,7 +276,7 @@ static int pciehprm_delete_resource( static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -297,11 +297,19 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) vid, busn, devn, funn); func = pciehp_slot_find(busn, devn, funn); dbg("%s: func = %p\n", __FUNCTION__,func); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + phprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + phprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - phprm_dump_func_res(func); } } } diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index bc890dec0e96..c68b22efb5ac 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -61,6 +61,7 @@ struct pci_func { u8 configured; u8 switch_save; u8 presence_save; + u8 pwr_save; u32 base_length[0x06]; u8 base_type[0x06]; u16 reserved2; diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index e92c1e0675f2..181a2f69ae56 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -137,6 +137,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + dbg("%s: Card present %x Power status %x\n", __FUNCTION__, + func->presence_save, func->pwr_save); if (getstatus) { /* @@ -145,6 +147,10 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); func->switch_save = 0; taskInfo->event_type = INT_SWITCH_OPEN; + if (func->pwr_save && func->presence_save) { + taskInfo->event_type = INT_POWER_FAULT; + err("Surprise Removal of card\n"); + } } else { /* * Switch closed @@ -1427,6 +1433,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed); if (rc) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } @@ -1438,6 +1445,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", __FUNCTION__); err("%s: Error code (%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } /* Done with exclusive hardware access */ @@ -1589,8 +1597,9 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) func->status = 0; func->switch_save = 0x10; func->is_a_board = 0x01; + func->pwr_save = 1; - /* next, we will instantiate the linux pci_dev structures + /* Next, we will instantiate the linux pci_dev structures * (with appropriate driver notification, if already present) */ index = 0; @@ -1781,6 +1790,7 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl) func->function = 0; func->configured = 0; func->switch_save = 0x10; + func->pwr_save = 0; func->is_a_board = 0; } @@ -1807,7 +1817,6 @@ static void shpchp_pushbutton_thread (unsigned long slot) { struct slot *p_slot = (struct slot *) slot; u8 getstatus; - int rc; pushbutton_pending = 0; @@ -1821,23 +1830,7 @@ static void shpchp_pushbutton_thread (unsigned long slot) p_slot->state = POWEROFF_STATE; dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); - if (shpchp_disable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - down(&p_slot->ctrl->crit_sect); - - /* Turn on the Attention LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - up(&p_slot->ctrl->crit_sect); - } + shpchp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; @@ -1847,15 +1840,6 @@ static void shpchp_pushbutton_thread (unsigned long slot) /* Wait for exclusive access to hardware */ down(&p_slot->ctrl->crit_sect); - /* Turn off the green LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - p_slot->hpc_ops->green_led_off(p_slot); /* Wait for the command to complete */ @@ -2096,7 +2080,7 @@ int shpchp_enable_slot (struct slot *p_slot) func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); if (!func) { dbg("%s: Error! slot NULL\n", __FUNCTION__); - return (1); + return 1; } /* Check to see if (latch closed, card present, power off) */ @@ -2105,19 +2089,19 @@ int shpchp_enable_slot (struct slot *p_slot) if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } up(&p_slot->ctrl->crit_sect); @@ -2125,7 +2109,7 @@ int shpchp_enable_slot (struct slot *p_slot) func = shpchp_slot_create(p_slot->bus); if (func == NULL) - return (1); + return 1; func->bus = p_slot->bus; func->device = p_slot->device; @@ -2135,6 +2119,8 @@ int shpchp_enable_slot (struct slot *p_slot) /* We have to save the presence info for these slots */ p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); + p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save)); + dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); func->switch_save = !getstatus? 0x10:0; @@ -2181,7 +2167,7 @@ int shpchp_disable_slot (struct slot *p_slot) struct pci_func *func; if (!p_slot->ctrl) - return (1); + return 1; /* Check to see if (latch closed, card present, power on) */ down(&p_slot->ctrl->crit_sect); @@ -2190,19 +2176,19 @@ int shpchp_disable_slot (struct slot *p_slot) if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return 1; } up(&p_slot->ctrl->crit_sect); diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 2c9b23f4630e..90113e9cd69b 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -263,6 +263,7 @@ int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slot new_slot->function = (u8) function; new_slot->is_a_board = 1; new_slot->switch_save = 0x10; + new_slot->pwr_save = 1; /* In case of unsupported board */ new_slot->status = DevError; new_slot->pci_dev = pci_find_slot(new_slot->bus, diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 8b70c0ccfd02..6ea1703c2a8b 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -218,6 +218,10 @@ static void acpi_get__hpp ( struct acpi_bridge *ab) } ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); + if (!ab->_hpp) { + err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name); + goto free_and_return; + } memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); ab->_hpp->cache_line_size = nui[0]; @@ -1391,7 +1395,7 @@ static int configure_existing_function( static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->bus; int devn, funn; u32 vid; @@ -1406,11 +1410,19 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + shpchprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + shpchprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - shpchprm_dump_func_res(func); } } } diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c index 673719e06d88..88f4d9f41886 100644 --- a/drivers/pci/hotplug/shpchprm_nonacpi.c +++ b/drivers/pci/hotplug/shpchprm_nonacpi.c @@ -208,7 +208,7 @@ static int configure_existing_function( static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -226,11 +226,19 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + phprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + phprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - phprm_dump_func_res(func); } } } -- cgit v1.2.3 From f5bfafe34c580d0364b547e9e593aa25cf06d8b1 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Tue, 8 Jun 2004 00:28:46 -0700 Subject: [PATCH] PCI: fix irq routing on acer travelmate 360 laptop Fixes interrupt routing on acer travelmate 360 notebooks. it looks like the bios assigned the wrong pirq value for the cardbus bridge. just assigning irq 10 to all devices with pirq 0x63 would break second usb port. pirq 0x68 seems to be right one for cardbus. Signed-off-by: Daniel Ritz Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/dmi_scan.c | 29 +++++++++++++++++++++++++++++ arch/i386/pci/irq.c | 9 +++++++++ 2 files changed, 38 insertions(+) diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index 6c20ebe9934f..2808e6b16fb4 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c @@ -359,6 +359,21 @@ static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d) return 0; } +/* + * Work around broken Acer TravelMate 360 Notebooks which assign Cardbus to + * IRQ 11 even though it is actually wired to IRQ 10 + */ +static __init int fix_acer_tm360_irqrouting(struct dmi_blacklist *d) +{ +#ifdef CONFIG_PCI + extern int acer_tm360_irqrouting; + if (acer_tm360_irqrouting == 0) { + acer_tm360_irqrouting = 1; + printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident); + } +#endif + return 0; +} /* * Check for clue free BIOS implementations who use * the following QA technique @@ -844,6 +859,13 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={ MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736") } }, + + { fix_acer_tm360_irqrouting, "Acer TravelMate 36x Laptop", { + MATCH(DMI_SYS_VENDOR, "Acer"), + MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + NO_MATCH, NO_MATCH + } }, + /* @@ -1033,6 +1055,13 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={ MATCH(DMI_BOARD_NAME, "PR-DLS"), MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"), MATCH(DMI_BIOS_DATE, "03/21/2003") }}, + + { disable_acpi_pci, "Acer TravelMate 36x Laptop", { + MATCH(DMI_SYS_VENDOR, "Acer"), + MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + NO_MATCH, NO_MATCH + } }, + #endif { NULL, } diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index e29b67b9cc27..4429f6aea08d 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -23,6 +23,7 @@ #define PIRQ_VERSION 0x0100 int broken_hp_bios_irq9; +int acer_tm360_irqrouting; static struct irq_routing_table *pirq_table; @@ -745,6 +746,14 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) r->set(pirq_router_dev, dev, pirq, 11); } + /* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */ + if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) { + pirq = 0x68; + mask = 0x400; + dev->irq = r->get(pirq_router_dev, dev, pirq); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } + /* * Find the best IRQ to assign: use the one * reported by the device if possible. -- cgit v1.2.3 From 42d5f1e11922ef68a9604c7655b778cb8c8765b7 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 11 Jun 2004 03:15:00 -0700 Subject: [PATCH] PCI: clarify pci.txt wrt IRQ allocation I think we should make it explicit that PCI IRQs shouldn't be relied upon until after pci_enable_device(). This patch: ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.7-rc3/2.6.7-rc3-mm1/broken-out/bk-acpi.patch does PCI interrupt routing (based on ACPI _PRT) and IRQ allocation at pci_enable_device()-time. (To avoid breaking things in 2.6, the above patch still allocates all PCI IRQs in pci_acpi_init(), before any drivers are initialized. But that shouldn't be needed by correct drivers, and I'd like to remove it in 2.7.) Signed-off-by: Greg Kroah-Hartman --- Documentation/pci.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/pci.txt b/Documentation/pci.txt index d30dc107ac62..41194763862b 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -166,8 +166,9 @@ count on these devices by calling pci_dev_put(). ~~~~~~~~~~~~~~~~~~~ Before you do anything with the device you've found, you need to enable it by calling pci_enable_device() which enables I/O and memory regions of -the device, assigns missing resources if needed and wakes up the device -if it was in suspended state. Please note that this function can fail. +the device, allocates an IRQ if necessary, assigns missing resources if +needed and wakes up the device if it was in suspended state. Please note +that this function can fail. If you want to use the device in bus mastering mode, call pci_set_master() which enables the bus master bit in PCI_COMMAND register and also fixes -- cgit v1.2.3 From f9da471619b2d34b60a58519c29fe463fc6c1318 Mon Sep 17 00:00:00 2001 From: Linda Xie Date: Fri, 11 Jun 2004 03:15:38 -0700 Subject: [PATCH] PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly I made changes to rpaphp code, so it can handle multi-fuction devices correctly. The problem is that the pci_dev field of slot struct can only record one pci_dev of the devices of a multi-fuction card. I changed pci_dev (a single pci_dev type pointer) to pci_funcs( a list of pci_dev type pointers). I rewrote some of the config/unconfig code to support the slot struct change. Along with above changes, I added LDRSLOT(logical I/O slot) support. We need LDRSLOT support for DLPAR I/O. A card in a LDRSLOT can't be physically removed, but can be logically removed from one partiton and reassinged to another partition. I also merged rpaphp changes from ames tree. Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 28 +-- drivers/pci/hotplug/rpaphp.h | 28 ++- drivers/pci/hotplug/rpaphp_core.c | 199 +++++++++++++++------- drivers/pci/hotplug/rpaphp_pci.c | 328 +++++++++++++++++++++++++----------- drivers/pci/hotplug/rpaphp_slot.c | 136 ++++++++++++--- drivers/pci/hotplug/rpaphp_vio.c | 6 +- 6 files changed, 508 insertions(+), 217 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index b321b47cf010..34d691cbe080 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -24,25 +24,6 @@ static DECLARE_MUTEX(rpadlpar_sem); -static inline int is_hotplug_capable(struct device_node *dn) -{ - unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL); - - return (int) (ptr != NULL); -} - -static char *get_node_drc_name(struct device_node *dn) -{ - char *ptr = NULL; - int *drc_names; - - drc_names = (int *) get_property(dn, "ibm,drc-names", NULL); - if (drc_names) - ptr = (char *) &drc_names[1]; - - return ptr; -} - static struct device_node *find_php_slot_vio_node(char *drc_name) { struct device_node *child; @@ -53,9 +34,9 @@ static struct device_node *find_php_slot_vio_node(char *drc_name) return NULL; for (child = of_get_next_child(parent, NULL); - child; child = of_get_next_child(parent, child)) { + child; child = of_get_next_child(parent, child)) { loc_code = get_property(child, "ibm,loc-code", NULL); - if (loc_code && !strcmp(loc_code, drc_name)) + if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name))) return child; } @@ -69,7 +50,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name) while ((np = of_find_node_by_type(np, "pci"))) if (is_hotplug_capable(np)) { - name = get_node_drc_name(np); + name = rpaphp_get_drc_name(np); if (name && (!strcmp(drc_name, name))) break; } @@ -324,6 +305,7 @@ int dlpar_remove_pci_slot(struct slot *slot, char *drc_name) } /* Remove pci bus */ + if (dlpar_pci_remove_bus(bridge_dev)) { printk(KERN_ERR "%s: unable to remove pci bus %s\n", __FUNCTION__, drc_name); @@ -364,7 +346,7 @@ int dlpar_remove_slot(char *drc_name) rc = -EINVAL; goto exit; } - + switch (slot->dev_type) { case PCI_DEV: rc = dlpar_remove_pci_slot(slot, drc_name); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 3c860e156911..eb0d6ba596bf 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -30,6 +30,9 @@ #include #include "pci_hotplug.h" +#define HOTPLUG 1 +#define EMBEDDED 0 + #define DR_INDICATOR 9002 #define DR_ENTITY_SENSE 9003 @@ -73,6 +76,11 @@ extern int debug; #define CONFIGURED 1 #define EMPTY 0 +struct rpaphp_pci_func { + struct pci_dev *pci_dev; + struct list_head sibling; +}; + /* * struct slot - slot information for each *physical* slot */ @@ -83,14 +91,13 @@ struct slot { u32 power_domain; char *name; char *location; + u8 removable; struct device_node *dn; /* slot's device_node in OFDT */ - /* dn has phb info */ + /* dn has phb info */ struct pci_dev *bridge; /* slot's pci_dev in pci_devices */ union { - struct pci_dev *pci_dev; /* pci_dev of device in this slot */ - /* it will be used for unconfig */ - /* NULL if slot is empty */ - struct vio_dev *vio_dev; /* vio_dev of the device in this slot */ + struct list_head pci_funcs; /* pci_devs in PCI slot */ + struct vio_dev *vio_dev; /* vio_dev in VIO slot */ } dev; u8 dev_type; /* VIO or PCI */ struct hotplug_slot *hotplug_slot; @@ -101,6 +108,13 @@ extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops; extern struct list_head rpaphp_slot_head; extern int num_slots; +static inline int is_hotplug_capable(struct device_node *dn) +{ + unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL); + + return (int) (ptr != NULL); +} + /* function prototypes */ /* rpaphp_pci.c */ @@ -110,10 +124,12 @@ extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_unconfig_pci_adapter(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); +extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); extern int rpaphp_remove_slot(struct slot *slot); +extern char *rpaphp_get_drc_name(struct device_node *dn); /* rpaphp_vio.c */ extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value); @@ -125,8 +141,8 @@ extern int rpaphp_enable_vio_slot(struct slot *slot); extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); extern int register_slot(struct slot *slot); +extern int deregister_slot(struct slot *slot); extern int rpaphp_get_power_status(struct slot *slot, u8 * value); extern int rpaphp_set_attention_status(struct slot *slot, u8 status); -extern void rpaphp_sysfs_remove_attr_location(struct hotplug_slot *slot); #endif /* _PPC64PHP_H */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 1572054280e2..dd6dcdc73b87 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -54,6 +54,8 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +void eeh_register_disable_func(int (*)(struct pci_dev *)); + module_param(debug, bool, 0644); static int enable_slot(struct hotplug_slot *slot); @@ -63,6 +65,7 @@ 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_adapter_status(struct hotplug_slot *slot, u8 * value); static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); +static int rpaphp_disable_slot(struct pci_dev *dev); struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .owner = THIS_MODULE, @@ -89,7 +92,7 @@ static int rpaphp_get_attention_status(struct slot *slot) */ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { - int retval; + int retval = 0; struct slot *slot = (struct slot *)hotplug_slot->private; down(&rpaphp_sem); @@ -208,47 +211,53 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe int rpaphp_remove_slot(struct slot *slot) { - int retval = 0; - struct hotplug_slot *php_slot = slot->hotplug_slot; - - list_del(&slot->rpaphp_slot_list); - - /* remove "php_location" file */ - rpaphp_sysfs_remove_attr_location(php_slot); - - retval = pci_hp_deregister(php_slot); - if (retval) - err("Problem unregistering a slot %s\n", slot->name); - - num_slots--; - - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); - return retval; + return deregister_slot(slot); } -static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types, - int **power_domains) +static int get_dn_properties(struct device_node *dn, int **indexes, int **names, + int **types, int **power_domains) { *indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL); - if (!*indexes) - return 0; + /* &names[1] contains NULL terminated slot names */ *names = (int *) get_property(dn, "ibm,drc-names", NULL); - if (!*names) - return 0; + /* &types[1] contains NULL terminated slot types */ *types = (int *) get_property(dn, "ibm,drc-types", NULL); - if (!*types) - return 0; + /* power_domains[1...n] are the slot power domains */ - *power_domains = (int *) get_property(dn, - "ibm,drc-power-domains", NULL); - if (!*power_domains) - return 0; - if (strcmp(dn->name, "pci") == 0 && - !get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL)) - return 0; - return 1; + *power_domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL); + + if (*indexes && *names && *types && *power_domains) + return (1); + + return (0); +} + +static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types, + int **power_domains) +{ + if (!is_hotplug_capable(dn)) + return (0); + if (!get_dn_properties(dn, indexes, names, types, power_domains)) + return (0); + return (1); +} + +static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types, + int **power_domains, int **my_drc_index) +{ + if (!is_hotplug_capable(dn)) + return (0); + + *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL); + if(!*my_drc_index) + return (0); + + if (!dn->parent) + return (0); + + return get_dn_properties(dn->parent, indexes, names, types, power_domains); } static inline int is_vdevice_root(struct device_node *dn) @@ -256,15 +265,48 @@ static inline int is_vdevice_root(struct device_node *dn) return !strcmp(dn->name, "vdevice"); } -/** - * rpaphp_add_slot: Add Hot Plug slot(s) to sysfs - * - */ +char *rpaphp_get_drc_name(struct device_node *dn) +{ + char *name, *ptr = NULL; + int *drc_names, *drc_indexes, i; + struct device_node *parent = dn->parent; + u32 *my_drc_index; + + if (!parent) + return NULL; + + my_drc_index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL); + if (!my_drc_index) + return NULL; + + drc_names = (int *) get_property(parent, "ibm,drc-names", NULL); + drc_indexes = (int *) get_property(parent, "ibm,drc-indexes", NULL); + if (!drc_names || !drc_indexes) + return NULL; + + name = (char *) &drc_names[1]; + for (i = 0; i < drc_indexes[0]; i++, name += (strlen(name) + 1)) { + if (drc_indexes[i + 1] == *my_drc_index) { + ptr = (char *) name; + break; + } + } + + return ptr; +} + +/**************************************************************** + * rpaphp not only registers PCI hotplug slots(HOTPLUG), + * but also logical DR slots(EMBEDDED). + * HOTPLUG slot: An adapter can be physically added/removed. + * EMBEDDED slot: An adapter can be logically removed/added + * from/to a partition with the slot. + ***************************************************************/ int rpaphp_add_slot(struct device_node *dn) { struct slot *slot; int retval = 0; - int i; + int i, *my_drc_index, slot_type; int *indexes, *names, *types, *power_domains; char *name, *type; @@ -277,42 +319,65 @@ int rpaphp_add_slot(struct device_node *dn) } /* register PCI devices */ - if (dn->name != 0 && strcmp(dn->name, "pci") == 0 && - is_php_dn(dn, &indexes, &names, &types, &power_domains)) { + if (dn->name != 0 && strcmp(dn->name, "pci") == 0) { + if (is_php_dn(dn, &indexes, &names, &types, &power_domains)) + slot_type = HOTPLUG; + else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index)) + slot_type = EMBEDDED; + else goto exit; name = (char *) &names[1]; type = (char *) &types[1]; - for (i = 0; i < indexes[0]; - i++, - name += (strlen(name) + 1), - type += (strlen(type) + 1)) { - if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, - power_domains[i + 1]))) { - retval = -ENOMEM; - goto exit; + for (i = 0; i < indexes[0]; i++, + name += (strlen(name) + 1), type += (strlen(type) + 1)) { + + if ( slot_type == HOTPLUG || + (slot_type == EMBEDDED && indexes[i + 1] == my_drc_index[0])) { + + if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, + power_domains[i + 1]))) { + retval = -ENOMEM; + goto exit; + } + if (slot_type == EMBEDDED) + slot->type = EMBEDDED; + else + slot->type = simple_strtoul(type, NULL, 10); + + dbg(" Found drc-index:0x%x drc-name:%s drc-type:%s\n", + indexes[i + 1], name, type); + + retval = register_pci_slot(slot); + if (slot_type == EMBEDDED) + goto exit; } - slot->type = simple_strtoul(type, NULL, 10); - if (slot->type < 1 || slot->type > 16) - slot->type = 0; - retval = register_pci_slot(slot); - - } /* for indexes */ - } /* end of PCI device_node */ + } + } exit: dbg("%s - Exit: num_slots=%d rc[%d]\n", __FUNCTION__, num_slots, retval); return retval; } -static int __init init_rpa(void) +/* + * init_slots - initialize 'struct slot' structures for each slot + * + */ +static void init_slots(void) { struct device_node *dn; + for (dn = find_all_nodes(); dn; dn = dn->next) + rpaphp_add_slot(dn); +} + +static int __init init_rpa(void) +{ + init_MUTEX(&rpaphp_sem); /* initialize internal data structure etc. */ - for (dn = find_all_nodes(); dn; dn = dn->next) - rpaphp_add_slot(dn); + init_slots(); if (!num_slots) return -ENODEV; @@ -342,12 +407,18 @@ static int __init rpaphp_init(void) { info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + /* let EEH know they can use hotplug */ + eeh_register_disable_func(&rpaphp_disable_slot); + /* read all the PRA info from the system */ return init_rpa(); } static void __exit rpaphp_exit(void) { + /* let EEH know we are going away */ + eeh_register_disable_func(NULL); + cleanup_slots(); } @@ -374,11 +445,16 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) retval = -EINVAL; } up(&rpaphp_sem); - exit: +exit: dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } +static int rpaphp_disable_slot(struct pci_dev *dev) +{ + return disable_slot(rpaphp_find_hotplug_slot(dev)); +} + static int disable_slot(struct hotplug_slot *hotplug_slot) { int retval; @@ -395,9 +471,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) down(&rpaphp_sem); switch (slot->dev_type) { case PCI_DEV: - rpaphp_set_attention_status(slot, LED_ID); retval = rpaphp_unconfig_pci_adapter(slot); - rpaphp_set_attention_status(slot, LED_OFF); break; case VIO_DEV: retval = rpaphp_unconfig_vio_adapter(slot); @@ -406,7 +480,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) retval = -ENODEV; } up(&rpaphp_sem); - exit: +exit: dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } @@ -417,3 +491,4 @@ module_exit(rpaphp_exit); EXPORT_SYMBOL_GPL(rpaphp_add_slot); EXPORT_SYMBOL_GPL(rpaphp_remove_slot); EXPORT_SYMBOL_GPL(rpaphp_slot_head); +EXPORT_SYMBOL_GPL(rpaphp_get_drc_name); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 6f5b61b7c61a..1fc2c3b820e8 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -30,24 +30,18 @@ struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) { - struct pci_dev *retval_dev = NULL, *dev; + struct pci_dev *retval_dev = NULL, *dev = NULL; char bus_id[BUS_ID_SIZE]; sprintf(bus_id, "%04x:%02x:%02x.%d",dn->phb->global_number, dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn)); - - dbg("Enter rpaphp_find_pci_dev() full_name=%s bus_id=%s\n", - dn->full_name, bus_id); - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (!strcmp(pci_name(dev), bus_id)) { + if (!strcmp(pci_name(dev), bus_id)) { retval_dev = dev; - dbg("rpaphp_find_pci_dev(): found dev=%p\n\n", dev); break; } } return retval_dev; - } EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev); @@ -79,11 +73,6 @@ static struct pci_dev *rpaphp_find_bridge_pdev(struct slot *slot) return rpaphp_find_pci_dev(slot->dn); } -static struct pci_dev *rpaphp_find_adapter_pdev(struct slot *slot) -{ - return rpaphp_find_pci_dev(slot->dn->child); -} - static int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; @@ -144,7 +133,8 @@ int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) else if (rpaphp_find_pci_dev(slot->dn->child)) *value = CONFIGURED; else { - dbg("%s: can't find pdev of adapter in slot[%s]\n", __FUNCTION__, slot->name); + err("%s: can't find pdev of adapter in slot[%s]\n", + __FUNCTION__, slot->dn->full_name); *value = NOT_CONFIGURED; } } @@ -158,7 +148,8 @@ exit: } /* Must be called before pci_bus_add_devices */ -static void rpaphp_fixup_new_pci_devices(struct pci_bus *bus) +static void +rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) { struct pci_dev *dev; @@ -169,8 +160,9 @@ static void rpaphp_fixup_new_pci_devices(struct pci_bus *bus) */ if (list_empty(&dev->global_list)) { int i; - - pcibios_fixup_device_resources(dev, bus); + + if(fix_bus) + pcibios_fixup_device_resources(dev, bus); pci_read_irq_line(dev); for (i = 0; i < PCI_NUM_RESOURCES; i++) { struct resource *r = &dev->resource[i]; @@ -183,69 +175,139 @@ static void rpaphp_fixup_new_pci_devices(struct pci_bus *bus) } } -static void -rpaphp_pci_config_device(struct pci_bus *pci_bus, struct device_node *dn) -{ - int num; - - num = pci_scan_slot(pci_bus, PCI_DEVFN(PCI_SLOT(dn->devfn), 0)); - if (num) { - rpaphp_fixup_new_pci_devices(pci_bus); - pci_bus_add_devices(pci_bus); - } -} - -static int rpaphp_pci_config_bridge(struct pci_dev *dev, struct device_node *dn); +static int rpaphp_pci_config_bridge(struct pci_dev *dev); /***************************************************************************** - rpaphp_pci_config_dn() will recursively configure all devices under the - given slot->dn and return the dn's pci_dev. + rpaphp_pci_config_slot() will configure all devices under the + given slot->dn and return the the first pci_dev. *****************************************************************************/ static struct pci_dev * -rpaphp_pci_config_dn(struct device_node *dn, struct pci_bus *bus) +rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus) { - struct device_node *local; + struct device_node *eads_first_child = dn->child; struct pci_dev *dev; - - for (local = dn->child; local; local = local->sibling) { - rpaphp_pci_config_device(bus, local); - dev = rpaphp_find_pci_dev(local); - if (!rpaphp_pci_config_bridge(dev, local)) + int num; + + dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); + + if (eads_first_child) { + /* pci_scan_slot should find all children of EADs */ + num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0)); + if (num) { + rpaphp_fixup_new_pci_devices(bus, 1); + pci_bus_add_devices(bus); + } + dev = rpaphp_find_pci_dev(eads_first_child); + if (!dev) { + err("No new device found\n"); return NULL; + } + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + rpaphp_pci_config_bridge(dev); } - return dev; } -static int rpaphp_pci_config_bridge(struct pci_dev *dev, struct device_node *dn) +static int rpaphp_pci_config_bridge(struct pci_dev *dev) +{ + u8 sec_busno; + struct pci_bus *child_bus; + struct pci_dev *child_dev; + + dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); + + /* get busno of downstream bus */ + pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); + + /* add to children of PCI bridge dev->bus */ + child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); + if (!child_bus) { + err("%s: could not add second bus\n", __FUNCTION__); + return -EIO; + } + sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); + /* do pci_scan_child_bus */ + pci_scan_child_bus(child_bus); + + list_for_each_entry(child_dev, &child_bus->devices, bus_list) { + eeh_add_device_late(child_dev); + } + + /* fixup new pci devices without touching bus struct */ + rpaphp_fixup_new_pci_devices(child_bus, 0); + + /* Make the discovered devices available */ + pci_bus_add_devices(child_bus); + return 0; +} + +static void enable_eeh(struct device_node *dn) { - if (dev && dn->child) { /* dn is a PCI bridge node */ - struct pci_bus *child; - u8 sec_busno; - - /* get busno of downstream bus */ - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); - - /* add to children of PCI bridge dev->bus */ - child = pci_add_new_bus(dev->bus, dev, sec_busno); - if (!child) { - err("%s: could not add second bus\n", __FUNCTION__); - return 0; + struct device_node *sib; + + for (sib = dn->child; sib; sib = sib->sibling) + enable_eeh(sib); + eeh_add_device_early(dn); + return; + +} + +#ifdef DEBUG +static void print_slot_pci_funcs(struct slot *slot) +{ + struct list_head *l; + + if (slot->dev_type == PCI_DEV) { + printk("pci_funcs of slot[%s]\n", slot->name); + if (list_empty(&slot->dev.pci_funcs)) + printk(" pci_funcs is EMPTY\n"); + + list_for_each (l, &slot->dev.pci_funcs) { + struct rpaphp_pci_func *func = + list_entry(l, struct rpaphp_pci_func, sibling); + printk(" FOUND dev=%s\n", pci_name(func->pci_dev)); } - sprintf(child->name, "PCI Bus #%02x", child->number); - /* Fixup subordinate bridge bases and resureces */ - pcibios_fixup_bus(child); + } + return; +} +#else +static void print_slot_pci_funcs(struct slot *slot) +{ + return; +} +#endif - /* may need do more stuff here */ - rpaphp_pci_config_dn(dn, dev->subordinate); +static int init_slot_pci_funcs(struct slot *slot) +{ + struct device_node *child; + + for (child = slot->dn->child; child != NULL; child = child->sibling) { + struct pci_dev *pdev = rpaphp_find_pci_dev(child); + + if (pdev) { + struct rpaphp_pci_func *func; + func = kmalloc(sizeof(struct rpaphp_pci_func), GFP_KERNEL); + if (!func) + return -ENOMEM; + memset(func, 0, sizeof(struct rpaphp_pci_func)); + INIT_LIST_HEAD(&func->sibling); + func->pci_dev = pdev; + list_add_tail(&func->sibling, &slot->dev.pci_funcs); + print_slot_pci_funcs(slot); + } else { + err("%s: dn=%s has no pci_dev\n", + __FUNCTION__, child->full_name); + return -EIO; + } } - return 1; + return 0; } -static struct pci_dev *rpaphp_config_pci_adapter(struct slot *slot) +static int rpaphp_config_pci_adapter(struct slot *slot) { struct pci_bus *pci_bus; - struct pci_dev *dev = NULL; + struct pci_dev *dev; + int rc = -ENODEV; dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name); @@ -256,38 +318,74 @@ static struct pci_dev *rpaphp_config_pci_adapter(struct slot *slot) err("%s: can't find bus structure\n", __FUNCTION__); goto exit; } - - eeh_add_device_early(slot->dn->child); - dev = rpaphp_pci_config_dn(slot->dn, pci_bus); - eeh_add_device_late(dev); + enable_eeh(slot->dn); + dev = rpaphp_pci_config_slot(slot->dn, pci_bus); + if (!dev) { + err("%s: can't find any devices.\n", __FUNCTION__); + goto exit; + } + /* associate corresponding pci_dev */ + rc = init_slot_pci_funcs(slot); + if (rc) + goto exit; + print_slot_pci_funcs(slot); + if (!list_empty(&slot->dev.pci_funcs)) + rc = 0; } else { /* slot is not enabled */ err("slot doesn't have pci_dev structure\n"); - dev = NULL; } - exit: - dbg("Exit %s: pci_dev %s\n", __FUNCTION__, dev ? "found" : "not found"); - return dev; + dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); + return rc; +} + + +static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) +{ + eeh_remove_device(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + struct pci_bus *bus = dev->subordinate; + struct list_head *ln; + if (!bus) + return; + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev) + rpaphp_eeh_remove_bus_device(pdev); + } + + } + return; } int rpaphp_unconfig_pci_adapter(struct slot *slot) { int retval = 0; + struct list_head *ln; dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name); - if (!slot->dev.pci_dev) { - info("%s: no card in slot[%s]\n", __FUNCTION__, slot->name); + if (list_empty(&slot->dev.pci_funcs)) { + err("%s: slot[%s] doesn't have any devices.\n", __FUNCTION__, + slot->name); retval = -EINVAL; goto exit; } - /* remove the device from the pci core */ - eeh_remove_device(slot->dev.pci_dev); - pci_remove_bus_device(slot->dev.pci_dev); - + /* remove the devices from the pci core */ + list_for_each (ln, &slot->dev.pci_funcs) { + struct rpaphp_pci_func *func; + + func = list_entry(ln, struct rpaphp_pci_func, sibling); + if (func->pci_dev) { + rpaphp_eeh_remove_bus_device(func->pci_dev); + pci_remove_bus_device(func->pci_dev); + } + kfree(func); + } + INIT_LIST_HEAD(&slot->dev.pci_funcs); slot->state = NOT_CONFIGURED; - info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, + info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, slot->name); exit: dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval); @@ -303,7 +401,7 @@ static int setup_pci_hotplug_slot_info(struct slot *slot) &slot->hotplug_slot->info-> adapter_status); if (slot->hotplug_slot->info->adapter_status == NOT_VALID) { - dbg("%s: NOT_VALID: skip dn->full_name=%s\n", + err("%s: NOT_VALID: skip dn->full_name=%s\n", __FUNCTION__, slot->dn->full_name); return -1; } @@ -314,35 +412,41 @@ static int setup_pci_slot(struct slot *slot) { slot->bridge = rpaphp_find_bridge_pdev(slot); if (!slot->bridge) { /* slot being added doesn't have pci_dev yet */ - dbg("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name); - dealloc_slot_struct(slot); - return 1; + err("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name); + goto exit_rc; } - + dbg("%s set slot->name to %s\n", __FUNCTION__, pci_name(slot->bridge)); strcpy(slot->name, pci_name(slot->bridge)); + /* find slot's pci_dev if it's not empty */ if (slot->hotplug_slot->info->adapter_status == EMPTY) { slot->state = EMPTY; /* slot is empty */ - slot->dev.pci_dev = NULL; } else { /* slot is occupied */ if (!(slot->dn->child)) { /* non-empty slot has to have child */ - err("%s: slot[%s]'s device_node doesn't have child for adapter\n", __FUNCTION__, slot->name); - dealloc_slot_struct(slot); - return 1; + err("%s: slot[%s]'s device_node doesn't have child for adapter\n", + __FUNCTION__, slot->name); + goto exit_rc; } - slot->dev.pci_dev = rpaphp_find_adapter_pdev(slot); - if (slot->dev.pci_dev) { + if (init_slot_pci_funcs(slot)) { + err("%s: init_slot_pci_funcs failed\n", __FUNCTION__); + goto exit_rc; + } + print_slot_pci_funcs(slot); + if (!list_empty(&slot->dev.pci_funcs)) { slot->state = CONFIGURED; - + } else { /* DLPAR add as opposed to - * boot time */ + * boot time */ slot->state = NOT_CONFIGURED; } } return 0; +exit_rc: + dealloc_slot_struct(slot); + return 1; } int register_pci_slot(struct slot *slot) @@ -350,14 +454,17 @@ int register_pci_slot(struct slot *slot) int rc = 1; slot->dev_type = PCI_DEV; + if (slot->type == EMBEDDED) + slot->removable = EMBEDDED; + else + slot->removable = HOTPLUG; + INIT_LIST_HEAD(&slot->dev.pci_funcs); if (setup_pci_hotplug_slot_info(slot)) goto exit_rc; if (setup_pci_slot(slot)) goto exit_rc; rc = register_slot(slot); exit_rc: - if (rc) - dealloc_slot_struct(slot); return rc; } @@ -371,12 +478,12 @@ int rpaphp_enable_pci_slot(struct slot *slot) dbg("%s: sensor state[%d]\n", __FUNCTION__, state); /* if slot is not empty, enable the adapter */ if (state == PRESENT) { - dbg("%s : slot[%s] is occupid.\n", __FUNCTION__, slot->name); - if ((slot->dev.pci_dev = - rpaphp_config_pci_adapter(slot)) != NULL) { + dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); + retval = rpaphp_config_pci_adapter(slot); + if (!retval) { slot->state = CONFIGURED; - dbg("%s: PCI adapter %s in slot[%s] has been configured\n", - __FUNCTION__, pci_name(slot->dev.pci_dev), slot->name); + dbg("%s: PCI devices in slot[%s] has been configured\n", + __FUNCTION__, slot->name); } else { slot->state = NOT_CONFIGURED; dbg("%s: no pci_dev struct for adapter in slot[%s]\n", @@ -392,10 +499,31 @@ int rpaphp_enable_pci_slot(struct slot *slot) retval = -EINVAL; } exit: - if (slot->state != NOT_VALID) - rpaphp_set_attention_status(slot, LED_ON); - else - rpaphp_set_attention_status(slot, LED_ID); dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } + +struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev) +{ + struct list_head *tmp, *n; + struct slot *slot; + + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + struct pci_bus *bus; + struct list_head *ln; + + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + bus = slot->bridge->subordinate; + if (!bus) + return NULL; /* shouldn't be here */ + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev == dev) + return slot->hotplug_slot; + } + } + + return NULL; +} + +EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot); diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 0e952c86f132..b8ba8920f433 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -29,6 +29,35 @@ #include #include "rpaphp.h" +static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf) +{ + u8 value; + int retval = -ENOENT; + struct slot *slot = (struct slot *)php_slot->private; + + if (!slot) + return retval; + + value = slot->removable; + retval = sprintf (buf, "%d\n", value); + return retval; +} + +static struct hotplug_slot_attribute hotplug_slot_attr_removable = { + .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO}, + .show = removable_read_file, +}; + +static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot) +{ + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr); +} + +static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot) +{ + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr); +} + static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) { char *value; @@ -53,7 +82,7 @@ static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot) sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); } -void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) +static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) { sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); } @@ -68,6 +97,17 @@ static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) void dealloc_slot_struct(struct slot *slot) { + struct list_head *ln, *n; + + if (slot->dev_type == PCI_DEV) { + list_for_each_safe (ln, n, &slot->dev.pci_funcs) { + struct rpaphp_pci_func *func; + + func = list_entry(ln, struct rpaphp_pci_func, sibling); + kfree(func); + } + } + kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); @@ -86,7 +126,7 @@ struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_ memset(slot, 0, sizeof (struct slot)); slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL); if (!slot->hotplug_slot) - goto error_slot; + goto error_slot; memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot)); slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL); @@ -95,7 +135,7 @@ struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_ memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); if (!slot->hotplug_slot->name) - goto error_info; + goto error_info; slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); if (!slot->location) goto error_name; @@ -107,9 +147,8 @@ struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_ slot->hotplug_slot->private = slot; slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; slot->hotplug_slot->release = &rpaphp_release_slot; - slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; - - return slot; + + return (slot); error_name: kfree(slot->hotplug_slot->name); @@ -123,15 +162,56 @@ error_nomem: return NULL; } +static int is_registered(struct slot *slot) +{ + struct slot *tmp_slot; + + list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) { + if (!strcmp(tmp_slot->name, slot->name)) + return 1; + } + return 0; +} + +int deregister_slot(struct slot *slot) +{ + int retval = 0; + struct hotplug_slot *php_slot = slot->hotplug_slot; + + dbg("%s - Entry: deregistering slot=%s\n", + __FUNCTION__, slot->name); + + list_del(&slot->rpaphp_slot_list); + + /* remove "phy_location" file */ + rpaphp_sysfs_remove_attr_location(php_slot); + + /* remove "phy_removable" file */ + rpaphp_sysfs_remove_attr_removable(php_slot); + + retval = pci_hp_deregister(php_slot); + if (retval) + err("Problem unregistering a slot %s\n", slot->name); + else + num_slots--; + + dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + return retval; +} + int register_slot(struct slot *slot) { int retval; - char *vio_uni_addr = NULL; - dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", - __FUNCTION__, slot->dn->full_name, slot->index, slot->name, + dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", + __FUNCTION__, slot->dn->full_name, slot->index, slot->name, slot->power_domain, slot->type); - + /* should not try to register the same slot twice */ + if (is_registered(slot)) { /* should't be here */ + err("register_slot: slot[%s] is already registered\n", slot->name); + rpaphp_release_slot(slot->hotplug_slot); + return 1; + } retval = pci_hp_register(slot->hotplug_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); @@ -142,30 +222,40 @@ int register_slot(struct slot *slot) /* create "phy_locatoin" file */ rpaphp_sysfs_add_attr_location(slot->hotplug_slot); + /* create "phy_removable" file */ + rpaphp_sysfs_add_attr_removable(slot->hotplug_slot); + /* add slot to our internal list */ dbg("%s adding slot[%s] to rpaphp_slot_list\n", __FUNCTION__, slot->name); list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); - if (vio_uni_addr) - info("Slot [%s](vio_uni_addr=%s) registered\n", - slot->name, vio_uni_addr); + if (slot->dev_type == VIO_DEV) + info("Slot [%s](VIO location=%s) registered\n", + slot->name, slot->location); else - info("Slot [%s](bus_id=%s) registered\n", - slot->name, pci_name(slot->bridge)); + info("Slot [%s](PCI location=%s) registered\n", + slot->name, slot->location); num_slots++; return 0; } int rpaphp_get_power_status(struct slot *slot, u8 * value) { - int rc; - - rc = rtas_get_power_level(slot->power_domain, (int *) value); - if (rc) - err("failed to get power-level for slot(%s), rc=0x%x\n", - slot->name, rc); + int rc = 0; + + if (slot->type == EMBEDDED) { + dbg("%s set to POWER_ON for EMBEDDED slot %s\n", + __FUNCTION__, slot->location); + *value = POWER_ON; + } + else { + rc = rtas_get_power_level(slot->power_domain, (int *) value); + if (rc) + err("failed to get power-level for slot(%s), rc=0x%x\n", + slot->location, rc); + } return rc; } @@ -177,8 +267,8 @@ int rpaphp_set_attention_status(struct slot *slot, u8 status) /* status: LED_OFF or LED_ON */ rc = rtas_set_indicator(DR_INDICATOR, slot->index, status); if (rc) - err("slot(%s) set attention-status(%d) failed! rc=0x%x\n", - slot->name, status, rc); + err("slot(name=%s location=%s index=0x%x) set attention-status(%d) failed! rc=0x%x\n", + slot->name, slot->location, slot->index, status, rc); return rc; } diff --git a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c index 29d7ca6ba2dc..b9e7abeea0ec 100644 --- a/drivers/pci/hotplug/rpaphp_vio.c +++ b/drivers/pci/hotplug/rpaphp_vio.c @@ -74,12 +74,12 @@ int register_vio_slot(struct device_node *dn) int rc = 1; struct slot *slot = NULL; + name = rpaphp_get_drc_name(dn); + if (!name) + goto exit_rc; index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL); if (!index) goto exit_rc; - name = get_property(dn, "ibm,loc-code", NULL); - if (!name) - goto exit_rc; if (!(slot = alloc_slot_struct(dn, *index, name, 0))) { rc = -ENOMEM; goto exit_rc; -- cgit v1.2.3 From 9406e29e578d178d6cceab61712cd275fa9b6266 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Sun, 13 Jun 2004 21:08:54 -0700 Subject: [PATCH] PCI: Fix PME bits in pci.txt Signed-off-by: Roger Luethi Signed-off-by: Greg Kroah-Hartman --- Documentation/power/pci.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt index 4a15f20ced12..972c7c74b879 100644 --- a/Documentation/power/pci.txt +++ b/Documentation/power/pci.txt @@ -286,11 +286,11 @@ wake event from: +------------------+ | Bit | State | +------------------+ -| 15 | D0 | -| 14 | D1 | +| 11 | D0 | +| 12 | D1 | | 13 | D2 | -| 12 | D3hot | -| 11 | D3cold | +| 14 | D3hot | +| 15 | D3cold | +------------------+ A device can use this to enable wake events: -- cgit v1.2.3 From 4cd5d72a86438e1b014d633c3837f7988c1d3858 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Sun, 13 Jun 2004 21:11:45 -0700 Subject: [PATCH] PCI: Fix off-by-one in pci_enable_wake Fix off-by-one in pci_enable_wake. Bit field location determined by mask, not value. Signed-off-by: Roger Luethi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e3c97d940bab..05daa8cffa90 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -442,7 +442,7 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) pci_read_config_word(dev,pm+PCI_PM_PMC,&value); value &= PCI_PM_CAP_PME_MASK; - value >>= ffs(value); /* First bit of mask */ + value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ /* Check if it can generate PME# from requested state. */ if (!value || !(value & (1 << state))) -- cgit v1.2.3 From 856f546e72cdc8d4fefc458f04f49c0e2405a2d0 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:00:58 +1000 Subject: [XFS] No longer hold the BKL for the entire ioctl operation, its not needed here. SGI Modid: xfs-linux:xfs-kern:173032a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/xfs_file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index aaa74d256889..e8e02f501013 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -53,6 +53,7 @@ #include "xfs_rw.h" #include +#include static struct vm_operations_struct linvfs_file_vm_ops; @@ -440,9 +441,10 @@ linvfs_ioctl( int error; vnode_t *vp = LINVFS_GET_VP(inode); - ASSERT(vp); + unlock_kernel(); VOP_IOCTL(vp, inode, filp, 0, cmd, arg, error); VMODIFY(vp); + lock_kernel(); /* NOTE: some of the ioctl's return positive #'s as a * byte count indicating success, such as @@ -463,9 +465,11 @@ linvfs_ioctl_invis( int error; vnode_t *vp = LINVFS_GET_VP(inode); + unlock_kernel(); ASSERT(vp); VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, arg, error); VMODIFY(vp); + lock_kernel(); /* NOTE: some of the ioctl's return positive #'s as a * byte count indicating success, such as -- cgit v1.2.3 From 1f152c17d5c7608c86b7d344ffcba576e678dd95 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:04:34 +1000 Subject: [XFS] Remove a couple of redundant NULL parent inode pointer checks. SGI Modid: xfs-linux:xfs-kern:173033a Signed-off-by: nathans@sgi.com --- fs/xfs/xfs_inode.c | 3 +-- fs/xfs/xfs_inode.h | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ab973fe102a2..8fc9b6bfc3a3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1140,8 +1140,7 @@ xfs_ialloc( * Call the space management code to pick * the on-disk inode to be allocated. */ - ASSERT(pip != NULL); - error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, + error = xfs_dialloc(tp, pip->i_ino, mode, okalloc, ialloc_context, call_again, &ino); if (error != 0) { return error; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 13abdd55ee90..f606073adf6b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -459,8 +459,8 @@ xfs_inode_t *xfs_bhvtoi(struct bhv_desc *bhvp); * directory, group of new file is set to that of the parent, and * new subdirectory gets S_ISGID bit from parent. */ -#define XFS_INHERIT_GID(pip, vfsp) ((pip) != NULL && \ - (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))) +#define XFS_INHERIT_GID(pip, vfsp) \ + (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) /* * xfs_iget.c prototypes. -- cgit v1.2.3 From 15cb8a4fa7099d1c3990012e2190fc15763c738f Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:09:06 +1000 Subject: [XFS] Fix xfs_lowbit64, it mishandled zero in the high bits. Cleanup a couple of other ffs users, since ffs(0) is apparently undefined on some architectures. SGI Modid: xfs-linux:xfs-kern:173034a Signed-off-by: nathans@sgi.com --- fs/xfs/xfs_bit.c | 24 ++++++++++++++---------- fs/xfs/xfs_rtalloc.c | 6 ++++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index ec12a13d8fac..a20a6c3dc13e 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -154,14 +154,17 @@ int xfs_lowbit64( __uint64_t v) { - int n; - n = ffs((unsigned)v); - if (n <= 0) { - n = ffs(v >> 32); - if (n >= 0) - n+=32; + __uint32_t w = (__uint32_t)v; + int n = 0; + + if (w) { /* lower bits */ + n = ffs(w); + } else { /* upper bits */ + w = (__uint32_t)(v >> 32); + if (w && (n = ffs(w))) + n += 32; } - return (n <= 0) ? n : n-1; + return n - 1; } /* @@ -171,10 +174,11 @@ int xfs_highbit64( __uint64_t v) { - __uint32_t h = v >> 32; + __uint32_t h = (__uint32_t)(v >> 32); + if (h) return xfs_highbit32(h) + 32; - return xfs_highbit32((__u32)v); + return xfs_highbit32((__uint32_t)v); } diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 524d8b211e8d..c130d4259fec 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -100,7 +100,9 @@ STATIC int xfs_lowbit32( __uint32_t v) { - return ffs(v)-1; + if (v) + return ffs(v) - 1; + return -1; } /* -- cgit v1.2.3 From 7ab21cf8e570d89c47dc39c8e0dd7e7b586240d5 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:17:44 +1000 Subject: [XFS] sparse: fix uses of macros before their definitions, etc. SGI Modid: xfs-linux:xfs-kern:173194a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/kmem.h | 2 +- fs/xfs/linux-2.6/xfs_fs_subr.c | 6 +++--- fs/xfs/xfs.h | 1 + fs/xfs/xfs_arch.h | 10 +++++----- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 13e6dcd595c9..f2ff2d61b270 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h @@ -84,7 +84,7 @@ kmem_flags_convert(int flags) { int lflags; -#if DEBUG +#ifdef DEBUG if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) { printk(KERN_WARNING "XFS: memory allocation with wrong flags (%x)\n", flags); diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c index afad97018512..05ebd30ec96f 100644 --- a/fs/xfs/linux-2.6/xfs_fs_subr.c +++ b/fs/xfs/linux-2.6/xfs_fs_subr.c @@ -36,7 +36,7 @@ * Stub for no-op vnode operations that return error status. */ int -fs_noerr() +fs_noerr(void) { return 0; } @@ -45,7 +45,7 @@ fs_noerr() * Operation unsupported under this file system. */ int -fs_nosys() +fs_nosys(void) { return ENOSYS; } @@ -55,7 +55,7 @@ fs_nosys() */ /* ARGSUSED */ void -fs_noval() +fs_noval(void) { } diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index 809bee71dd72..7e276dcaf4dc 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h @@ -35,5 +35,6 @@ #include #include +#include #endif /* __XFS_H__ */ diff --git a/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h index 3d65fe3c6583..3c7a90bfb0e3 100644 --- a/fs/xfs/xfs_arch.h +++ b/fs/xfs/xfs_arch.h @@ -157,11 +157,11 @@ /* does not return a value */ #define INT_MOD_EXPR(reference,arch,code) \ - (void)(((arch) == ARCH_NOCONVERT) \ + (((arch) == ARCH_NOCONVERT) \ ? \ - ((reference) code) \ + (void)((reference) code) \ : \ - ( \ + (void)( \ (reference) = INT_GET((reference),arch) , \ ((reference) code), \ INT_SET(reference, arch, reference) \ @@ -187,10 +187,10 @@ /* does not return a value */ #define INT_COPY(dst,src,arch) \ - (void)( \ + ( \ ((sizeof(dst) == sizeof(src)) || ((arch) == ARCH_NOCONVERT)) \ ? \ - ((dst) = (src)) \ + (void)((dst) = (src)) \ : \ INT_SET(dst, arch, INT_GET(src, arch)) \ ) -- cgit v1.2.3 From f42d4365d8128128523f9303284fe39665a5e207 Mon Sep 17 00:00:00 2001 From: Dean Roehrich Date: Sat, 19 Jun 2004 06:38:53 +1000 Subject: [XFS] Change things to use new version of xfs_dm_init/xfs_dm_exit SGI Modid: xfs-linux:xfs-kern:173206a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/xfs_super.c | 4 ++-- fs/xfs/linux-2.6/xfs_super.h | 9 ++++++++- fs/xfs/xfs_dmapi.h | 13 ++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index e7825df99003..3aa96b8b24b2 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -835,12 +835,12 @@ init_xfs_fs( void ) vn_init(); xfs_init(); uuid_init(); - vfs_initdmapi(); vfs_initquota(); error = register_filesystem(&xfs_fs_type); if (error) goto undo_register; + XFS_DM_INIT(&xfs_fs_type); return 0; undo_register: @@ -857,7 +857,7 @@ STATIC void __exit exit_xfs_fs( void ) { vfs_exitquota(); - vfs_exitdmapi(); + XFS_DM_EXIT(&xfs_fs_type); unregister_filesystem(&xfs_fs_type); xfs_cleanup(); pagebuf_terminate(); diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index 0d3703db3cee..866c7ad75f92 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -92,6 +92,12 @@ extern void xfs_qm_exit(void); # define XFS_TRACE_STRING #endif +#ifdef CONFIG_XFS_DMAPI +# define XFS_DMAPI_STRING "dmapi support, " +#else +# define XFS_DMAPI_STRING +#endif + #ifdef DEBUG # define XFS_DBG_STRING "debug" #else @@ -103,6 +109,7 @@ extern void xfs_qm_exit(void); XFS_REALTIME_STRING \ XFS_BIGFS_STRING \ XFS_TRACE_STRING \ + XFS_DMAPI_STRING \ XFS_DBG_STRING /* DBG must be last */ #define LINVFS_GET_VFS(s) \ diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 53838b48b7d8..c010e3bd1250 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -199,7 +199,14 @@ typedef enum { extern struct bhv_vfsops xfs_dmops; -extern int dmapi_init(void); -extern void dmapi_uninit(void); +#ifdef CONFIG_XFS_DMAPI +void xfs_dm_init(struct file_system_type *); +void xfs_dm_exit(struct file_system_type *); +#define XFS_DM_INIT(fstype) xfs_dm_init(fstype) +#define XFS_DM_EXIT(fstype) xfs_dm_exit(fstype) +#else +#define XFS_DM_INIT() +#define XFS_DM_EXIT() +#endif #endif /* __XFS_DMAPI_H__ */ -- cgit v1.2.3 From ab96a93436e8846cd8626c58a0599886df094638 Mon Sep 17 00:00:00 2001 From: Dean Roehrich Date: Sat, 19 Jun 2004 06:43:35 +1000 Subject: [XFS] Fix non-dmapi build SGI Modid: xfs-linux:xfs-kern:173222a Signed-off-by: nathans@sgi.com --- fs/xfs/xfs_dmapi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index c010e3bd1250..55ae3e67d245 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h @@ -205,8 +205,8 @@ void xfs_dm_exit(struct file_system_type *); #define XFS_DM_INIT(fstype) xfs_dm_init(fstype) #define XFS_DM_EXIT(fstype) xfs_dm_exit(fstype) #else -#define XFS_DM_INIT() -#define XFS_DM_EXIT() +#define XFS_DM_INIT(fstype) +#define XFS_DM_EXIT(fstype) #endif #endif /* __XFS_DMAPI_H__ */ -- cgit v1.2.3 From a5c4ca270c21c30680c6e31ccc38ad33c1168198 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:49:46 +1000 Subject: [XFS] Ensure buffers that map to unwritten extents are only submitted when properly setup. SGI Modid: xfs-linux:xfs-kern:173555a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/xfs_aops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 200159fece50..58f31821d423 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -288,7 +288,7 @@ xfs_probe_unwritten_page( *fsbs = 0; bh = head = page_buffers(page); do { - if (!buffer_unwritten(bh)) + if (!buffer_unwritten(bh) || !buffer_uptodate(bh)) break; if (!xfs_offset_to_map(page, iomapp, p_offset)) break; @@ -769,6 +769,8 @@ xfs_page_state_convert( * extent state conversion transaction on completion. */ if (buffer_unwritten(bh)) { + if (!startio) + continue; if (!iomp) { err = xfs_map_blocks(inode, offset, len, &iomap, BMAPI_READ|BMAPI_IGNSTATE); @@ -778,7 +780,7 @@ xfs_page_state_convert( iomp = xfs_offset_to_map(page, &iomap, p_offset); } - if (iomp && startio) { + if (iomp) { if (!bh->b_end_io) { err = xfs_map_unwritten(inode, page, head, bh, p_offset, @@ -787,7 +789,10 @@ xfs_page_state_convert( if (err) { goto error; } + } else { + set_bit(BH_Lock, &bh->b_state); } + BUG_ON(!buffer_locked(bh)); bh_arr[cnt++] = bh; page_dirty = 0; } -- cgit v1.2.3 From d61692f103a8a7ae163db82c4ea1cea01bd0a7ab Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:52:51 +1000 Subject: [XFS] Sanitise the ACL initialisation macros. SGI Modid: xfs-linux:xfs-kern:173559a Signed-off-by: nathans@sgi.com --- fs/xfs/xfs_acl.h | 26 +++++++++++--------------- fs/xfs/xfs_vfsops.c | 4 ++-- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index ab15998d469f..35e56b7f00ab 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2001-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -61,14 +61,17 @@ typedef struct xfs_acl { #define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) -#ifdef __KERNEL__ - #ifdef CONFIG_XFS_POSIX_ACL struct vattr; struct vnode; struct xfs_inode; +extern struct kmem_zone *xfs_acl_zone; +#define xfs_acl_zone_init(zone, name) \ + (zone) = kmem_zone_init(sizeof(xfs_acl_t), name) +#define xfs_acl_zone_destroy(zone) kmem_cache_destroy(zone) + extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *); extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); extern int xfs_acl_get(struct vnode *, xfs_acl_t *, xfs_acl_t *); @@ -80,17 +83,10 @@ extern int xfs_acl_vset(struct vnode *, void *, size_t, int); extern int xfs_acl_vget(struct vnode *, void *, size_t, int); extern int xfs_acl_vremove(struct vnode *vp, int); -extern struct kmem_zone *xfs_acl_zone; - #define _ACL_TYPE_ACCESS 1 #define _ACL_TYPE_DEFAULT 2 #define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) -#define _ACL_DECL(a) xfs_acl_t *(a) = NULL -#define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP)) -#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)) : 0) -#define _ACL_ZONE_INIT(z,name) ((z) = kmem_zone_init(sizeof(xfs_acl_t), name)) -#define _ACL_ZONE_DESTROY(z) (kmem_cache_destroy(z)) #define _ACL_INHERIT(c,v,d) (xfs_acl_inherit(c,v,d)) #define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0) #define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0) @@ -98,17 +94,19 @@ extern struct kmem_zone *xfs_acl_zone; #define _ACL_DEFAULT_EXISTS xfs_acl_vhasacl_default #define _ACL_XFS_IACCESS(i,m,c) (XFS_IFORK_Q(i) ? xfs_acl_iaccess(i,m,c) : -1) +#define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP)) +#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)) : 0) + #else +#define xfs_acl_zone_init(zone,name) +#define xfs_acl_zone_destroy(zone) #define xfs_acl_vset(v,p,sz,t) (-EOPNOTSUPP) #define xfs_acl_vget(v,p,sz,t) (-EOPNOTSUPP) #define xfs_acl_vremove(v,t) (-EOPNOTSUPP) #define xfs_acl_vhasacl_access(v) (0) #define xfs_acl_vhasacl_default(v) (0) -#define _ACL_DECL(a) ((void)0) #define _ACL_ALLOC(a) (1) /* successfully allocate nothing */ #define _ACL_FREE(a) ((void)0) -#define _ACL_ZONE_INIT(z,name) ((void)0) -#define _ACL_ZONE_DESTROY(z) ((void)0) #define _ACL_INHERIT(c,v,d) (0) #define _ACL_GET_ACCESS(pv,pa) (0) #define _ACL_GET_DEFAULT(pv,pd) (0) @@ -117,6 +115,4 @@ extern struct kmem_zone *xfs_acl_zone; #define _ACL_XFS_IACCESS(i,m,c) (-1) #endif -#endif /* __KERNEL__ */ - #endif /* __XFS_ACL_H__ */ diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index be1188165660..114c53a766a2 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -118,7 +118,7 @@ xfs_init(void) xfs_ili_zone = kmem_zone_init(sizeof(xfs_inode_log_item_t), "xfs_ili"); xfs_chashlist_zone = kmem_zone_init(sizeof(xfs_chashlist_t), "xfs_chashlist"); - _ACL_ZONE_INIT(xfs_acl_zone, "xfs_acl"); + xfs_acl_zone_init(xfs_acl_zone, "xfs_acl"); /* * Allocate global trace buffers. @@ -170,6 +170,7 @@ xfs_cleanup(void) xfs_cleanup_procfs(); xfs_sysctl_unregister(); xfs_refcache_destroy(); + xfs_acl_zone_destroy(xfs_acl_zone); #ifdef XFS_DIR2_TRACE ktrace_free(xfs_dir2_trace_buf); @@ -202,7 +203,6 @@ xfs_cleanup(void) kmem_cache_destroy(xfs_ifork_zone); kmem_cache_destroy(xfs_ili_zone); kmem_cache_destroy(xfs_chashlist_zone); - _ACL_ZONE_DESTROY(xfs_acl_zone); } /* -- cgit v1.2.3 From aa1e420aeba8bc41ccedb2f3253946ec3ca8e55b Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 06:59:11 +1000 Subject: [XFS] Remove unused MAC macros, never needed on Linux. SGI Modid: xfs-linux:xfs-kern:173561a Signed-off-by: nathans@sgi.com --- fs/xfs/xfs_acl.c | 4 ---- fs/xfs/xfs_inode.c | 6 ------ fs/xfs/xfs_vnodeops.c | 16 ---------------- 3 files changed, 26 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index ad9f5de3ae57..b800f8f4e058 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -231,8 +231,6 @@ xfs_acl_vget( int flags = 0; VN_HOLD(vp); - if ((error = _MAC_VACCESS(vp, NULL, VREAD))) - goto out; if(size) { if (!(_ACL_ALLOC(xfs_acl))) { error = ENOMEM; @@ -395,8 +393,6 @@ xfs_acl_allow_set( return ENOTDIR; if (vp->v_vfsp->vfs_flag & VFS_RDONLY) return EROFS; - if ((error = _MAC_VACCESS(vp, NULL, VWRITE))) - return error; va.va_mask = XFS_AT_UID; VOP_GETATTR(vp, &va, 0, NULL, error); if (error) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8fc9b6bfc3a3..8a821fed5a8c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3695,12 +3695,6 @@ xfs_iaccess( mode_t orgmode = mode; struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); - /* - * Verify that the MAC policy allows the requested access. - */ - if ((error = _MAC_XFS_IACCESS(ip, mode, cr))) - return XFS_ERROR(error); - if (mode & S_IWUSR) { umode_t imode = inode->i_mode; diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index ab9b4d18113c..72a04a11cec4 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -411,11 +411,6 @@ xfs_setattr( xfs_ilock(ip, lock_flags); - if (_MAC_XFS_IACCESS(ip, MACWRITE, credp)) { - code = XFS_ERROR(EACCES); - goto error_return; - } - /* boolean: are we the file owner? */ file_owner = (current_fsuid(credp) == ip->i_d.di_uid); @@ -2446,11 +2441,6 @@ xfs_remove( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); } - if ((error = _MAC_XFS_IACCESS(ip, MACWRITE, credp))) { - REMOVE_DEBUG_TRACE(__LINE__); - goto error_return; - } - /* * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. */ @@ -2536,8 +2526,6 @@ xfs_remove( error1: xfs_bmap_cancel(&free_list); cancel_flags |= XFS_TRANS_ABORT; - - error_return: xfs_trans_cancel(tp, cancel_flags); goto std_return; @@ -3105,10 +3093,6 @@ xfs_rmdir( ITRACE(cdp); xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); - if ((error = _MAC_XFS_IACCESS(cdp, MACWRITE, credp))) { - goto error_return; - } - ASSERT(cdp->i_d.di_nlink >= 2); if (cdp->i_d.di_nlink != 2) { error = XFS_ERROR(ENOTEMPTY); -- cgit v1.2.3 From 3527705ea9de9a66c1551fc62b1dcd86a8f77a19 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 07:44:24 +1000 Subject: [XFS] Remove the one remaining, broken use of XFS_WRITEIO_LOG and sanitize direct IO map blocks call. SGI Modid: xfs-linux:xfs-kern:173562a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/xfs_aops.c | 23 +++++------------------ fs/xfs/xfs_mount.h | 6 +----- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 58f31821d423..5e391eb50406 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -172,28 +172,15 @@ xfs_map_blocks( struct inode *inode, loff_t offset, ssize_t count, - xfs_iomap_t *iomapp, + xfs_iomap_t *mapp, int flags) { vnode_t *vp = LINVFS_GET_VP(inode); - int error, niomaps = 1; - - if (((flags & (BMAPI_DIRECT|BMAPI_SYNC)) == BMAPI_DIRECT) && - (offset >= i_size_read(inode))) - count = max_t(ssize_t, count, XFS_WRITE_IO_LOG); -retry: - VOP_BMAP(vp, offset, count, flags, iomapp, &niomaps, error); - if ((error == EAGAIN) || (error == EIO)) - return -error; - if (unlikely((flags & (BMAPI_WRITE|BMAPI_DIRECT)) == - (BMAPI_WRITE|BMAPI_DIRECT) && niomaps && - (iomapp->iomap_flags & IOMAP_DELAY))) { - flags = BMAPI_ALLOCATE; - goto retry; - } - if (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) { + int error, nmaps = 1; + + VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error); + if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) VMODIFY(vp); - } return -error; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 1ee2bbf6362a..f51ec12968d0 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -424,10 +424,6 @@ typedef struct xfs_mount { */ #define XFS_READIO_LOG_LARGE 16 #define XFS_WRITEIO_LOG_LARGE 16 -/* - * Default allocation size - */ -#define XFS_WRITE_IO_LOG 16 /* * Max and min values for UIO and mount-option defined I/O sizes; -- cgit v1.2.3 From ff3717bb3082df56f12a486e2a6db6513da09414 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 07:47:58 +1000 Subject: [XFS] Fix flags argument to xfs_incore call on attr removal. SGI Modid: xfs-linux:xfs-kern:173563a Signed-off-by: nathans@sgi.com --- fs/xfs/xfs_attr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 8eb321eec512..f1ccb5890665 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -2149,8 +2149,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) /* * If the "remote" value is in the cache, remove it. */ - /* bp = incore(mp->m_dev, dblkno, blkcnt, 1); */ - bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, 1); + bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, + XFS_INCORE_TRYLOCK); if (bp) { XFS_BUF_STALE(bp); XFS_BUF_UNDELAYWRITE(bp); -- cgit v1.2.3 From 86634e478c487331fd8b488068dc43643319f4eb Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 07:53:10 +1000 Subject: [XFS] Fix a race condition in the undo-delayed-write buffer routine. SGI Modid: xfs-linux:xfs-kern:173564a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/xfs_buf.c | 13 +++++++++++-- fs/xfs/linux-2.6/xfs_buf.h | 20 ++++---------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index b6dc7d9dca7d..cf0a94dcff54 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1566,11 +1566,20 @@ void pagebuf_delwri_dequeue( xfs_buf_t *pb) { - PB_TRACE(pb, "delwri_uq", 0); + int dequeued = 0; + spin_lock(&pbd_delwrite_lock); - list_del_init(&pb->pb_list); + if ((pb->pb_flags & PBF_DELWRI) && !list_empty(&pb->pb_list)) { + list_del_init(&pb->pb_list); + dequeued = 1; + } pb->pb_flags &= ~PBF_DELWRI; spin_unlock(&pbd_delwrite_lock); + + if (dequeued) + pagebuf_rele(pb); + + PB_TRACE(pb, "delwri_dq", (long)dequeued); } STATIC void diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index f97e6c0cd597..7bebfd65a7fc 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -347,27 +347,15 @@ extern void pagebuf_trace( #define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE) #define XFS_BUF_SUPER_STALE(x) do { \ XFS_BUF_STALE(x); \ - xfs_buf_undelay(x); \ + pagebuf_delwri_dequeue(x); \ XFS_BUF_DONE(x); \ } while (0) #define XFS_BUF_MANAGE PBF_FS_MANAGED #define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_FS_MANAGED) -static inline void xfs_buf_undelay(xfs_buf_t *pb) -{ - if (pb->pb_flags & PBF_DELWRI) { - if (pb->pb_list.next != &pb->pb_list) { - pagebuf_delwri_dequeue(pb); - pagebuf_rele(pb); - } else { - pb->pb_flags &= ~PBF_DELWRI; - } - } -} - #define XFS_BUF_DELAYWRITE(x) ((x)->pb_flags |= PBF_DELWRI) -#define XFS_BUF_UNDELAYWRITE(x) xfs_buf_undelay(x) +#define XFS_BUF_UNDELAYWRITE(x) pagebuf_delwri_dequeue(x) #define XFS_BUF_ISDELAYWRITE(x) ((x)->pb_flags & PBF_DELWRI) #define XFS_BUF_ERROR(x,no) pagebuf_ioerror(x,no) @@ -500,7 +488,7 @@ static inline int xfs_bawrite(void *mp, xfs_buf_t *bp) { bp->pb_fspriv3 = mp; bp->pb_strat = xfs_bdstrat_cb; - xfs_buf_undelay(bp); + pagebuf_delwri_dequeue(bp); return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | _PBF_RUN_QUEUES); } @@ -540,7 +528,7 @@ static inline int XFS_bwrite(xfs_buf_t *pb) if (!iowait) pb->pb_flags |= _PBF_RUN_QUEUES; - xfs_buf_undelay(pb); + pagebuf_delwri_dequeue(pb); pagebuf_iostrategy(pb); if (iowait) { error = pagebuf_iowait(pb); -- cgit v1.2.3 From 1353142207d320241aa932007b58051b21100480 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 08:05:32 +1000 Subject: [XFS] Fix up memory allocators to be more resilient. SGI Modid: xfs-linux:xfs-kern:173571a Signed-off-by: nathans@sgi.com --- fs/xfs/Makefile | 1 + fs/xfs/linux-2.6/kmem.c | 126 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/linux-2.6/kmem.h | 114 +++++++++++++-------------------------- fs/xfs/linux-2.6/xfs_buf.c | 43 +++++++++------ fs/xfs/linux-2.6/xfs_super.c | 29 +++++++--- 5 files changed, 216 insertions(+), 97 deletions(-) create mode 100644 fs/xfs/linux-2.6/kmem.c diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 3795a5c8e8ff..09f81b3793e1 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -126,6 +126,7 @@ xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o # Objects in linux-2.6/ xfs-y += $(addprefix linux-2.6/, \ + kmem.o \ xfs_aops.o \ xfs_buf.o \ xfs_file.o \ diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c new file mode 100644 index 000000000000..f40ce91de6f1 --- /dev/null +++ b/fs/xfs/linux-2.6/kmem.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include + +#include "time.h" +#include "kmem.h" + +#define MAX_VMALLOCS 6 +#define MAX_SLAB_SIZE 0x20000 + + +void * +kmem_alloc(size_t size, int flags) +{ + int retries = 0, lflags = kmem_flags_convert(flags); + void *ptr; + + do { + if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS) + ptr = kmalloc(size, lflags); + else + ptr = __vmalloc(size, lflags, PAGE_KERNEL); + if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP))) + return ptr; + if (!(++retries % 100)) + printk(KERN_ERR "possible deadlock in %s (mode:0x%x)\n", + __FUNCTION__, lflags); + } while (1); +} + +void * +kmem_zalloc(size_t size, int flags) +{ + void *ptr; + + ptr = kmem_alloc(size, flags); + if (ptr) + memset((char *)ptr, 0, (int)size); + return ptr; +} + +void +kmem_free(void *ptr, size_t size) +{ + if (((unsigned long)ptr < VMALLOC_START) || + ((unsigned long)ptr >= VMALLOC_END)) { + kfree(ptr); + } else { + vfree(ptr); + } +} + +void * +kmem_realloc(void *ptr, size_t newsize, size_t oldsize, int flags) +{ + void *new; + + new = kmem_alloc(newsize, flags); + if (ptr) { + if (new) + memcpy(new, ptr, + ((oldsize < newsize) ? oldsize : newsize)); + kmem_free(ptr, oldsize); + } + return new; +} + +void * +kmem_zone_alloc(kmem_zone_t *zone, int flags) +{ + int retries = 0, lflags = kmem_flags_convert(flags); + void *ptr; + + do { + ptr = kmem_cache_alloc(zone, lflags); + if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP))) + return ptr; + if (!(++retries % 100)) + printk(KERN_ERR "possible deadlock in %s (mode:0x%x)\n", + __FUNCTION__, lflags); + } while (1); +} + +void * +kmem_zone_zalloc(kmem_zone_t *zone, int flags) +{ + void *ptr; + + ptr = kmem_zone_alloc(zone, flags); + if (ptr) + memset((char *)ptr, 0, kmem_cache_size(zone)); + return ptr; +} diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index f2ff2d61b270..ffe383e14e36 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -32,32 +32,34 @@ #ifndef __XFS_SUPPORT_KMEM_H__ #define __XFS_SUPPORT_KMEM_H__ -#include -#include #include -#include - -/* - * Cutoff point to use vmalloc instead of kmalloc. - */ -#define MAX_SLAB_SIZE 0x20000 +#include +#include /* - * XFS uses slightly different names for these due to the - * IRIX heritage. + * memory management routines */ -#define kmem_zone kmem_cache_s -#define kmem_zone_t kmem_cache_t - #define KM_SLEEP 0x0001 #define KM_NOSLEEP 0x0002 #define KM_NOFS 0x0004 -#define KM_MAYFAIL 0x0005 +#define KM_MAYFAIL 0x0008 + +#define kmem_zone kmem_cache_s +#define kmem_zone_t kmem_cache_t typedef unsigned long xfs_pflags_t; +#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO) #define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS) +#define PFLAGS_SET_NOIO() do { \ + current->flags |= PF_NOIO; \ +} while (0) + +#define PFLAGS_CLEAR_NOIO() do { \ + current->flags &= ~PF_NOIO; \ +} while (0) + /* these could be nested, so we save state */ #define PFLAGS_SET_FSTRANS(STATEP) do { \ *(STATEP) = current->flags; \ @@ -79,8 +81,7 @@ typedef unsigned long xfs_pflags_t; *(NSTATEP) = *(OSTATEP); \ } while (0) -static __inline unsigned int -kmem_flags_convert(int flags) +static __inline unsigned int kmem_flags_convert(int flags) { int lflags; @@ -100,54 +101,9 @@ kmem_flags_convert(int flags) /* avoid recusive callbacks to filesystem during transactions */ if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS)) lflags &= ~__GFP_FS; - - if (!(flags & KM_MAYFAIL)) - lflags |= __GFP_NOFAIL; - } - - return lflags; -} - -static __inline void * -kmem_alloc(size_t size, int flags) -{ - if (unlikely(MAX_SLAB_SIZE < size)) - /* Avoid doing filesystem sensitive stuff to get this */ - return __vmalloc(size, kmem_flags_convert(flags), PAGE_KERNEL); - return kmalloc(size, kmem_flags_convert(flags)); -} - -static __inline void * -kmem_zalloc(size_t size, int flags) -{ - void *ptr = kmem_alloc(size, flags); - if (likely(ptr != NULL)) - memset(ptr, 0, size); - return ptr; -} - -static __inline void -kmem_free(void *ptr, size_t size) -{ - if (unlikely((unsigned long)ptr < VMALLOC_START || - (unsigned long)ptr >= VMALLOC_END)) - kfree(ptr); - else - vfree(ptr); -} - -static __inline void * -kmem_realloc(void *ptr, size_t newsize, size_t oldsize, int flags) -{ - void *new = kmem_alloc(newsize, flags); - - if (likely(ptr != NULL)) { - if (likely(new != NULL)) - memcpy(new, ptr, min(oldsize, newsize)); - kmem_free(ptr, oldsize); } - - return new; + + return lflags; } static __inline kmem_zone_t * @@ -156,27 +112,33 @@ kmem_zone_init(int size, char *zone_name) return kmem_cache_create(zone_name, size, 0, 0, NULL, NULL); } -static __inline void * -kmem_zone_alloc(kmem_zone_t *zone, int flags) +static __inline void +kmem_zone_free(kmem_zone_t *zone, void *ptr) { - return kmem_cache_alloc(zone, kmem_flags_convert(flags)); + kmem_cache_free(zone, ptr); } -static __inline void * -kmem_zone_zalloc(kmem_zone_t *zone, int flags) +static __inline void +kmem_zone_destroy(kmem_zone_t *zone) { - void *ptr = kmem_zone_alloc(zone, flags); - if (likely(ptr != NULL)) - memset(ptr, 0, kmem_cache_size(zone)); - return ptr; + if (zone && kmem_cache_destroy(zone)) + BUG(); } -static __inline void -kmem_zone_free(kmem_zone_t *zone, void *ptr) +static __inline int +kmem_zone_shrink(kmem_zone_t *zone) { - kmem_cache_free(zone, ptr); + return kmem_cache_shrink(zone); } +extern void *kmem_zone_zalloc(kmem_zone_t *, int); +extern void *kmem_zone_alloc(kmem_zone_t *, int); + +extern void *kmem_alloc(size_t, int); +extern void *kmem_realloc(void *, size_t, size_t, int); +extern void *kmem_zalloc(size_t, int); +extern void kmem_free(void *, size_t); + typedef struct shrinker *kmem_shaker_t; typedef int (*kmem_shake_func_t)(int, unsigned int); diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index cf0a94dcff54..c05024715231 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -65,7 +65,8 @@ */ STATIC kmem_cache_t *pagebuf_cache; -STATIC void pagebuf_daemon_wakeup(void); +STATIC kmem_shaker_t pagebuf_shake; +STATIC int pagebuf_daemon_wakeup(int, unsigned int); STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); STATIC struct workqueue_struct *pagebuf_logio_workqueue; STATIC struct workqueue_struct *pagebuf_dataio_workqueue; @@ -384,13 +385,13 @@ _pagebuf_lookup_pages( * But until all the XFS lowlevel code is revamped to * handle buffer allocation failures we can't do much. */ - if (!(++retries % 100)) { - printk(KERN_ERR "possibly deadlocking in %s\n", - __FUNCTION__); - } + if (!(++retries % 100)) + printk(KERN_ERR + "possible deadlock in %s (mode:0x%x)\n", + __FUNCTION__, gfp_mask); XFS_STATS_INC(pb_page_retries); - pagebuf_daemon_wakeup(); + pagebuf_daemon_wakeup(0, gfp_mask); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(10); goto retry; @@ -1595,12 +1596,16 @@ STATIC struct task_struct *pagebuf_daemon_task; STATIC int pagebuf_daemon_active; STATIC int force_flush; -STATIC void -pagebuf_daemon_wakeup(void) + +STATIC int +pagebuf_daemon_wakeup( + int priority, + unsigned int mask) { force_flush = 1; barrier(); wake_up_process(pagebuf_daemon_task); + return 0; } STATIC int @@ -1784,21 +1789,28 @@ pagebuf_init(void) pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (pagebuf_cache == NULL) { - printk("pagebuf: couldn't init pagebuf cache\n"); + printk("XFS: couldn't init xfs_buf_t cache\n"); pagebuf_terminate(); return -ENOMEM; } - for (i = 0; i < NHASH; i++) { - spin_lock_init(&pbhash[i].pb_hash_lock); - INIT_LIST_HEAD(&pbhash[i].pb_hash); - } - #ifdef PAGEBUF_TRACE pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); #endif pagebuf_daemon_start(); + + pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup); + if (pagebuf_shake == NULL) { + pagebuf_terminate(); + return -ENOMEM; + } + + for (i = 0; i < NHASH; i++) { + spin_lock_init(&pbhash[i].pb_hash_lock); + INIT_LIST_HEAD(&pbhash[i].pb_hash); + } + return 0; } @@ -1817,5 +1829,6 @@ pagebuf_terminate(void) ktrace_free(pagebuf_trace_buf); #endif - kmem_cache_destroy(pagebuf_cache); + kmem_zone_destroy(pagebuf_cache); + kmem_shake_deregister(pagebuf_shake); } diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 3aa96b8b24b2..2ec34c55e205 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -76,7 +76,8 @@ STATIC struct quotactl_ops linvfs_qops; STATIC struct super_operations linvfs_sops; STATIC struct export_operations linvfs_export_ops; -STATIC kmem_cache_t * linvfs_inode_cachep; +STATIC kmem_zone_t *linvfs_inode_zone; +STATIC kmem_shaker_t xfs_inode_shaker; STATIC struct xfs_mount_args * xfs_args_allocate( @@ -289,7 +290,7 @@ linvfs_alloc_inode( { vnode_t *vp; - vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_cachep, + vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_zone, kmem_flags_convert(KM_SLEEP)); if (!vp) return NULL; @@ -300,7 +301,20 @@ STATIC void linvfs_destroy_inode( struct inode *inode) { - kmem_cache_free(linvfs_inode_cachep, LINVFS_GET_VP(inode)); + kmem_cache_free(linvfs_inode_zone, LINVFS_GET_VP(inode)); +} + +int +xfs_inode_shake( + int priority, + unsigned int gfp_mask) +{ + int pages; + + + pages = kmem_zone_shrink(linvfs_inode_zone); + pages += kmem_zone_shrink(xfs_inode_zone); + return pages; } STATIC void @@ -319,12 +333,12 @@ init_once( STATIC int init_inodecache( void ) { - linvfs_inode_cachep = kmem_cache_create("linvfs_icache", + linvfs_inode_zone = kmem_cache_create("linvfs_icache", sizeof(vnode_t), 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once, NULL); - if (linvfs_inode_cachep == NULL) + if (linvfs_inode_zone == NULL) return -ENOMEM; return 0; } @@ -332,7 +346,7 @@ init_inodecache( void ) STATIC void destroy_inodecache( void ) { - if (kmem_cache_destroy(linvfs_inode_cachep)) + if (kmem_cache_destroy(linvfs_inode_zone)) printk(KERN_WARNING "%s: cache still in use!\n", __FUNCTION__); } @@ -837,6 +851,8 @@ init_xfs_fs( void ) uuid_init(); vfs_initquota(); + xfs_inode_shaker = kmem_shake_register(xfs_inode_shake); + error = register_filesystem(&xfs_fs_type); if (error) goto undo_register; @@ -859,6 +875,7 @@ exit_xfs_fs( void ) vfs_exitquota(); XFS_DM_EXIT(&xfs_fs_type); unregister_filesystem(&xfs_fs_type); + kmem_shake_deregister(xfs_inode_shaker); xfs_cleanup(); pagebuf_terminate(); destroy_inodecache(); -- cgit v1.2.3 From 9e8f2b7c3d8803f1c98e44587e530c2ef87530f1 Mon Sep 17 00:00:00 2001 From: Russell Cattelan Date: Sat, 19 Jun 2004 09:38:36 +1000 Subject: [XFS] Fix for NFS+XFS data corruption problem. See http://oss.sgi.com/bugzilla/show_bug.cgi?id=198 for full details. SGI Modid: xfs-linux:xfs-kern:173598a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/xfs_aops.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 5e391eb50406..7122efdba491 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -668,13 +668,12 @@ xfs_cluster_write( xfs_iomap_t *iomapp, struct writeback_control *wbc, int startio, - int all_bh) + int all_bh, + pgoff_t tlast) { - pgoff_t tlast; struct page *page; - tlast = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT; - for (; tindex < tlast; tindex++) { + for (; tindex <= tlast; tindex++) { page = xfs_probe_delalloc_page(inode, tindex); if (!page) break; @@ -712,17 +711,20 @@ xfs_page_state_convert( { struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; xfs_iomap_t *iomp, iomap; - unsigned long p_offset = 0; - pgoff_t end_index; loff_t offset; - unsigned long long end_offset; + unsigned long p_offset = 0; + __uint64_t end_offset; + pgoff_t end_index, last_index, tlast; int len, err, i, cnt = 0, uptodate = 1; int flags = startio ? 0 : BMAPI_TRYLOCK; int page_dirty = 1; + int delalloc = 0; /* Are we off the end of the file ? */ - end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; + offset = i_size_read(inode); + end_index = offset >> PAGE_CACHE_SHIFT; + last_index = (offset - 1) >> PAGE_CACHE_SHIFT; if (page->index >= end_index) { if ((page->index >= end_index + 1) || !(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) { @@ -789,6 +791,7 @@ xfs_page_state_convert( */ } else if (buffer_delay(bh)) { if (!iomp) { + delalloc = 1; err = xfs_map_blocks(inode, offset, len, &iomap, BMAPI_ALLOCATE | flags); if (err) { @@ -863,8 +866,12 @@ xfs_page_state_convert( xfs_submit_page(page, bh_arr, cnt); if (iomp) { + tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> + PAGE_CACHE_SHIFT; + if (delalloc && (tlast > last_index)) + tlast = last_index; xfs_cluster_write(inode, page->index + 1, iomp, wbc, - startio, unmapped); + startio, unmapped, tlast); } return page_dirty; -- cgit v1.2.3 From 6860067ce44160f9200d7048b82fd97921c4a540 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 19 Jun 2004 10:09:35 +1000 Subject: [XFS] Fix up highmem build and error handling on inode shrink register. SGI Modid: xfs-linux:xfs-kern:173764a Signed-off-by: nathans@sgi.com --- fs/xfs/linux-2.6/kmem.c | 1 + fs/xfs/linux-2.6/xfs_super.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c index f40ce91de6f1..fae717655486 100644 --- a/fs/xfs/linux-2.6/kmem.c +++ b/fs/xfs/linux-2.6/kmem.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "time.h" diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 2ec34c55e205..00818cd70e7d 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -852,6 +852,10 @@ init_xfs_fs( void ) vfs_initquota(); xfs_inode_shaker = kmem_shake_register(xfs_inode_shake); + if (!xfs_inode_shaker) { + error = -ENOMEM; + goto undo_shaker; + } error = register_filesystem(&xfs_fs_type); if (error) @@ -860,6 +864,9 @@ init_xfs_fs( void ) return 0; undo_register: + kmem_shake_deregister(xfs_inode_shaker); + +undo_shaker: pagebuf_terminate(); undo_pagebuf: -- cgit v1.2.3 From 90f346a711f4b8b8254acafcb0b475423a89d0fd Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Jun 2004 20:12:59 +0100 Subject: [PCMCIA] Add Cirrus PD6729 PCMCIA bridge support. Patch from Komuro, cleaned up by Russell King. --- drivers/pcmcia/Kconfig | 7 + drivers/pcmcia/Makefile | 1 + drivers/pcmcia/pd6729.c | 732 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/pcmcia/pd6729.h | 28 ++ 4 files changed, 768 insertions(+) create mode 100644 drivers/pcmcia/pd6729.c create mode 100644 drivers/pcmcia/pd6729.h diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 32ed7a0ce05a..8a4007516ff4 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -69,6 +69,13 @@ config CARDBUS depends on YENTA default y if YENTA +config PD6729 + tristate "Cirrus PD6729 compatible bridge support" + depends on PCMCIA && PCI + help + This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge + device, found in some older laptops and PCMCIA card readers. + config I82092 tristate "i82092 compatible bridge support" depends on PCMCIA && PCI diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 160f73eef3db..caefaebfb777 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -9,6 +9,7 @@ endif obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o obj-$(CONFIG_YENTA) += yenta_socket.o +obj-$(CONFIG_PD6729) += pd6729.o obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_I82092) += i82092.o obj-$(CONFIG_TCIC) += tcic.o diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c new file mode 100644 index 000000000000..e92d63a67c43 --- /dev/null +++ b/drivers/pcmcia/pd6729.c @@ -0,0 +1,732 @@ +/* + * Driver for the Cirrus PD6729 PCI-PCMCIA bridge. + * + * Based on the i82092.c driver. + * + * This software may be used and distributed according to the terms of + * the GNU General Public License, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "pd6729.h" +#include "i82365.h" +#include "cirrus.h" + +MODULE_LICENSE("GPL"); + +#define MAX_SOCKETS 2 + +/* simple helper functions */ +/* External clock time, in nanoseconds. 120 ns = 8.33 MHz */ +#define to_cycles(ns) ((ns)/120) + +static spinlock_t port_lock = SPIN_LOCK_UNLOCKED; + +/* basic value read/write functions */ + +static unsigned char indirect_read(struct pd6729_socket *socket, unsigned short reg) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg += socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + val = inb(port + 1); + spin_unlock_irqrestore(&port_lock, flags); + + return val; +} + +static unsigned short indirect_read16(struct pd6729_socket *socket, unsigned short reg) +{ + unsigned long port; + unsigned short tmp; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + tmp = inb(port + 1); + reg++; + outb(reg, port); + tmp = tmp | (inb(port + 1) << 8); + spin_unlock_irqrestore(&port_lock, flags); + + return tmp; +} + +static void indirect_write(struct pd6729_socket *socket, unsigned short reg, unsigned char value) +{ + unsigned long port; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + outb(value, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +static void indirect_setbit(struct pd6729_socket *socket, unsigned short reg, unsigned char mask) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + val = inb(port + 1); + val |= mask; + outb(reg, port); + outb(val, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +static void indirect_resetbit(struct pd6729_socket *socket, unsigned short reg, unsigned char mask) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + outb(reg, port); + val = inb(port + 1); + val &= ~mask; + outb(reg, port); + outb(val, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +static void indirect_write16(struct pd6729_socket *socket, unsigned short reg, unsigned short value) +{ + unsigned long port; + unsigned char val; + unsigned long flags; + + spin_lock_irqsave(&port_lock, flags); + reg = reg + socket->number * 0x40; + port = socket->io_base; + + outb(reg, port); + val = value & 255; + outb(val, port + 1); + + reg++; + + outb(reg, port); + val = value >> 8; + outb(val, port + 1); + spin_unlock_irqrestore(&port_lock, flags); +} + +/* Interrupt handler functionality */ + +static irqreturn_t pd6729_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + struct pd6729_socket *socket = (struct pd6729_socket *)dev; + int i; + int loopcount = 0; + int handled = 0; + unsigned int events, active = 0; + + while (1) { + loopcount++; + if (loopcount > 20) { + printk(KERN_ERR "pd6729: infinite eventloop in interrupt\n"); + break; + } + + active = 0; + + for (i = 0; i < MAX_SOCKETS; i++) { + unsigned int csc; + + /* card status change register */ + csc = indirect_read(&socket[i], I365_CSC); + if (csc == 0) /* no events on this socket */ + continue; + + handled = 1; + events = 0; + + if (csc & I365_CSC_DETECT) { + events |= SS_DETECT; + dprintk("Card detected in socket %i!\n", i); + } + + if (indirect_read(&socket[i], I365_INTCTL) & I365_PC_IOCARD) { + /* For IO/CARDS, bit 0 means "read the card" */ + events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; + } else { + /* Check for battery/ready events */ + events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0; + events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; + events |= (csc & I365_CSC_READY) ? SS_READY : 0; + } + + if (events) { + pcmcia_parse_events(&socket[i].socket, events); + } + active |= events; + } + + if (active == 0) /* no more events to handle */ + break; + } + return IRQ_RETVAL(handled); +} + +/* socket functions */ + +static void set_bridge_state(struct pd6729_socket *socket) +{ + indirect_write(socket, I365_GBLCTL, 0x00); + indirect_write(socket, I365_GENCTL, 0x00); + + indirect_setbit(socket, I365_INTCTL, 0x08); +} + +static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned int status; + unsigned int data; + struct pd6729_socket *t; + + /* Interface Status Register */ + status = indirect_read(socket, I365_STATUS); + *value = 0; + + if ((status & I365_CS_DETECT) == I365_CS_DETECT) { + *value |= SS_DETECT; + } + + /* IO cards have a different meaning of bits 0,1 */ + /* Also notice the inverse-logic on the bits */ + if (indirect_read(socket, I365_INTCTL) & I365_PC_IOCARD) { + /* IO card */ + if (!(status & I365_CS_STSCHG)) + *value |= SS_STSCHG; + } else { + /* non I/O card */ + if (!(status & I365_CS_BVD1)) + *value |= SS_BATDEAD; + if (!(status & I365_CS_BVD2)) + *value |= SS_BATWARN; + } + + if (status & I365_CS_WRPROT) + *value |= SS_WRPROT; /* card is write protected */ + + if (status & I365_CS_READY) + *value |= SS_READY; /* card is not busy */ + + if (status & I365_CS_POWERON) + *value |= SS_POWERON; /* power is applied to the card */ + + t = (socket->number) ? socket : socket + 1; + indirect_write(t, PD67_EXT_INDEX, PD67_EXTERN_DATA); + data = indirect_read16(t, PD67_EXT_DATA); + *value |= (data & PD67_EXD_VS1(socket->number)) ? 0 : SS_3VCARD; + + return 0; +} + + +static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned char reg, vcc, vpp; + + state->flags = 0; + state->Vcc = 0; + state->Vpp = 0; + state->io_irq = 0; + state->csc_mask = 0; + + /* First the power status of the socket */ + /* PCTRL - Power Control Register */ + reg = indirect_read(socket, I365_POWER); + + if (reg & I365_PWR_AUTO) + state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */ + + if (reg & I365_PWR_OUT) + state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ + + vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; + + if (reg & I365_VCC_5V) { + state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) & + PD67_MC1_VCC_3V) ? 33 : 50; + + if (vpp == I365_VPP1_5V) { + if (state->Vcc == 50) + state->Vpp = 50; + else + state->Vpp = 33; + } + if (vpp == I365_VPP1_12V) + state->Vpp = 120; + } + + /* Now the IO card, RESET flags and IO interrupt */ + /* IGENC, Interrupt and General Control */ + reg = indirect_read(socket, I365_INTCTL); + + if ((reg & I365_PC_RESET) == 0) + state->flags |= SS_RESET; + if (reg & I365_PC_IOCARD) + state->flags |= SS_IOCARD; /* This is an IO card */ + + /* Set the IRQ number */ + state->io_irq = socket->socket.pci_irq; + + /* Card status change */ + /* CSCICR, Card Status Change Interrupt Configuration */ + reg = indirect_read(socket, I365_CSCINT); + + if (reg & I365_CSC_DETECT) + state->csc_mask |= SS_DETECT; /* Card detect is enabled */ + + if (state->flags & SS_IOCARD) {/* IO Cards behave different */ + if (reg & I365_CSC_STSCHG) + state->csc_mask |= SS_STSCHG; + } else { + if (reg & I365_CSC_BVD1) + state->csc_mask |= SS_BATDEAD; + if (reg & I365_CSC_BVD2) + state->csc_mask |= SS_BATWARN; + if (reg & I365_CSC_READY) + state->csc_mask |= SS_READY; + } + + return 0; +} + +static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned char reg; + + /* First, set the global controller options */ + + set_bridge_state(socket); + + /* Values for the IGENC register */ + + reg = 0; + /* The reset bit has "inverse" logic */ + if (!(state->flags & SS_RESET)) + reg = reg | I365_PC_RESET; + if (state->flags & SS_IOCARD) + reg = reg | I365_PC_IOCARD; + + /* IGENC, Interrupt and General Control Register */ + indirect_write(socket, I365_INTCTL, reg); + + /* Power registers */ + + reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */ + + if (state->flags & SS_PWR_AUTO) { + dprintk("Auto power\n"); + reg |= I365_PWR_AUTO; /* automatic power mngmnt */ + } + if (state->flags & SS_OUTPUT_ENA) { + dprintk("Power Enabled\n"); + reg |= I365_PWR_OUT; /* enable power */ + } + + switch (state->Vcc) { + case 0: + break; + case 33: + dprintk("setting voltage to Vcc to 3.3V on socket %i\n", + socket->number); + reg |= I365_VCC_5V; + indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); + break; + case 50: + dprintk("setting voltage to Vcc to 5V on socket %i\n", + socket->number); + reg |= I365_VCC_5V; + indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); + break; + default: + dprintk("pd6729: pd6729_set_socket called with invalid VCC power value: %i\n", + state->Vcc); + return -EINVAL; + } + + switch (state->Vpp) { + case 0: + dprintk("not setting Vpp on socket %i\n", socket->number); + break; + case 33: + case 50: + dprintk("setting Vpp to Vcc for socket %i\n", socket->number); + reg |= I365_VPP1_5V; + break; + case 120: + dprintk("setting Vpp to 12.0\n"); + reg |= I365_VPP1_12V; + break; + default: + dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n", + state->Vpp); + return -EINVAL; + } + + /* only write if changed */ + if (reg != indirect_read(socket, I365_POWER)) + indirect_write(socket, I365_POWER, reg); + + /* Now, specifiy that all interrupts are to be done as PCI interrupts */ + indirect_write(socket, PD67_EXT_INDEX, PD67_EXT_CTL_1); + indirect_write(socket, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ); + + /* Enable specific interrupt events */ + + reg = 0x00; + if (state->csc_mask & SS_DETECT) { + reg |= I365_CSC_DETECT; + } + if (state->flags & SS_IOCARD) { + if (state->csc_mask & SS_STSCHG) + reg |= I365_CSC_STSCHG; + } else { + if (state->csc_mask & SS_BATDEAD) + reg |= I365_CSC_BVD1; + if (state->csc_mask & SS_BATWARN) + reg |= I365_CSC_BVD2; + if (state->csc_mask & SS_READY) + reg |= I365_CSC_READY; + } + reg |= 0x30; /* management IRQ: PCI INTA# = "irq 3" */ + indirect_write(socket, I365_CSCINT, reg); + + reg = indirect_read(socket, I365_INTCTL); + reg |= 0x03; /* card IRQ: PCI INTA# = "irq 3" */ + indirect_write(socket, I365_INTCTL, reg); + + /* now clear the (probably bogus) pending stuff by doing a dummy read */ + (void)indirect_read(socket, I365_CSC); + + return 0; +} + +static int pd6729_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned char map, ioctl; + + map = io->map; + + /* Check error conditions */ + if (map > 1) { + dprintk("pd6729_set_io_map with invalid map"); + return -EINVAL; + } + + /* Turn off the window before changing anything */ + if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map)) + indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map)); + +/* dprintk("set_io_map: Setting range to %x - %x\n", io->start, io->stop);*/ + + /* write the new values */ + indirect_write16(socket, I365_IO(map)+I365_W_START, io->start); + indirect_write16(socket, I365_IO(map)+I365_W_STOP, io->stop); + + ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map); + + if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); + if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); + if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); + + indirect_write(socket, I365_IOCTL, ioctl); + + /* Turn the window back on if needed */ + if (io->flags & MAP_ACTIVE) + indirect_setbit(socket, I365_ADDRWIN, I365_ENA_IO(map)); + + return 0; +} + +static int pd6729_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem) +{ + struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket); + unsigned short base, i; + unsigned char map; + + map = mem->map; + if (map > 4) { + printk("pd6729_set_mem_map: invalid map"); + return -EINVAL; + } + + if ((mem->sys_start > mem->sys_stop) || (mem->speed > 1000)) { + printk("pd6729_set_mem_map: invalid address / speed"); + /* printk("invalid mem map for socket %i : %lx to %lx with a start of %x\n", + sock, mem->sys_start, mem->sys_stop, mem->card_start); */ + return -EINVAL; + } + + /* Turn off the window before changing anything */ + if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_MEM(map)) + indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_MEM(map)); + + /* write the start address */ + base = I365_MEM(map); + i = (mem->sys_start >> 12) & 0x0fff; + if (mem->flags & MAP_16BIT) + i |= I365_MEM_16BIT; + if (mem->flags & MAP_0WS) + i |= I365_MEM_0WS; + indirect_write16(socket, base + I365_W_START, i); + + /* write the stop address */ + + i= (mem->sys_stop >> 12) & 0x0fff; + switch (to_cycles(mem->speed)) { + case 0: + break; + case 1: + i |= I365_MEM_WS0; + break; + case 2: + i |= I365_MEM_WS1; + break; + default: + i |= I365_MEM_WS1 | I365_MEM_WS0; + break; + } + + indirect_write16(socket, base + I365_W_STOP, i); + + /* Take care of high byte */ + indirect_write(socket, PD67_EXT_INDEX, PD67_MEM_PAGE(map)); + indirect_write(socket, PD67_EXT_DATA, mem->sys_start >> 24); + + /* card start */ + + i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff; + if (mem->flags & MAP_WRPROT) + i |= I365_MEM_WRPROT; + if (mem->flags & MAP_ATTRIB) { +/* dprintk("requesting attribute memory for socket %i\n", + socket->number);*/ + i |= I365_MEM_REG; + } else { +/* dprintk("requesting normal memory for socket %i\n", + socket->number);*/ + } + indirect_write16(socket, base + I365_W_OFF, i); + + /* Enable the window if necessary */ + if (mem->flags & MAP_ACTIVE) + indirect_setbit(socket, I365_ADDRWIN, I365_ENA_MEM(map)); + + return 0; +} + +static int pd6729_suspend(struct pcmcia_socket *sock) +{ + return pd6729_set_socket(sock, &dead_socket); +} + +static int pd6729_init(struct pcmcia_socket *sock) +{ + int i; + pccard_io_map io = { 0, 0, 0, 0, 1 }; + pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + + mem.sys_stop = 0x0fff; + pd6729_set_socket(sock, &dead_socket); + for (i = 0; i < 2; i++) { + io.map = i; + pd6729_set_io_map(sock, &io); + } + for (i = 0; i < 5; i++) { + mem.map = i; + pd6729_set_mem_map(sock, &mem); + } + + return 0; +} + + +/* the pccard structure and its functions */ +static struct pccard_operations pd6729_operations = { + .init = pd6729_init, + .suspend = pd6729_suspend, + .get_status = pd6729_get_status, + .get_socket = pd6729_get_socket, + .set_socket = pd6729_set_socket, + .set_io_map = pd6729_set_io_map, + .set_mem_map = pd6729_set_mem_map, +}; + +static int __devinit pd6729_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int i, j, ret; + char configbyte; + struct pd6729_socket *socket; + + socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, GFP_KERNEL); + if (!socket) + return -ENOMEM; + + memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS); + + if ((ret = pci_enable_device(dev))) + goto err_out_free_mem; + + printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge at 0x%lx on irq %d\n", + pci_resource_start(dev, 0), dev->irq); + printk(KERN_INFO "pd6729: configured as a %d socket device.\n", MAX_SOCKETS); + /* Since we have no memory BARs some firmware we may not + have had PCI_COMMAND_MEM enabled, yet the device needs + it. */ + pci_read_config_byte(dev, PCI_COMMAND, &configbyte); + if (!(configbyte & PCI_COMMAND_MEMORY)) { + printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n"); + configbyte |= PCI_COMMAND_MEMORY; + pci_write_config_byte(dev, PCI_COMMAND, configbyte); + } + + ret = pci_request_regions(dev, "pd6729"); + if (ret) { + printk(KERN_INFO "pd6729: pci request region failed.\n"); + goto err_out_disable; + } + + for (i = 0; i < MAX_SOCKETS; i++) { + socket[i].io_base = pci_resource_start(dev, 0); + socket[i].socket.features |= SS_CAP_PCCARD; + socket[i].socket.map_size = 0x1000; + socket[i].socket.irq_mask = 0; + socket[i].socket.pci_irq = dev->irq; + socket[i].socket.owner = THIS_MODULE; + + socket[i].number = i; + + socket[i].socket.ops = &pd6729_operations; + socket[i].socket.dev.dev = &dev->dev; + socket[i].socket.driver_data = &socket[i]; + } + + pci_set_drvdata(dev, socket); + + /* Register the interrupt handler */ + if ((ret = request_irq(dev->irq, pd6729_interrupt, SA_SHIRQ, "pd6729", socket))) { + printk(KERN_ERR "pd6729: Failed to register irq %d, aborting\n", dev->irq); + goto err_out_free_res; + } + + for (i = 0; i < MAX_SOCKETS; i++) { + ret = pcmcia_register_socket(&socket[i].socket); + if (ret) { + printk(KERN_INFO "pd6729: pcmcia_register_socket failed.\n"); + for (j = 0; j < i ; j++) + pcmcia_unregister_socket(&socket[j].socket); + goto err_out_free_res2; + } + } + + return 0; + + err_out_free_res2: + free_irq(dev->irq, socket); + err_out_free_res: + pci_release_regions(dev); + err_out_disable: + pci_disable_device(dev); + + err_out_free_mem: + kfree(socket); + return ret; +} + +static void __devexit pd6729_pci_remove(struct pci_dev *dev) +{ + int i; + struct pd6729_socket *socket = pci_get_drvdata(dev); + + for (i = 0; i < MAX_SOCKETS; i++) + pcmcia_unregister_socket(&socket[i].socket); + + free_irq(dev->irq, socket); + pci_release_regions(dev); + pci_disable_device(dev); + + kfree(socket); +} + +static int pd6729_socket_suspend(struct pci_dev *dev, u32 state) +{ + return pcmcia_socket_dev_suspend(&dev->dev, state); +} + +static int pd6729_socket_resume(struct pci_dev *dev) +{ + return pcmcia_socket_dev_resume(&dev->dev); +} + +static struct pci_device_id pd6729_pci_ids[] = { + { + .vendor = PCI_VENDOR_ID_CIRRUS, + .device = PCI_DEVICE_ID_CIRRUS_6729, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { } +}; +MODULE_DEVICE_TABLE(pci, pd6729_pci_ids); + +static struct pci_driver pd6729_pci_drv = { + .name = "pd6729", + .id_table = pd6729_pci_ids, + .probe = pd6729_pci_probe, + .remove = __devexit_p(pd6729_pci_remove), + .suspend = pd6729_socket_suspend, + .resume = pd6729_socket_resume, +}; + +static int pd6729_module_init(void) +{ + return pci_module_init(&pd6729_pci_drv); +} + +static void pd6729_module_exit(void) +{ + pci_unregister_driver(&pd6729_pci_drv); +} + +module_init(pd6729_module_init); +module_exit(pd6729_module_exit); diff --git a/drivers/pcmcia/pd6729.h b/drivers/pcmcia/pd6729.h new file mode 100644 index 000000000000..9e90520ef6cc --- /dev/null +++ b/drivers/pcmcia/pd6729.h @@ -0,0 +1,28 @@ +#ifndef _INCLUDE_GUARD_PD6729_H_ +#define _INCLUDE_GUARD_PD6729_H_ + +/* Debuging defines */ +#ifdef NOTRACE +#define dprintk(fmt, args...) printk(fmt , ## args) +#else +#define dprintk(fmt, args...) do {} while (0) +#endif + +/* Flags for I365_GENCTL */ +#define I365_DF_VS1 0x40 /* DF-step Voltage Sense */ +#define I365_DF_VS2 0x80 + +/* Fields in PD67_EXTERN_DATA */ +#define PD67_EXD_VS1(s) (0x01 << ((s) << 1)) +#define PD67_EXD_VS2(s) (0x02 << ((s) << 1)) + + + + +struct pd6729_socket { + int number; + unsigned long io_base; /* base io address of the socket */ + struct pcmcia_socket socket; +}; + +#endif -- cgit v1.2.3 From 153fef7f7c79ee51016bd8aff0b4c28c69626523 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Jun 2004 23:17:11 +0100 Subject: [PCMCIA] 02-validatemem Move validate_mem() so we don't recurse. We call this function from the DS_GET_FIRST_TUPLE and DS_VALIDATE_CIS calls, which are the the first two functions which may be called by cardmgr or cardctl which require CIS access. --- drivers/pcmcia/cistpl.c | 1 - drivers/pcmcia/cs_internal.h | 2 +- drivers/pcmcia/ds.c | 2 ++ drivers/pcmcia/rsrc_mgr.c | 21 +++++++++++++++------ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index d975ad35aa52..2892e5adc98c 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -107,7 +107,6 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag pccard_mem_map *mem = &s->cis_mem; if (!(s->features & SS_CAP_STATIC_MAP) && mem->sys_start == 0) { - validate_mem(s); mem->sys_start = 0; if (find_mem_region(&mem->sys_start, s->map_size, s->map_size, 0, "card services", s)) { diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 41b94af0784e..e73efb05c93e 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -180,7 +180,7 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf); int copy_memory(memory_handle_t handle, copy_op_t *req); /* In rsrc_mgr */ -void validate_mem(struct pcmcia_socket *s); +void pcmcia_validate_mem(struct pcmcia_socket *s); struct resource *find_io_region(unsigned long base, int num, unsigned long align, char *name, struct pcmcia_socket *s); int adjust_io_region(struct resource *res, unsigned long r_start, diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index d5d487e79b79..9ecd8233c21e 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -941,6 +941,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = pcmcia_get_configuration_info(s->handle, &buf.config); break; case DS_GET_FIRST_TUPLE: + pcmcia_validate_mem(s->parent); ret = pcmcia_get_first_tuple(s->handle, &buf.tuple); break; case DS_GET_NEXT_TUPLE: @@ -962,6 +963,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = pcmcia_get_status(s->handle, &buf.status); break; case DS_VALIDATE_CIS: + pcmcia_validate_mem(s->parent); ret = pcmcia_validate_cis(s->handle, &buf.cisinfo); break; case DS_SUSPEND_CARD: diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 2e606be988be..d4e0a88f3cb6 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -454,7 +454,7 @@ static u_long inv_probe(resource_map_t *m, struct pcmcia_socket *s) return do_mem_probe(m->base, m->num, s); } -void validate_mem(struct pcmcia_socket *s) +static void validate_mem(struct pcmcia_socket *s) { resource_map_t *m, mm; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; @@ -462,9 +462,6 @@ void validate_mem(struct pcmcia_socket *s) u_long b, i, ok = 0; int force_low = !(s->features & SS_CAP_PAGE_REGS); - if (!probe_mem) - return; - down(&rsrc_sem); /* We do up to four passes through the list */ if (!force_low) { @@ -500,12 +497,12 @@ void validate_mem(struct pcmcia_socket *s) #else /* CONFIG_PCMCIA_PROBE */ -void validate_mem(struct pcmcia_socket *s) +static void validate_mem(struct pcmcia_socket *s) { resource_map_t *m, mm; static int done = 0; - if (probe_mem && done++ == 0) { + if (done++ == 0) { down(&rsrc_sem); for (m = mem_db.next; m != &mem_db; m = mm.next) { mm = *m; @@ -518,6 +515,18 @@ void validate_mem(struct pcmcia_socket *s) #endif /* CONFIG_PCMCIA_PROBE */ +void pcmcia_validate_mem(struct pcmcia_socket *s) +{ + down(&s->skt_sem); + + if (probe_mem && s->state & SOCKET_PRESENT) + validate_mem(s); + + up(&s->skt_sem); +} + +EXPORT_SYMBOL(pcmcia_validate_mem); + struct pcmcia_align_data { unsigned long mask; unsigned long offset; -- cgit v1.2.3 From a99a281c3dbc66a1bf7ebeb0654f2f4efe1f7eab Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Jun 2004 23:26:48 +0100 Subject: [PCMCIA] 03-memwin Eliminate win->base and win->size elements from window_t. window_t contains struct pccard_mem_map, which contains a copy of these (sys_start, sys_stop) in a slightly different form. --- drivers/pcmcia/cs.c | 10 ++++------ include/pcmcia/ss.h | 2 -- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 06462389ac7a..e25cf7f777e4 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -1549,7 +1549,7 @@ int pcmcia_release_window(window_handle_t win) /* Release system memory */ if(!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(win->base, win->size); + release_mem_region(win->ctl.sys_start, win->ctl.sys_stop - win->ctl.sys_start + 1); win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -1871,14 +1871,14 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle win->index = w; win->handle = *handle; win->sock = s; - win->base = req->Base; - win->size = req->Size; + win->ctl.sys_start = req->Base; if (!(s->features & SS_CAP_STATIC_MAP) && - find_mem_region(&win->base, win->size, align, + find_mem_region(&win->ctl.sys_start, req->Size, align, (req->Attributes & WIN_MAP_BELOW_1MB), (*handle)->dev_info, s)) return CS_IN_USE; + win->ctl.sys_stop = win->ctl.sys_start + req->Size - 1; (*handle)->state |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ @@ -1893,8 +1893,6 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle win->ctl.flags |= MAP_16BIT; if (req->Attributes & WIN_USE_WAIT) win->ctl.flags |= MAP_USE_WAIT; - win->ctl.sys_start = win->base; - win->ctl.sys_stop = win->base + win->size-1; win->ctl.card_start = 0; if (s->ops->set_mem_map(s, &win->ctl) != 0) return CS_BAD_ARGS; diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index c45bed63166c..510d75155c57 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -154,8 +154,6 @@ typedef struct window_t { u_short index; client_handle_t handle; struct pcmcia_socket *sock; - u_long base; - u_long size; pccard_mem_map ctl; } window_t; -- cgit v1.2.3 From 9c40518616528e33801f34d6ac22b8b3d7ad4dd6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Jun 2004 23:53:25 +0100 Subject: [PCMCIA] 04-memres Make find_mem_region() return a struct resource. We preserve pccard_mem_map's sys_start and sys_stop elements for the moment since socket drivers are relying on this information for setting up their windows. --- drivers/pcmcia/cistpl.c | 24 +++++++++++++----------- drivers/pcmcia/cs.c | 30 +++++++++++++++++++----------- drivers/pcmcia/cs_internal.h | 2 +- drivers/pcmcia/i82092.c | 4 ++-- drivers/pcmcia/i82365.c | 4 ++-- drivers/pcmcia/pd6729.c | 4 ++-- drivers/pcmcia/rsrc_mgr.c | 18 ++++++++++-------- drivers/pcmcia/tcic.c | 4 ++-- drivers/pcmcia/yenta_socket.c | 4 ++-- include/pcmcia/ss.h | 1 + 10 files changed, 54 insertions(+), 41 deletions(-) diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 2892e5adc98c..b78d41a3c840 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -85,13 +85,15 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ void release_cis_mem(struct pcmcia_socket *s) { - if (s->cis_mem.sys_start != 0) { + if (s->cis_mem.flags & MAP_ACTIVE) { s->cis_mem.flags &= ~MAP_ACTIVE; s->ops->set_mem_map(s, &s->cis_mem); - if (!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(s->cis_mem.sys_start, s->map_size); + if (s->cis_mem.res) { + release_resource(s->cis_mem.res); + kfree(s->cis_mem.res); + s->cis_mem.res = NULL; + } iounmap(s->cis_virt); - s->cis_mem.sys_start = 0; s->cis_virt = NULL; } } @@ -105,16 +107,16 @@ static unsigned char * set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) { pccard_mem_map *mem = &s->cis_mem; - if (!(s->features & SS_CAP_STATIC_MAP) && - mem->sys_start == 0) { - mem->sys_start = 0; - if (find_mem_region(&mem->sys_start, s->map_size, - s->map_size, 0, "card services", s)) { + if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { + mem->res = find_mem_region(0, s->map_size, s->map_size, 0, + "card services", s); + if (mem->res == NULL) { printk(KERN_NOTICE "cs: unable to map card memory!\n"); return NULL; } - mem->sys_stop = mem->sys_start+s->map_size-1; - s->cis_virt = ioremap(mem->sys_start, s->map_size); + mem->sys_start = mem->res->start; + mem->sys_stop = mem->res->end; + s->cis_virt = ioremap(mem->res->start, s->map_size); } mem->card_start = card_offset; mem->flags = flags; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index e25cf7f777e4..44bfe71c70cf 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -1100,8 +1100,8 @@ int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req) if (w == MAX_WIN) return CS_NO_MORE_ITEMS; win = &s->win[w]; - req->Base = win->ctl.sys_start; - req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1; + req->Base = win->ctl.res->start; + req->Size = win->ctl.res->end - win->ctl.res->start + 1; req->AccessSpeed = win->ctl.speed; req->Attributes = 0; if (win->ctl.flags & MAP_ATTRIB) @@ -1548,8 +1548,11 @@ int pcmcia_release_window(window_handle_t win) s->state &= ~SOCKET_WIN_REQ(win->index); /* Release system memory */ - if(!(s->features & SS_CAP_STATIC_MAP)) - release_mem_region(win->ctl.sys_start, win->ctl.sys_stop - win->ctl.sys_start + 1); + if (win->ctl.res) { + release_resource(win->ctl.res); + kfree(win->ctl.res); + win->ctl.res = NULL; + } win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->magic = 0; @@ -1871,14 +1874,19 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle win->index = w; win->handle = *handle; win->sock = s; - win->ctl.sys_start = req->Base; - if (!(s->features & SS_CAP_STATIC_MAP) && - find_mem_region(&win->ctl.sys_start, req->Size, align, - (req->Attributes & WIN_MAP_BELOW_1MB), - (*handle)->dev_info, s)) - return CS_IN_USE; - win->ctl.sys_stop = win->ctl.sys_start + req->Size - 1; + if (!(s->features & SS_CAP_STATIC_MAP)) { + win->ctl.res = find_mem_region(req->Base, req->Size, align, + (req->Attributes & WIN_MAP_BELOW_1MB), + (*handle)->dev_info, s); + if (!win->ctl.res) + return CS_IN_USE; + win->ctl.sys_start = win->ctl.res->start; + win->ctl.sys_stop = win->ctl.res->end; + } else { + win->ctl.sys_start = req->Base; + win->ctl.sys_stop = req->Base + req->Size - 1; + } (*handle)->state |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index e73efb05c93e..88396d87be21 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -185,7 +185,7 @@ struct resource *find_io_region(unsigned long base, int num, unsigned long align char *name, struct pcmcia_socket *s); int adjust_io_region(struct resource *res, unsigned long r_start, unsigned long r_end, struct pcmcia_socket *s); -int find_mem_region(u_long *base, u_long num, u_long align, +struct resource *find_mem_region(u_long base, u_long num, u_long align, int low, char *name, struct pcmcia_socket *s); int try_irq(u_int Attributes, int irq, int specific); void undo_irq(u_int Attributes, int irq); diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 69125c3b3257..3115eb3bc7f1 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -420,12 +420,12 @@ static void set_bridge_state(int sock) static int i82092aa_init(struct pcmcia_socket *sock) { int i; + struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; enter("i82092aa_init"); - mem.sys_stop = 0x0fff; for (i = 0; i < 2; i++) { io.map = i; i82092aa_set_io_map(sock, &io); diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 120569b1f12e..9e20b68aa49b 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1308,10 +1308,10 @@ static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) static int pcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; pcic_set_io_map(s, &io); diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index e92d63a67c43..694e13f43aac 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -563,10 +563,10 @@ static int pd6729_suspend(struct pcmcia_socket *sock) static int pd6729_init(struct pcmcia_socket *sock) { int i; + struct resource res = { .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff }; - mem.sys_stop = 0x0fff; pd6729_set_socket(sock, &dead_socket); for (i = 0; i < 2; i++) { io.map = i; diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index d4e0a88f3cb6..5a246dddb95d 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -303,6 +303,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in s->cis_mem.sys_start = res->start; s->cis_mem.sys_stop = res->end; + s->cis_mem.res = res; s->cis_virt = ioremap(res->start, s->map_size); if (s->cis_virt) { ret = pcmcia_validate_cis(s->clients, info); @@ -313,6 +314,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in } s->cis_mem.sys_start = 0; s->cis_mem.sys_stop = 0; + s->cis_mem.res = NULL; if ((ret != 0) || (info->Chains == 0)) return 0; return 1; @@ -332,6 +334,7 @@ static int checksum(struct pcmcia_socket *s, struct resource *res) map.speed = 0; map.sys_start = res->start; map.sys_stop = res->end; + map.res = res; map.card_start = 0; s->ops->set_mem_map(s, &map); @@ -661,8 +664,8 @@ struct resource *find_io_region(unsigned long base, int num, return res; } -int find_mem_region(u_long *base, u_long num, u_long align, - int low, char *name, struct pcmcia_socket *s) +struct resource *find_mem_region(u_long base, u_long num, u_long align, + int low, char *name, struct pcmcia_socket *s) { struct resource *res = make_resource(0, num, IORESOURCE_MEM, name); struct pcmcia_align_data data; @@ -672,16 +675,16 @@ int find_mem_region(u_long *base, u_long num, u_long align, low = low || !(s->features & SS_CAP_PAGE_REGS); data.mask = align - 1; - data.offset = *base & data.mask; + data.offset = base & data.mask; data.map = &mem_db; for (i = 0; i < 2; i++) { if (low) { max = 0x100000UL; - min = *base < max ? *base : 0; + min = base < max ? base : 0; } else { max = ~0UL; - min = 0x100000UL + *base; + min = 0x100000UL + base; } down(&rsrc_sem); @@ -702,10 +705,9 @@ int find_mem_region(u_long *base, u_long num, u_long align, if (ret != 0) { kfree(res); - } else { - *base = res->start; + res = NULL; } - return ret; + return res; } /*====================================================================== diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 367222170f07..f3b38e96dcdc 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -868,10 +868,10 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m static int tcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; tcic_set_io_map(s, &io); diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 767b2c1a23b4..ae3b05c2b706 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -445,10 +445,10 @@ static void yenta_interrupt_wrapper(unsigned long data) static void yenta_clear_maps(struct yenta_socket *socket) { int i; + struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; - mem.sys_stop = 0x0fff; yenta_set_socket(&socket->socket, &dead_socket); for (i = 0; i < 2; i++) { io.map = i; diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 510d75155c57..4df622f6da47 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -105,6 +105,7 @@ typedef struct pccard_mem_map { u_short speed; u_long sys_start, sys_stop; u_int card_start; + struct resource *res; } pccard_mem_map; typedef struct cb_bridge_map { -- cgit v1.2.3 From 98c3ca287c5be757278459b12b6c02bc5f88a97a Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 21 Jun 2004 00:01:26 +0100 Subject: [PCMCIA] 05-nonbusy When allocating memory and IO resources, do not mark them busy. This allows drivers themselves to claim and mark the regions busy, as they are supposed to. --- drivers/pcmcia/rsrc_mgr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 5a246dddb95d..e45a3ca78f14 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -118,7 +118,7 @@ make_resource(unsigned long b, unsigned long n, int flags, char *name) res->name = name; res->start = b; res->end = b + n - 1; - res->flags = flags | IORESOURCE_BUSY; + res->flags = flags; } return res; } @@ -634,7 +634,7 @@ int adjust_io_region(struct resource *res, unsigned long r_start, struct resource *find_io_region(unsigned long base, int num, unsigned long align, char *name, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_IO, name); + struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id); struct pcmcia_align_data data; unsigned long min = base; int ret; @@ -667,7 +667,7 @@ struct resource *find_io_region(unsigned long base, int num, struct resource *find_mem_region(u_long base, u_long num, u_long align, int low, char *name, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_MEM, name); + struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id); struct pcmcia_align_data data; unsigned long min, max; int ret, i; -- cgit v1.2.3 From 6982faf19d3c3ea74e5d7d45178a72f200f5bc00 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 21 Jun 2004 11:50:47 +0100 Subject: [PCMCIA] 06-ide IDE releases the PCMCIA resource to work around the need to have two conflicting subsystems (IDE and PCMCIA) claim resources. Since PCMCIA no longer marks its resouces busy, this work around must be removed. --- drivers/ide/legacy/ide-cs.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index fb7ae0006249..d40538ab5def 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -327,11 +327,6 @@ void ide_config(dev_link_t *link) CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); - /* deal with brain dead IDE resource management */ - release_region(link->io.BasePort1, link->io.NumPorts1); - if (link->io.NumPorts2) - release_region(link->io.BasePort2, link->io.NumPorts2); - /* disable drive interrupts during IDE probe */ outb(0x02, ctl_base); -- cgit v1.2.3 From 8480f667fc64e9567f994410fa127603b6d4577a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 22 Jun 2004 02:57:06 -0700 Subject: [PATCH] PCI: Fix MSI-X setup msix_capability_init() puts the offset of the MSI-X capability into pos, then uses pos as a loop index to clear the MSI-X vector table, and then tries to use pos as the offset again, which results in writing the MSI-X enable bit off into space. This patch fixes that by adding a new loop index variable and using that to clear the vector table. Signed-off-by: Roland Dreier Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 132af770d38f..35c73b9769e0 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -569,7 +569,7 @@ static int msix_capability_init(struct pci_dev *dev) struct msi_desc *entry; struct msg_address address; struct msg_data data; - int vector = 0, pos, dev_msi_cap; + int vector = 0, pos, dev_msi_cap, i; u32 phys_addr, table_offset; u32 control; u8 bir; @@ -629,12 +629,12 @@ static int msix_capability_init(struct pci_dev *dev) writel(address.hi_address, base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); writel(*(u32*)&data, base + PCI_MSIX_ENTRY_DATA_OFFSET); /* Initialize all entries from 1 up to 0 */ - for (pos = 1; pos < dev_msi_cap; pos++) { - writel(0, base + pos * PCI_MSIX_ENTRY_SIZE + + for (i = 1; i < dev_msi_cap; i++) { + writel(0, base + i * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(0, base + pos * PCI_MSIX_ENTRY_SIZE + + writel(0, base + i * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(0, base + pos * PCI_MSIX_ENTRY_SIZE + + writel(0, base + i * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_DATA_OFFSET); } attach_msi_entry(entry, vector); -- cgit v1.2.3 From 23990425b56fd29f4142d309abfc9b33e16e94d7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 02:57:48 -0700 Subject: [PATCH] PCI: remove duplicate in pci_ids.h Get rid of duplicate entry, one is in the middle of the file with duplicate at the end Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 45d805ddeb9e..31617253cdcb 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2272,6 +2272,3 @@ #define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 #define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 #define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 - -#define PCI_VENDOR_ID_HINT 0x3388 -#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 -- cgit v1.2.3 From c911ba686e4496dc7ece5544d683e31db746aef0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 02:58:27 -0700 Subject: [PATCH] PCI: fix out of order entry in pci_ids.h The last entry in pci_ids.h is out of order, someone wasn't reading the comment to keep it sorted. Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 31617253cdcb..80879404d80c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1769,6 +1769,12 @@ #define PCI_DEVICE_ID_CCD_B00C 0xb00c #define PCI_DEVICE_ID_CCD_B100 0xb100 +#define PCI_VENDOR_ID_MICROGATE 0x13c0 +#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 +#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 +#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 +#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 + #define PCI_VENDOR_ID_3WARE 0x13C1 #define PCI_DEVICE_ID_3WARE_1000 0x1000 #define PCI_DEVICE_ID_3WARE_7000 0x1001 @@ -2266,9 +2272,3 @@ #define PCI_DEVICE_ID_ARK_STING 0xa091 #define PCI_DEVICE_ID_ARK_STINGARK 0xa099 #define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 - -#define PCI_VENDOR_ID_MICROGATE 0x13c0 -#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 -#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 -#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 -#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210 -- cgit v1.2.3 From b0316bada5735d62b854e471f1b1f501625e086f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 02:59:02 -0700 Subject: [PATCH] PCI: add id's for sk98 driver Redoing the sk98 driver to correct pci model. These are (most of) the entries it uses. Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 80879404d80c..e03556883a77 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -967,12 +967,14 @@ #define PCI_VENDOR_ID_3COM 0x10b7 #define PCI_DEVICE_ID_3COM_3C985 0x0001 +#define PCI_DEVICE_ID_3COM_3C940 0x1700 #define PCI_DEVICE_ID_3COM_3C339 0x3390 #define PCI_DEVICE_ID_3COM_3C359 0x3590 #define PCI_DEVICE_ID_3COM_3C590 0x5900 #define PCI_DEVICE_ID_3COM_3C595TX 0x5950 #define PCI_DEVICE_ID_3COM_3C595T4 0x5951 #define PCI_DEVICE_ID_3COM_3C595MII 0x5952 +#define PCI_DEVICE_ID_3COM_3C940B 0x80eb #define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 #define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 #define PCI_DEVICE_ID_3COM_3C905TX 0x9050 @@ -1420,6 +1422,9 @@ #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 +#define PCI_VENDOR_ID_DLINK 0x1186 +#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00 + #define PCI_VENDOR_ID_ARTOP 0x1191 #define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004 #define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 @@ -1735,6 +1740,9 @@ #define PCI_VENDOR_ID_KAWASAKI 0x136b #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 +#define PCI_VENDOR_ID_CNET 0x1371 +#define PCI_DEVICE_ID_CNET_GIGACARD 0x434e + #define PCI_VENDOR_ID_LMC 0x1376 #define PCI_DEVICE_ID_LMC_HSSI 0x0003 #define PCI_DEVICE_ID_LMC_DS3 0x0004 @@ -1919,6 +1927,10 @@ #define PCI_DEVICE_ID_FARSITE_TE1 0x1610 #define PCI_DEVICE_ID_FARSITE_TE1C 0x1612 +#define PCI_VENDOR_ID_LINKSYS 0x1737 +#define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032 +#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 + #define PCI_VENDOR_ID_ALTIMA 0x173b #define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8 #define PCI_DEVICE_ID_ALTIMA_AC1001 0x03e9 -- cgit v1.2.3 From c51fd78e40195663177a27690246658a48f4ff06 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 03:04:54 -0700 Subject: [NET]: rtentry->rt_dev is __user. The device entry in the route ioctl's needs annotation. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/route.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/route.h b/include/linux/route.h index e670dbac51ea..f7ed35d5e653 100644 --- a/include/linux/route.h +++ b/include/linux/route.h @@ -24,7 +24,7 @@ #define _LINUX_ROUTE_H #include - +#include /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ struct rtentry @@ -38,7 +38,7 @@ struct rtentry unsigned long rt_pad3; void *rt_pad4; short rt_metric; /* +1 for binary compatibility! */ - char *rt_dev; /* forcing the device at add */ + char __user *rt_dev; /* forcing the device at add */ unsigned long rt_mtu; /* per route MTU/Window */ #ifndef __KERNEL__ #define rt_mss rt_mtu /* Compatibility :-( */ -- cgit v1.2.3 From 296cf45d024d126cd7976a663ff8533648d97184 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 03:06:32 -0700 Subject: [IPV4]: ip_rt_ioctl argument is user pointer. The function ip_rt_ioctl expects a pointer to a user route structure, so define it that way and cast as appropriate. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/route.h | 2 +- net/ipv4/af_inet.c | 2 +- net/ipv4/fib_frontend.c | 2 +- net/ipv4/ipconfig.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 0e7210e6d194..a5e9c575ea3e 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -129,7 +129,7 @@ extern void ip_rt_send_redirect(struct sk_buff *skb); extern unsigned inet_addr_type(u32 addr); extern void ip_rt_multicast_event(struct in_device *); -extern int ip_rt_ioctl(unsigned int cmd, void *arg); +extern int ip_rt_ioctl(unsigned int cmd, void __user *arg); extern void ip_rt_get_source(u8 *src, struct rtable *rt); extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f6c27fc4f05c..caa8632509b5 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -848,7 +848,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCADDRT: case SIOCDELRT: case SIOCRTMSG: - err = ip_rt_ioctl(cmd, (void *)arg); + err = ip_rt_ioctl(cmd, (void __user *)arg); break; case SIOCDARP: case SIOCGARP: diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index fc4e9f8e6bb7..f5b008a9d7d0 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -235,7 +235,7 @@ e_inval: * Handle IP routing ioctl calls. These are used to manipulate the routing tables */ -int ip_rt_ioctl(unsigned int cmd, void *arg) +int ip_rt_ioctl(unsigned int cmd, void __user *arg) { int err; struct kern_rta rta; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index a5322adb2be8..19833d69dab8 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -272,7 +272,7 @@ static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg) mm_segment_t oldfs = get_fs(); set_fs(get_ds()); - res = devinet_ioctl(cmd, arg); + res = devinet_ioctl(cmd, (struct ifreq __user *) arg); set_fs(oldfs); return res; } @@ -283,7 +283,7 @@ static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg) mm_segment_t oldfs = get_fs(); set_fs(get_ds()); - res = ip_rt_ioctl(cmd, arg); + res = ip_rt_ioctl(cmd, (void __user *) arg); set_fs(oldfs); return res; } -- cgit v1.2.3 From 38194998ffe413468434633b26eb66dd3967f758 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jun 2004 03:07:21 -0700 Subject: [BRIDGE]: Turn off debug message in bridge ioctl. Trivial patch to turn off a debug message. It seems some SNMP daemons just periodically trying to look at MII state. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index cceb01866634..363c73f28b9b 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -403,6 +403,6 @@ int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } - printk(KERN_DEBUG "Bridge does not support ioctl 0x%x\n", cmd); + pr_debug("Bridge does not support ioctl 0x%x\n", cmd); return -EOPNOTSUPP; } -- cgit v1.2.3 From 0d072115e0b16d89f9844d0a03ee5a181e4486ae Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 11:51:20 -0300 Subject: [NET] Move sndmsg_page and sndmsg_off to struct sock Yeah, the poor cousins will use this as well :-) --- include/linux/ip.h | 2 -- include/net/sock.h | 6 +++++- net/core/sock.c | 11 +++++++++++ net/ipv4/ip_output.c | 16 ++++++++-------- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_ipv4.c | 4 ---- net/ipv6/ip6_output.c | 16 ++++++++-------- net/ipv6/tcp_ipv6.c | 4 ---- 8 files changed, 34 insertions(+), 29 deletions(-) diff --git a/include/linux/ip.h b/include/linux/ip.h index ab799b48b485..12d504ef8df0 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h @@ -129,8 +129,6 @@ struct inet_opt { int mc_index; /* Multicast device index */ __u32 mc_addr; struct ip_mc_socklist *mc_list; /* Group array */ - struct page *sndmsg_page; /* Cached page for sendmsg */ - u32 sndmsg_off; /* Cached offset for sendmsg */ /* * Following members are used to retain the infomation to build * an ip header on each ip fragmentation while the socket is corked. diff --git a/include/net/sock.h b/include/net/sock.h index 0398823e18ed..fe293dc84da9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -167,6 +167,8 @@ struct sock_common { * @sk_socket - Identd and reporting IO signals * @sk_user_data - RPC layer private data * @sk_owner - module that owns this socket + * @sk_sndmsg_page - cached page for sendmsg + * @sk_sndmsg_off - cached offset for sendmsg * @sk_send_head - front of stuff to transmit * @sk_write_pending - a write to stream socket waits to start * @sk_queue_shrunk - write queue has been shrunk recently @@ -249,8 +251,10 @@ struct sock { struct timeval sk_stamp; struct socket *sk_socket; void *sk_user_data; - struct sk_buff *sk_send_head; struct module *sk_owner; + struct page *sk_sndmsg_page; + __u32 sk_sndmsg_off; + struct sk_buff *sk_send_head; int sk_write_pending; void *sk_security; __u8 sk_queue_shrunk; diff --git a/net/core/sock.c b/net/core/sock.c index 992c2ab34c7a..089972f623ab 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -650,6 +650,14 @@ void sk_free(struct sock *sk) printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); + /* + * If sendmsg cached page exists, toss it. + */ + if (sk->sk_sndmsg_page) { + __free_page(sk->sk_sndmsg_page); + sk->sk_sndmsg_page = NULL; + } + security_sk_free(sk); kmem_cache_free(sk->sk_slab, sk); module_put(owner); @@ -1175,6 +1183,9 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_error_report = sock_def_error_report; sk->sk_destruct = sock_def_destruct; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; + sk->sk_peercred.pid = 0; sk->sk_peercred.uid = -1; sk->sk_peercred.gid = -1; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 34a4a3feccb7..2e04043e0e2d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -766,8 +766,8 @@ int ip_append_data(struct sock *sk, inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst); inet->cork.rt = rt; inet->cork.length = 0; - inet->sndmsg_page = NULL; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; if ((exthdrlen = rt->u.dst.header_len) != 0) { length += exthdrlen; transhdrlen += exthdrlen; @@ -915,8 +915,8 @@ alloc_new_skb: } else { int i = skb_shinfo(skb)->nr_frags; skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; - struct page *page = inet->sndmsg_page; - int off = inet->sndmsg_off; + struct page *page = sk->sk_sndmsg_page; + int off = sk->sk_sndmsg_off; unsigned int left; if (page && (left = PAGE_SIZE - off) > 0) { @@ -928,7 +928,7 @@ alloc_new_skb: goto error; } get_page(page); - skb_fill_page_desc(skb, i, page, inet->sndmsg_off, 0); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); frag = &skb_shinfo(skb)->frags[i]; } } else if (i < MAX_SKB_FRAGS) { @@ -939,8 +939,8 @@ alloc_new_skb: err = -ENOMEM; goto error; } - inet->sndmsg_page = page; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = page; + sk->sk_sndmsg_off = 0; skb_fill_page_desc(skb, i, page, 0, 0); frag = &skb_shinfo(skb)->frags[i]; @@ -954,7 +954,7 @@ alloc_new_skb: err = -EFAULT; goto error; } - inet->sndmsg_off += copy; + sk->sk_sndmsg_off += copy; frag->size += copy; skb->len += copy; skb->data_len += copy; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index bc1394f67919..34afc2863953 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -816,8 +816,8 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, return res; } -#define TCP_PAGE(sk) (inet_sk(sk)->sndmsg_page) -#define TCP_OFF(sk) (inet_sk(sk)->sndmsg_off) +#define TCP_PAGE(sk) (sk->sk_sndmsg_page) +#define TCP_OFF(sk) (sk->sk_sndmsg_off) static inline int select_size(struct sock *sk, struct tcp_opt *tp) { diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a487ef203e52..956a9c44af40 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2113,10 +2113,6 @@ static int tcp_v4_destroy_sock(struct sock *sk) if (tp->bind_hash) tcp_put_port(sk); - /* If sendmsg cached page exists, toss it. */ - if (inet_sk(sk)->sndmsg_page) - __free_page(inet_sk(sk)->sndmsg_page); - atomic_dec(&tcp_sockets_allocated); return 0; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b9e7b26c5c29..c0b2003787b1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -854,8 +854,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse np->cork.hop_limit = hlimit; inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst); inet->cork.length = 0; - inet->sndmsg_page = NULL; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = NULL; + sk->sk_sndmsg_off = 0; exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0); length += exthdrlen; transhdrlen += exthdrlen; @@ -971,8 +971,8 @@ alloc_new_skb: } else { int i = skb_shinfo(skb)->nr_frags; skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; - struct page *page = inet->sndmsg_page; - int off = inet->sndmsg_off; + struct page *page = sk->sk_sndmsg_page; + int off = sk->sk_sndmsg_off; unsigned int left; if (page && (left = PAGE_SIZE - off) > 0) { @@ -984,7 +984,7 @@ alloc_new_skb: goto error; } get_page(page); - skb_fill_page_desc(skb, i, page, inet->sndmsg_off, 0); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); frag = &skb_shinfo(skb)->frags[i]; } } else if(i < MAX_SKB_FRAGS) { @@ -995,8 +995,8 @@ alloc_new_skb: err = -ENOMEM; goto error; } - inet->sndmsg_page = page; - inet->sndmsg_off = 0; + sk->sk_sndmsg_page = page; + sk->sk_sndmsg_off = 0; skb_fill_page_desc(skb, i, page, 0, 0); frag = &skb_shinfo(skb)->frags[i]; @@ -1010,7 +1010,7 @@ alloc_new_skb: err = -EFAULT; goto error; } - inet->sndmsg_off += copy; + sk->sk_sndmsg_off += copy; frag->size += copy; skb->len += copy; skb->data_len += copy; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c41ddd55f958..ed89f41ddb78 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1911,10 +1911,6 @@ static int tcp_v6_destroy_sock(struct sock *sk) if (tcp_sk(sk)->bind_hash) tcp_put_port(sk); - /* If sendmsg cached page exists, toss it. */ - if (inet->sndmsg_page != NULL) - __free_page(inet->sndmsg_page); - atomic_dec(&tcp_sockets_allocated); return inet6_destroy_sock(sk); -- cgit v1.2.3 From 8a99b8d40d08d7d3ddb01e6cb5fbe6d94102543d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 13:32:50 -0300 Subject: [NET] rename struct inet_protocol to net_protocol The poor cousins will also have registration routines, etc. Signed-off-by: Arnaldo Carvalho de Melo --- include/net/protocol.h | 11 +++++------ net/ipv4/af_inet.c | 8 ++++---- net/ipv4/ah4.c | 2 +- net/ipv4/esp4.c | 2 +- net/ipv4/icmp.c | 2 +- net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_input.c | 2 +- net/ipv4/ipcomp.c | 2 +- net/ipv4/ipmr.c | 4 ++-- net/ipv4/protocol.c | 6 +++--- net/ipv4/xfrm4_tunnel.c | 2 +- net/ipv6/sit.c | 2 +- net/sctp/protocol.c | 2 +- 13 files changed, 23 insertions(+), 24 deletions(-) diff --git a/include/net/protocol.h b/include/net/protocol.h index f67327486a9c..357691f6a45f 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -34,8 +34,7 @@ /* This is used to register protocols. */ -struct inet_protocol -{ +struct net_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); int no_policy; @@ -78,15 +77,15 @@ struct inet_protosw { #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ -extern struct inet_protocol *inet_protocol_base; -extern struct inet_protocol *inet_protos[MAX_INET_PROTOS]; +extern struct net_protocol *inet_protocol_base; +extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; #endif -extern int inet_add_protocol(struct inet_protocol *prot, unsigned char num); -extern int inet_del_protocol(struct inet_protocol *prot, unsigned char num); +extern int inet_add_protocol(struct net_protocol *prot, unsigned char num); +extern int inet_del_protocol(struct net_protocol *prot, unsigned char num); extern void inet_register_protosw(struct inet_protosw *p); extern void inet_unregister_protosw(struct inet_protosw *p); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8b14637aa8a2..f6c27fc4f05c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1041,24 +1041,24 @@ void inet_unregister_protosw(struct inet_protosw *p) } #ifdef CONFIG_IP_MULTICAST -static struct inet_protocol igmp_protocol = { +static struct net_protocol igmp_protocol = { .handler = igmp_rcv, }; #endif -static struct inet_protocol tcp_protocol = { +static struct net_protocol tcp_protocol = { .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, .no_policy = 1, }; -static struct inet_protocol udp_protocol = { +static struct net_protocol udp_protocol = { .handler = udp_rcv, .err_handler = udp_err, .no_policy = 1, }; -static struct inet_protocol icmp_protocol = { +static struct net_protocol icmp_protocol = { .handler = icmp_rcv, }; diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 0d62398f71a6..e2cee0788c78 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -340,7 +340,7 @@ static struct xfrm_type ah_type = .output = ah_output }; -static struct inet_protocol ah4_protocol = { +static struct net_protocol ah4_protocol = { .handler = xfrm4_rcv, .err_handler = ah4_err, .no_policy = 1, diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 4755e0dcc90d..4e678c4aabf8 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -594,7 +594,7 @@ static struct xfrm_type esp_type = .output = esp_output }; -static struct inet_protocol esp4_protocol = { +static struct net_protocol esp4_protocol = { .handler = xfrm4_rcv, .err_handler = esp4_err, .no_policy = 1, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index f3b54930368c..efcd23dd37b9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -592,7 +592,7 @@ static void icmp_unreach(struct sk_buff *skb) struct iphdr *iph; struct icmphdr *icmph; int hash, protocol; - struct inet_protocol *ipprot; + struct net_protocol *ipprot; struct sock *raw_sk; u32 info = 0; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4a227f51b2c1..4cd7e8b57624 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1240,7 +1240,7 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev) } -static struct inet_protocol ipgre_protocol = { +static struct net_protocol ipgre_protocol = { .handler = ipgre_rcv, .err_handler = ipgre_err, }; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2f71ed5cfcc9..b72ea4961f15 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -223,7 +223,7 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) int protocol = skb->nh.iph->protocol; int hash; struct sock *raw_sk; - struct inet_protocol *ipprot; + struct net_protocol *ipprot; resubmit: hash = protocol & (MAX_INET_PROTOS - 1); diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index e20c7e43b215..9e04df880d3c 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -405,7 +405,7 @@ static struct xfrm_type ipcomp_type = { .output = ipcomp_output }; -static struct inet_protocol ipcomp4_protocol = { +static struct net_protocol ipcomp4_protocol = { .handler = xfrm4_rcv, .err_handler = ipcomp4_err, .no_policy = 1, diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index a25e56077072..b1fdb95e0d00 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -109,7 +109,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm); -static struct inet_protocol pim_protocol; +static struct net_protocol pim_protocol; static struct timer_list ipmr_expire_timer; @@ -1876,7 +1876,7 @@ static struct file_operations ipmr_mfc_fops = { #endif #ifdef CONFIG_IP_PIMSM_V2 -static struct inet_protocol pim_protocol = { +static struct net_protocol pim_protocol = { .handler = pim_rcv, }; #endif diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index a98eb5250d9a..a8b4bdc27ec4 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -48,14 +48,14 @@ #include #include -struct inet_protocol *inet_protos[MAX_INET_PROTOS]; +struct net_protocol *inet_protos[MAX_INET_PROTOS]; static spinlock_t inet_proto_lock = SPIN_LOCK_UNLOCKED; /* * Add a protocol handler to the hash tables */ -int inet_add_protocol(struct inet_protocol *prot, unsigned char protocol) +int inet_add_protocol(struct net_protocol *prot, unsigned char protocol) { int hash, ret; @@ -77,7 +77,7 @@ int inet_add_protocol(struct inet_protocol *prot, unsigned char protocol) * Remove a protocol from the hash tables. */ -int inet_del_protocol(struct inet_protocol *prot, unsigned char protocol) +int inet_del_protocol(struct net_protocol *prot, unsigned char protocol) { int hash, ret; diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 3c9d4aaa21be..5a7ed8e13d63 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -167,7 +167,7 @@ static struct xfrm_type ipip_type = { .output = ipip_output }; -static struct inet_protocol ipip_protocol = { +static struct net_protocol ipip_protocol = { .handler = ipip_rcv, .err_handler = ipip_err, .no_policy = 1, diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 2fac873fdd3d..67d0361f51d1 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -800,7 +800,7 @@ int __init ipip6_fb_tunnel_init(struct net_device *dev) return 0; } -static struct inet_protocol sit_protocol = { +static struct net_protocol sit_protocol = { .handler = ipip6_rcv, .err_handler = ipip6_err, }; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index fbc958a75ea4..f2abbf48a7d3 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -875,7 +875,7 @@ static struct inet_protosw sctp_stream_protosw = { }; /* Register with IP layer. */ -static struct inet_protocol sctp_protocol = { +static struct net_protocol sctp_protocol = { .handler = sctp_rcv, .err_handler = sctp_v4_err, .no_policy = 1, -- cgit v1.2.3 From fb5f695cabd362c1c5dc8be38593bb389533e20b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 14:04:46 -0300 Subject: [NET] remove fill_page_desc, its just a copy of skb_fill_page_desc Also remove an unused inet_opt variable from ipv6 code. Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/skbuff.h | 12 +++++++----- net/ipv4/tcp.c | 14 ++------------ net/ipv6/tcp_ipv6.c | 1 - 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cc44268a6e83..2d9ee25fb08f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -664,13 +664,15 @@ static inline int skb_pagelen(const struct sk_buff *skb) return len + skb_headlen(skb); } -static inline void skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size) +static inline void skb_fill_page_desc(struct sk_buff *skb, int i, + struct page *page, int off, int size) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - frag->page = page; - frag->page_offset = off; - frag->size = size; - skb_shinfo(skb)->nr_frags = i+1; + + frag->page = page; + frag->page_offset = off; + frag->size = size; + skb_shinfo(skb)->nr_frags = i + 1; } #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 34afc2863953..e9a5843f6902 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -628,16 +628,6 @@ static void tcp_listen_stop (struct sock *sk) BUG_TRAP(!sk->sk_ack_backlog); } -static inline void fill_page_desc(struct sk_buff *skb, int i, - struct page *page, int off, int size) -{ - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - frag->page = page; - frag->page_offset = off; - frag->size = size; - skb_shinfo(skb)->nr_frags = i + 1; -} - static inline void tcp_mark_push(struct tcp_opt *tp, struct sk_buff *skb) { TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; @@ -740,7 +730,7 @@ new_segment: skb_shinfo(skb)->frags[i - 1].size += copy; } else if (i < MAX_SKB_FRAGS) { get_page(page); - fill_page_desc(skb, i, page, offset, copy); + skb_fill_page_desc(skb, i, page, offset, copy); } else { tcp_mark_push(tp, skb); goto new_segment; @@ -980,7 +970,7 @@ new_segment: skb_shinfo(skb)->frags[i - 1].size += copy; } else { - fill_page_desc(skb, i, page, off, copy); + skb_fill_page_desc(skb, i, page, off, copy); if (TCP_PAGE(sk)) { get_page(page); } else if (off + copy < PAGE_SIZE) { diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ed89f41ddb78..db58adc22c59 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1894,7 +1894,6 @@ static int tcp_v6_init_sock(struct sock *sk) static int tcp_v6_destroy_sock(struct sock *sk) { struct tcp_opt *tp = tcp_sk(sk); - struct inet_opt *inet = inet_sk(sk); tcp_clear_xmit_timers(sk); -- cgit v1.2.3 From 3ac2a2d46ecd8c21f58ed2c67995d6a6c0e65806 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Jun 2004 19:20:40 -0300 Subject: [NET] Generalise tcp memory pressure handling Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 34 +++++++++++- include/net/tcp.h | 32 ++--------- net/core/stream.c | 97 +++++++++++++++++++++++++++++++++ net/ipv4/proc.c | 4 +- net/ipv4/sysctl_net_ipv4.c | 12 ++--- net/ipv4/tcp.c | 131 ++++++--------------------------------------- net/ipv4/tcp_input.c | 34 ++++++------ net/ipv4/tcp_ipv4.c | 45 ++++++++-------- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 2 +- net/ipv4/tcp_timer.c | 12 ++--- net/ipv6/tcp_ipv6.c | 8 +-- 12 files changed, 210 insertions(+), 203 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index fe293dc84da9..23f72934b180 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -491,10 +491,11 @@ extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); extern int sk_stream_wait_memory(struct sock *sk, long *timeo_p); extern void sk_stream_wait_close(struct sock *sk, long timeo_p); extern int sk_stream_error(struct sock *sk, int flags, int err); +extern void sk_stream_kill_queues(struct sock *sk); extern int sk_wait_data(struct sock *sk, long *timeo); -/* IP protocol blocks we attach to sockets. +/* Networking protocol blocks we attach to sockets. * socket layer -> transport layer interface * transport -> network interface is defined by struct inet_proto */ @@ -538,6 +539,21 @@ struct proto { void (*unhash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); + /* Memory pressure */ + void (*enter_memory_pressure)(void); + atomic_t memory_allocated; /* Current allocated memory. */ + atomic_t sockets_allocated; /* Current number of sockets. */ + /* + * Pressure flag: try to collapse. + * Technical note: it is used by multiple contexts non atomically. + * All the sk_stream_mem_schedule() is of this nature: accounting + * is strict, actions are advisory and have some latency. + */ + int memory_pressure; + int sysctl_mem[3]; + int sysctl_wmem[3]; + int sysctl_rmem[3]; + char name[32]; struct { @@ -628,6 +644,22 @@ static inline struct inode *SOCK_INODE(struct socket *socket) return &container_of(socket, struct socket_alloc, socket)->vfs_inode; } +extern void __sk_stream_mem_reclaim(struct sock *sk); +extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind); + +#define SK_STREAM_MEM_QUANTUM ((int)PAGE_SIZE) + +static inline int sk_stream_pages(int amt) +{ + return (amt + SK_STREAM_MEM_QUANTUM - 1) / SK_STREAM_MEM_QUANTUM; +} + +static inline void sk_stream_mem_reclaim(struct sock *sk) +{ + if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) + __sk_stream_mem_reclaim(sk); +} + /* Used by processes to "lock" a socket state, so that * interrupts and bottom half handlers won't change it * from under us. It essentially blocks any incoming diff --git a/include/net/tcp.h b/include/net/tcp.h index 22a62d58c24d..8e2a7739136a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -594,9 +594,6 @@ extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; extern int sysctl_tcp_ecn; extern int sysctl_tcp_dsack; -extern int sysctl_tcp_mem[3]; -extern int sysctl_tcp_wmem[3]; -extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; extern int sysctl_tcp_adv_win_scale; extern int sysctl_tcp_tw_reuse; @@ -614,10 +611,6 @@ extern int sysctl_tcp_bic_low_window; extern int sysctl_tcp_default_win_scale; extern int sysctl_tcp_moderate_rcvbuf; -extern atomic_t tcp_memory_allocated; -extern atomic_t tcp_sockets_allocated; -extern int tcp_memory_pressure; - struct open_request; struct or_calltable { @@ -1867,24 +1860,7 @@ static __inline__ void tcp_openreq_init(struct open_request *req, req->rmt_port = skb->h.th->source; } -#define TCP_MEM_QUANTUM ((int)PAGE_SIZE) - -extern void __tcp_mem_reclaim(struct sock *sk); -extern int tcp_mem_schedule(struct sock *sk, int size, int kind); - -static inline void tcp_mem_reclaim(struct sock *sk) -{ - if (sk->sk_forward_alloc >= TCP_MEM_QUANTUM) - __tcp_mem_reclaim(sk); -} - -static inline void tcp_enter_memory_pressure(void) -{ - if (!tcp_memory_pressure) { - NET_INC_STATS(TCPMemoryPressures); - tcp_memory_pressure = 1; - } -} +extern void tcp_enter_memory_pressure(void); static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) { @@ -1893,7 +1869,7 @@ static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, if (skb) { skb->truesize += mem; if (sk->sk_forward_alloc >= (int)skb->truesize || - tcp_mem_schedule(sk, skb->truesize, 0)) { + sk_stream_mem_schedule(sk, skb->truesize, 0)) { skb_reserve(skb, MAX_TCP_HEADER); return skb; } @@ -1913,7 +1889,7 @@ static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp) static inline struct page * tcp_alloc_page(struct sock *sk) { if (sk->sk_forward_alloc >= (int)PAGE_SIZE || - tcp_mem_schedule(sk, PAGE_SIZE, 0)) { + sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) { struct page *page = alloc_pages(sk->sk_allocation, 0); if (page) return page; @@ -1929,7 +1905,7 @@ static inline void tcp_writequeue_purge(struct sock *sk) while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) sk_stream_free_skb(sk, skb); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); } extern void tcp_listen_wlock(void); diff --git a/net/core/stream.c b/net/core/stream.c index d00c8d90565f..1d9c8b932fa1 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -188,3 +188,100 @@ int sk_stream_error(struct sock *sk, int flags, int err) } EXPORT_SYMBOL(sk_stream_error); + +void __sk_stream_mem_reclaim(struct sock *sk) +{ + if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) { + atomic_sub(sk->sk_forward_alloc / SK_STREAM_MEM_QUANTUM, + &sk->sk_prot->memory_allocated); + sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1; + if (sk->sk_prot->memory_pressure && + (atomic_read(&sk->sk_prot->memory_allocated) < + sk->sk_prot->sysctl_mem[0])) + sk->sk_prot->memory_pressure = 0; + } +} + +EXPORT_SYMBOL(__sk_stream_mem_reclaim); + +int sk_stream_mem_schedule(struct sock *sk, int size, int kind) +{ + int amt = sk_stream_pages(size); + + sk->sk_forward_alloc += amt * SK_STREAM_MEM_QUANTUM; + atomic_add(amt, &sk->sk_prot->memory_allocated); + + /* Under limit. */ + if (atomic_read(&sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) { + if (sk->sk_prot->memory_pressure) + sk->sk_prot->memory_pressure = 0; + return 1; + } + + /* Over hard limit. */ + if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) { + sk->sk_prot->enter_memory_pressure(); + goto suppress_allocation; + } + + /* Under pressure. */ + if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1]) + sk->sk_prot->enter_memory_pressure(); + + if (kind) { + if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_prot->sysctl_rmem[0]) + return 1; + } else if (sk->sk_wmem_queued < sk->sk_prot->sysctl_wmem[0]) + return 1; + + if (!sk->sk_prot->memory_pressure || + sk->sk_prot->sysctl_mem[2] > atomic_read(&sk->sk_prot->sockets_allocated) * + sk_stream_pages(sk->sk_wmem_queued + + atomic_read(&sk->sk_rmem_alloc) + + sk->sk_forward_alloc)) + return 1; + +suppress_allocation: + + if (!kind) { + sk_stream_moderate_sndbuf(sk); + + /* Fail only if socket is _under_ its sndbuf. + * In this case we cannot block, so that we have to fail. + */ + if (sk->sk_wmem_queued + size >= sk->sk_sndbuf) + return 1; + } + + /* Alas. Undo changes. */ + sk->sk_forward_alloc -= amt * SK_STREAM_MEM_QUANTUM; + atomic_sub(amt, &sk->sk_prot->memory_allocated); + return 0; +} + +EXPORT_SYMBOL(sk_stream_mem_schedule); + +void sk_stream_kill_queues(struct sock *sk) +{ + /* First the read buffer. */ + __skb_queue_purge(&sk->sk_receive_queue); + + /* Next, the error queue. */ + __skb_queue_purge(&sk->sk_error_queue); + + /* Next, the write queue. */ + BUG_TRAP(skb_queue_empty(&sk->sk_write_queue)); + + /* Account for returned memory. */ + sk_stream_mem_reclaim(sk); + + BUG_TRAP(!sk->sk_wmem_queued); + BUG_TRAP(!sk->sk_forward_alloc); + + /* It is _impossible_ for the backlog to contain anything + * when we get here. All user references to this socket + * have gone away, only the net layer knows can touch it. + */ +} + +EXPORT_SYMBOL(sk_stream_kill_queues); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index be47cbec57be..35164af84e34 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -65,8 +65,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) socket_seq_show(seq); seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count), - tcp_tw_count, atomic_read(&tcp_sockets_allocated), - atomic_read(&tcp_memory_allocated)); + tcp_tw_count, atomic_read(&tcp_prot.sockets_allocated), + atomic_read(&tcp_prot.memory_allocated)); seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot)); seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues, diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 6b0b74430e28..81c31a3b10b3 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -508,24 +508,24 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_TCP_MEM, .procname = "tcp_mem", - .data = &sysctl_tcp_mem, - .maxlen = sizeof(sysctl_tcp_mem), + .data = &tcp_prot.sysctl_mem, + .maxlen = sizeof(tcp_prot.sysctl_mem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_WMEM, .procname = "tcp_wmem", - .data = &sysctl_tcp_wmem, - .maxlen = sizeof(sysctl_tcp_wmem), + .data = &tcp_prot.sysctl_wmem, + .maxlen = sizeof(tcp_prot.sysctl_wmem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_RMEM, .procname = "tcp_rmem", - .data = &sysctl_tcp_rmem, - .maxlen = sizeof(sysctl_tcp_rmem), + .data = &tcp_prot.sysctl_rmem, + .maxlen = sizeof(tcp_prot.sysctl_rmem), .mode = 0644, .proc_handler = &proc_dointvec }, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e9a5843f6902..dffead725c64 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -278,85 +278,11 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0); int sysctl_tcp_default_win_scale; -int sysctl_tcp_mem[3]; -int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; -int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; - -atomic_t tcp_memory_allocated; /* Current allocated memory. */ -atomic_t tcp_sockets_allocated; /* Current number of TCP sockets. */ - -/* Pressure flag: try to collapse. - * Technical note: it is used by multiple contexts non atomically. - * All the tcp_mem_schedule() is of this nature: accounting - * is strict, actions are advisory and have some latency. */ -int tcp_memory_pressure; - -#define TCP_PAGES(amt) (((amt) + TCP_MEM_QUANTUM - 1) / TCP_MEM_QUANTUM) - -int tcp_mem_schedule(struct sock *sk, int size, int kind) -{ - int amt = TCP_PAGES(size); - - sk->sk_forward_alloc += amt * TCP_MEM_QUANTUM; - atomic_add(amt, &tcp_memory_allocated); - - /* Under limit. */ - if (atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { - if (tcp_memory_pressure) - tcp_memory_pressure = 0; - return 1; - } - - /* Over hard limit. */ - if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) { - tcp_enter_memory_pressure(); - goto suppress_allocation; - } - - /* Under pressure. */ - if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[1]) - tcp_enter_memory_pressure(); - - if (kind) { - if (atomic_read(&sk->sk_rmem_alloc) < sysctl_tcp_rmem[0]) - return 1; - } else if (sk->sk_wmem_queued < sysctl_tcp_wmem[0]) - return 1; - - if (!tcp_memory_pressure || - sysctl_tcp_mem[2] > atomic_read(&tcp_sockets_allocated) * - TCP_PAGES(sk->sk_wmem_queued + - atomic_read(&sk->sk_rmem_alloc) + - sk->sk_forward_alloc)) - return 1; - -suppress_allocation: - - if (!kind) { - sk_stream_moderate_sndbuf(sk); - - /* Fail only if socket is _under_ its sndbuf. - * In this case we cannot block, so that we have to fail. - */ - if (sk->sk_wmem_queued + size >= sk->sk_sndbuf) - return 1; - } - - /* Alas. Undo changes. */ - sk->sk_forward_alloc -= amt * TCP_MEM_QUANTUM; - atomic_sub(amt, &tcp_memory_allocated); - return 0; -} - -void __tcp_mem_reclaim(struct sock *sk) +void tcp_enter_memory_pressure(void) { - if (sk->sk_forward_alloc >= TCP_MEM_QUANTUM) { - atomic_sub(sk->sk_forward_alloc / TCP_MEM_QUANTUM, - &tcp_memory_allocated); - sk->sk_forward_alloc &= TCP_MEM_QUANTUM - 1; - if (tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) - tcp_memory_pressure = 0; + if (!tcp_prot.memory_pressure) { + NET_INC_STATS(TCPMemoryPressures); + tcp_prot.memory_pressure = 1; } } @@ -1624,29 +1550,6 @@ void tcp_shutdown(struct sock *sk, int how) } } -static __inline__ void tcp_kill_sk_queues(struct sock *sk) -{ - /* First the read buffer. */ - __skb_queue_purge(&sk->sk_receive_queue); - - /* Next, the error queue. */ - __skb_queue_purge(&sk->sk_error_queue); - - /* Next, the write queue. */ - BUG_TRAP(skb_queue_empty(&sk->sk_write_queue)); - - /* Account for returned memory. */ - tcp_mem_reclaim(sk); - - BUG_TRAP(!sk->sk_wmem_queued); - BUG_TRAP(!sk->sk_forward_alloc); - - /* It is _impossible_ for the backlog to contain anything - * when we get here. All user references to this socket - * have gone away, only the net layer knows can touch it. - */ -} - /* * At this point, there should be no process reference to this * socket, and thus no user references at all. Therefore we @@ -1674,7 +1577,7 @@ void tcp_destroy_sock(struct sock *sk) sk->sk_prot->destroy(sk); - tcp_kill_sk_queues(sk); + sk_stream_kill_queues(sk); xfrm_sk_free_policy(sk); @@ -1717,7 +1620,7 @@ void tcp_close(struct sock *sk, long timeout) __kfree_skb(skb); } - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); /* As outlined in draft-ietf-tcpimpl-prob-03.txt, section * 3.10, we send a RST here because data was lost. To @@ -1816,10 +1719,10 @@ adjudge_to_death: } } if (sk->sk_state != TCP_CLOSE) { - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { + atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "TCP: too many of orphaned " "sockets\n"); @@ -2366,15 +2269,15 @@ void __init tcp_init(void) } tcp_port_rover = sysctl_local_port_range[0] - 1; - sysctl_tcp_mem[0] = 768 << order; - sysctl_tcp_mem[1] = 1024 << order; - sysctl_tcp_mem[2] = 1536 << order; + tcp_prot.sysctl_mem[0] = 768 << order; + tcp_prot.sysctl_mem[1] = 1024 << order; + tcp_prot.sysctl_mem[2] = 1536 << order; if (order < 3) { - sysctl_tcp_wmem[2] = 64 * 1024; - sysctl_tcp_rmem[0] = PAGE_SIZE; - sysctl_tcp_rmem[1] = 43689; - sysctl_tcp_rmem[2] = 2 * 43689; + tcp_prot.sysctl_wmem[2] = 64 * 1024; + tcp_prot.sysctl_rmem[0] = PAGE_SIZE; + tcp_prot.sysctl_rmem[1] = 43689; + tcp_prot.sysctl_rmem[2] = 2 * 43689; } printk(KERN_INFO "TCP: Hash tables configured " @@ -2384,9 +2287,6 @@ void __init tcp_init(void) tcpdiag_init(); } -EXPORT_SYMBOL(__tcp_mem_reclaim); -EXPORT_SYMBOL(sysctl_tcp_rmem); -EXPORT_SYMBOL(sysctl_tcp_wmem); EXPORT_SYMBOL(tcp_accept); EXPORT_SYMBOL(tcp_close); EXPORT_SYMBOL(tcp_close_state); @@ -2402,6 +2302,5 @@ EXPORT_SYMBOL(tcp_sendmsg); EXPORT_SYMBOL(tcp_sendpage); EXPORT_SYMBOL(tcp_setsockopt); EXPORT_SYMBOL(tcp_shutdown); -EXPORT_SYMBOL(tcp_sockets_allocated); EXPORT_SYMBOL(tcp_statistics); EXPORT_SYMBOL(tcp_timewait_cachep); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5ac9ec2ad579..eb20c5d98163 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -207,7 +207,7 @@ static void tcp_fixup_sndbuf(struct sock *sk) sizeof(struct sk_buff); if (sk->sk_sndbuf < 3 * sndmem) - sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); + sk->sk_sndbuf = min(3 * sndmem, tcp_prot.sysctl_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -259,7 +259,7 @@ tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) /* Check #1 */ if (tp->rcv_ssthresh < tp->window_clamp && (int)tp->rcv_ssthresh < tcp_space(sk) && - !tcp_memory_pressure) { + !tcp_prot.memory_pressure) { int incr; /* Check #2. Increase window, if skb with such overhead @@ -291,7 +291,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk) while (tcp_win_from_space(rcvmem) < tp->advmss) rcvmem += 128; if (sk->sk_rcvbuf < 4 * rcvmem) - sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]); + sk->sk_rcvbuf = min(4 * rcvmem, tcp_prot.sysctl_rmem[2]); } /* 4. Try to fixup all. It is made iimediately after connection enters @@ -347,12 +347,12 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) * do not clamp window. Try to expand rcvbuf instead. */ if (ofo_win) { - if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && + if (sk->sk_rcvbuf < tcp_prot.sysctl_rmem[2] && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && - !tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) + !tcp_prot.memory_pressure && + atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), - sysctl_tcp_rmem[2]); + tcp_prot.sysctl_rmem[2]); } if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { app_win += ofo_win; @@ -473,7 +473,7 @@ void tcp_rcv_space_adjust(struct sock *sk) rcvmem = (tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff)); space *= rcvmem; - space = min(space, sysctl_tcp_rmem[2]); + space = min(space, tcp_prot.sysctl_rmem[2]); if (space > sk->sk_rcvbuf) sk->sk_rcvbuf = space; } @@ -527,7 +527,7 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_opt *tp, struct sk_b * restart window, so that we send ACKs quickly. */ tcp_incr_quickack(tp); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); } } tp->ack.lrcvtime = now; @@ -3158,7 +3158,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) __skb_queue_purge(&tp->out_of_order_queue); if (tp->sack_ok) tcp_sack_reset(tp); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_state_change(sk); @@ -3393,7 +3393,7 @@ static void tcp_ofo_queue(struct sock *sk) static inline int tcp_rmem_schedule(struct sock *sk, struct sk_buff *skb) { return (int)skb->truesize <= sk->sk_forward_alloc || - tcp_mem_schedule(sk, skb->truesize, 1); + sk_stream_mem_schedule(sk, skb->truesize, 1); } static int tcp_prune_queue(struct sock *sk); @@ -3760,14 +3760,14 @@ static int tcp_prune_queue(struct sock *sk) if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) tcp_clamp_window(sk, tp); - else if (tcp_memory_pressure) + else if (tcp_prot.memory_pressure) tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); tcp_collapse_ofo_queue(sk); tcp_collapse(sk, sk->sk_receive_queue.next, (struct sk_buff*)&sk->sk_receive_queue, tp->copied_seq, tp->rcv_nxt); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) return 0; @@ -3788,7 +3788,7 @@ static int tcp_prune_queue(struct sock *sk) */ if (tp->sack_ok) tcp_sack_reset(tp); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); } if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) @@ -3840,15 +3840,15 @@ static void tcp_new_space(struct sock *sk) if (tp->packets_out < tp->snd_cwnd && !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && - !tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + !tcp_prot.memory_pressure && + atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) { int sndmem = max_t(u32, tp->mss_clamp, tp->mss_cache) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering + 1); sndmem *= 2*demanded; if (sndmem > sk->sk_sndbuf) - sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]); + sk->sk_sndbuf = min(sndmem, tcp_prot.sysctl_wmem[2]); tp->snd_cwnd_stamp = tcp_time_stamp; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 956a9c44af40..828920f7b552 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2086,10 +2086,10 @@ static int tcp_v4_init_sock(struct sock *sk) tp->af_specific = &ipv4_specific; - sk->sk_sndbuf = sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sysctl_tcp_rmem[1]; + sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; + sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; - atomic_inc(&tcp_sockets_allocated); + atomic_inc(&tcp_prot.sockets_allocated); return 0; } @@ -2113,7 +2113,7 @@ static int tcp_v4_destroy_sock(struct sock *sk) if (tp->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_sockets_allocated); + atomic_dec(&tcp_prot.sockets_allocated); return 0; } @@ -2582,23 +2582,26 @@ void tcp4_proc_exit(void) #endif /* CONFIG_PROC_FS */ struct proto tcp_prot = { - .name = "TCP", - .close = tcp_close, - .connect = tcp_v4_connect, - .disconnect = tcp_disconnect, - .accept = tcp_accept, - .ioctl = tcp_ioctl, - .init = tcp_v4_init_sock, - .destroy = tcp_v4_destroy_sock, - .shutdown = tcp_shutdown, - .setsockopt = tcp_setsockopt, - .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, - .recvmsg = tcp_recvmsg, - .backlog_rcv = tcp_v4_do_rcv, - .hash = tcp_v4_hash, - .unhash = tcp_unhash, - .get_port = tcp_v4_get_port, + .name = "TCP", + .close = tcp_close, + .connect = tcp_v4_connect, + .disconnect = tcp_disconnect, + .accept = tcp_accept, + .ioctl = tcp_ioctl, + .init = tcp_v4_init_sock, + .destroy = tcp_v4_destroy_sock, + .shutdown = tcp_shutdown, + .setsockopt = tcp_setsockopt, + .getsockopt = tcp_getsockopt, + .sendmsg = tcp_sendmsg, + .recvmsg = tcp_recvmsg, + .backlog_rcv = tcp_v4_do_rcv, + .hash = tcp_v4_hash, + .unhash = tcp_unhash, + .get_port = tcp_v4_get_port, + .enter_memory_pressure = tcp_enter_memory_pressure, + .sysctl_wmem = { 4 * 1024, 16 * 1024, 128 * 1024 }, + .sysctl_rmem = { 4 * 1024, 87380, 87380 * 2 }, }; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index dacd76e33133..4f36e164eb07 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -801,7 +801,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, #ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); #endif - atomic_inc(&tcp_sockets_allocated); + atomic_inc(&tcp_prot.sockets_allocated); if (sock_flag(newsk, SOCK_KEEPOPEN)) tcp_reset_keepalive_timer(newsk, diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7d6eca0cd01e..e78461bdbf3b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -672,7 +672,7 @@ u32 __tcp_select_window(struct sock *sk) if (free_space < full_space/2) { tp->ack.quick = 0; - if (tcp_memory_pressure) + if (tcp_prot.memory_pressure) tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss); if (free_space < mss) diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 44615198e6a1..876f9f410277 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -113,7 +113,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) if (orphans >= sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { + atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "Out of socket memory\n"); @@ -217,7 +217,7 @@ static void tcp_delack_timer(unsigned long data) goto out_unlock; } - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); if (sk->sk_state == TCP_CLOSE || !(tp->ack.pending & TCP_ACK_TIMER)) goto out; @@ -257,8 +257,8 @@ static void tcp_delack_timer(unsigned long data) TCP_CHECK_TIMER(sk); out: - if (tcp_memory_pressure) - tcp_mem_reclaim(sk); + if (tcp_prot.memory_pressure) + sk_stream_mem_reclaim(sk); out_unlock: bh_unlock_sock(sk); sock_put(sk); @@ -448,7 +448,7 @@ static void tcp_write_timer(unsigned long data) TCP_CHECK_TIMER(sk); out: - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); out_unlock: bh_unlock_sock(sk); sock_put(sk); @@ -633,7 +633,7 @@ static void tcp_keepalive_timer (unsigned long data) } TCP_CHECK_TIMER(sk); - tcp_mem_reclaim(sk); + sk_stream_mem_reclaim(sk); resched: tcp_reset_keepalive_timer (sk, elapsed); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index db58adc22c59..99d6ccefd17f 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1883,10 +1883,10 @@ static int tcp_v6_init_sock(struct sock *sk) sk->sk_write_space = sk_stream_write_space; sk->sk_use_write_queue = 1; - sk->sk_sndbuf = sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sysctl_tcp_rmem[1]; + sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; + sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; - atomic_inc(&tcp_sockets_allocated); + atomic_inc(&tcp_prot.sockets_allocated); return 0; } @@ -1910,7 +1910,7 @@ static int tcp_v6_destroy_sock(struct sock *sk) if (tcp_sk(sk)->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_sockets_allocated); + atomic_dec(&tcp_prot.sockets_allocated); return inet6_destroy_sock(sk); } -- cgit v1.2.3 From 6e42a42172b97e4c8ee8bdedafdf21596f86d876 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Jun 2004 02:59:52 -0700 Subject: [PATCH] PCI: (one more) PCI quirk for SMBus bridge on Asus P4 boards my board has one of those "clever" bioses that hide the smbus. this tiny patch adds it to the Bad Guy List (TM). Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b82a1c31e1df..0ccd6857d508 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -705,6 +705,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) } if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) switch(dev->subsystem_device) { + case 0x80b1: /* P4GE-V */ case 0x80b2: /* P4PE */ case 0x8093: /* P4B533-V */ asus_hides_smbus = 1; -- cgit v1.2.3 From 803d84e5dd2c7efd29f2ad4ff4694fce054262fd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 23 Jun 2004 05:42:54 -0700 Subject: [NETFILTER]: Use correct size_t printk format string in ipt_addrtype.c --- net/ipv4/netfilter/ipt_addrtype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 7392ba6bd23f..f5909a4c3fc7 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c @@ -48,7 +48,7 @@ static int checkentry(const char *tablename, const struct ipt_ip *ip, unsigned int hook_mask) { if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) { - printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.", + printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.", matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info))); return 0; } -- cgit v1.2.3 From 6ea12222942cd549dc1be9d0623a34cd3f39e39d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 23 Jun 2004 05:44:57 -0700 Subject: [ATM]: In proc_mpc_read, make length ssize_t. --- net/atm/mpoa_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 64c676dd550e..714fe71aeda9 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -103,7 +103,7 @@ static ssize_t proc_mpc_read(struct file *file, char __user *buff, size_t count, loff_t *pos){ unsigned long page = 0; unsigned char *temp; - int length = 0; + ssize_t length = 0; int i = 0; struct mpoa_client *mpc = mpcs; in_cache_entry *in_entry; -- cgit v1.2.3 From fdf12225556ebee8cb881414f98ce228b4d096ce Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 23 Jun 2004 12:03:17 -0300 Subject: [NET] Generalise tcp_{writequeue_purge,rmem_schedule,alloc_{pskb,page}} Only new requirement was to add a max_header field to struct sock sk_prot member. Signed-off-by: Arnaldo Carvalho de Melo --- include/net/sock.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/net/tcp.h | 46 ------------------------------------------ net/ipv4/tcp.c | 12 +++++------ net/ipv4/tcp_input.c | 16 ++++++--------- net/ipv4/tcp_ipv4.c | 3 ++- net/ipv4/tcp_output.c | 2 +- net/ipv6/tcp_ipv6.c | 3 ++- 7 files changed, 73 insertions(+), 65 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 23f72934b180..809a3c687c1c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -553,6 +553,7 @@ struct proto { int sysctl_mem[3]; int sysctl_wmem[3]; int sysctl_rmem[3]; + int max_header; char name[32]; @@ -660,6 +661,21 @@ static inline void sk_stream_mem_reclaim(struct sock *sk) __sk_stream_mem_reclaim(sk); } +static inline void sk_stream_writequeue_purge(struct sock *sk) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) + sk_stream_free_skb(sk, skb); + sk_stream_mem_reclaim(sk); +} + +static inline int sk_stream_rmem_schedule(struct sock *sk, struct sk_buff *skb) +{ + return (int)skb->truesize <= sk->sk_forward_alloc || + sk_stream_mem_schedule(sk, skb->truesize, 1); +} + /* Used by processes to "lock" a socket state, so that * interrupts and bottom half handlers won't change it * from under us. It essentially blocks any incoming @@ -1141,6 +1157,46 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk) } } +static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, + int size, int mem, int gfp) +{ + struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp); + + if (skb) { + skb->truesize += mem; + if (sk->sk_forward_alloc >= (int)skb->truesize || + sk_stream_mem_schedule(sk, skb->truesize, 0)) { + skb_reserve(skb, sk->sk_prot->max_header); + return skb; + } + __kfree_skb(skb); + } else { + sk->sk_prot->enter_memory_pressure(); + sk_stream_moderate_sndbuf(sk); + } + return NULL; +} + +static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk, + int size, int gfp) +{ + return sk_stream_alloc_pskb(sk, size, 0, gfp); +} + +static inline struct page *sk_stream_alloc_page(struct sock *sk) +{ + struct page *page = NULL; + + if (sk->sk_forward_alloc >= (int)PAGE_SIZE || + sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) + page = alloc_pages(sk->sk_allocation, 0); + else { + sk->sk_prot->enter_memory_pressure(); + sk_stream_moderate_sndbuf(sk); + } + return page; +} + #define sk_stream_for_retrans_queue(skb, sk) \ for (skb = (sk)->sk_write_queue.next; \ (skb != (sk)->sk_send_head) && \ diff --git a/include/net/tcp.h b/include/net/tcp.h index 8e2a7739136a..626a0803e452 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1862,52 +1862,6 @@ static __inline__ void tcp_openreq_init(struct open_request *req, extern void tcp_enter_memory_pressure(void); -static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp) -{ - struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp); - - if (skb) { - skb->truesize += mem; - if (sk->sk_forward_alloc >= (int)skb->truesize || - sk_stream_mem_schedule(sk, skb->truesize, 0)) { - skb_reserve(skb, MAX_TCP_HEADER); - return skb; - } - __kfree_skb(skb); - } else { - tcp_enter_memory_pressure(); - sk_stream_moderate_sndbuf(sk); - } - return NULL; -} - -static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp) -{ - return tcp_alloc_pskb(sk, size, 0, gfp); -} - -static inline struct page * tcp_alloc_page(struct sock *sk) -{ - if (sk->sk_forward_alloc >= (int)PAGE_SIZE || - sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) { - struct page *page = alloc_pages(sk->sk_allocation, 0); - if (page) - return page; - } - tcp_enter_memory_pressure(); - sk_stream_moderate_sndbuf(sk); - return NULL; -} - -static inline void tcp_writequeue_purge(struct sock *sk) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) - sk_stream_free_skb(sk, skb); - sk_stream_mem_reclaim(sk); -} - extern void tcp_listen_wlock(void); /* - We may sleep inside this lock. diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index dffead725c64..554de667bfee 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -639,8 +639,8 @@ new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; - skb = tcp_alloc_pskb(sk, 0, tp->mss_cache, - sk->sk_allocation); + skb = sk_stream_alloc_pskb(sk, 0, tp->mss_cache, + sk->sk_allocation); if (!skb) goto wait_for_memory; @@ -806,8 +806,8 @@ new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; - skb = tcp_alloc_pskb(sk, select_size(sk, tp), - 0, sk->sk_allocation); + skb = sk_stream_alloc_pskb(sk, select_size(sk, tp), + 0, sk->sk_allocation); if (!skb) goto wait_for_memory; @@ -868,7 +868,7 @@ new_segment: if (!page) { /* Allocate new cache page. */ - if (!(page = tcp_alloc_page(sk))) + if (!(page = sk_stream_alloc_page(sk))) goto wait_for_memory; off = 0; } @@ -1778,7 +1778,7 @@ int tcp_disconnect(struct sock *sk, int flags) tcp_clear_xmit_timers(sk); __skb_queue_purge(&sk->sk_receive_queue); - tcp_writequeue_purge(sk); + sk_stream_writequeue_purge(sk); __skb_queue_purge(&tp->out_of_order_queue); inet->dport = 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eb20c5d98163..235ecbbd7a77 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3390,12 +3390,6 @@ static void tcp_ofo_queue(struct sock *sk) } } -static inline int tcp_rmem_schedule(struct sock *sk, struct sk_buff *skb) -{ - return (int)skb->truesize <= sk->sk_forward_alloc || - sk_stream_mem_schedule(sk, skb->truesize, 1); -} - static int tcp_prune_queue(struct sock *sk); static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) @@ -3449,8 +3443,9 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) queue_and_out: if (eaten < 0 && (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !tcp_rmem_schedule(sk, skb))) { - if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) + !sk_stream_rmem_schedule(sk, skb))) { + if (tcp_prune_queue(sk) < 0 || + !sk_stream_rmem_schedule(sk, skb)) goto drop; } sk_stream_set_owner_r(skb, sk); @@ -3522,8 +3517,9 @@ drop: TCP_ECN_check_ce(tp, skb); if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !tcp_rmem_schedule(sk, skb)) { - if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb)) + !sk_stream_rmem_schedule(sk, skb)) { + if (tcp_prune_queue(sk) < 0 || + !sk_stream_rmem_schedule(sk, skb)) goto drop; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 828920f7b552..1f18e6aab18b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2101,7 +2101,7 @@ static int tcp_v4_destroy_sock(struct sock *sk) tcp_clear_xmit_timers(sk); /* Cleanup up the write buffer. */ - tcp_writequeue_purge(sk); + sk_stream_writequeue_purge(sk); /* Cleans up our, hopefully empty, out_of_order_queue. */ __skb_queue_purge(&tp->out_of_order_queue); @@ -2602,6 +2602,7 @@ struct proto tcp_prot = { .enter_memory_pressure = tcp_enter_memory_pressure, .sysctl_wmem = { 4 * 1024, 16 * 1024, 128 * 1024 }, .sysctl_rmem = { 4 * 1024, 87380, 87380 * 2 }, + .max_header = MAX_TCP_HEADER, }; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e78461bdbf3b..b6203742f97f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -372,7 +372,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) return -ENOMEM; /* Get a new skb... force flag on. */ - buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC); + buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); if (buff == NULL) return -ENOMEM; /* We'll just try again later. */ sk_charge_skb(sk, buff); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 99d6ccefd17f..a1b6dfb0193c 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1898,7 +1898,7 @@ static int tcp_v6_destroy_sock(struct sock *sk) tcp_clear_xmit_timers(sk); /* Cleanup up the write buffer. */ - tcp_writequeue_purge(sk); + sk_stream_writequeue_purge(sk); /* Cleans up our, hopefully empty, out_of_order_queue. */ __skb_queue_purge(&tp->out_of_order_queue); @@ -2096,6 +2096,7 @@ struct proto tcpv6_prot = { .hash = tcp_v6_hash, .unhash = tcp_unhash, .get_port = tcp_v6_get_port, + .max_header = MAX_TCP_HEADER, }; static struct inet6_protocol tcpv6_protocol = { -- cgit v1.2.3 From 9b89634d038b334f1779f1d73a8e19a733213d03 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 23 Jun 2004 20:09:17 +0100 Subject: [ARM] Fix Integrator/CP timer support. --- arch/arm/mach-integrator/core.c | 139 +++++++++++++++++++++++++++++ arch/arm/mach-integrator/integrator_cp.c | 2 + arch/arm/mach-integrator/time.c | 144 ------------------------------- 3 files changed, 141 insertions(+), 144 deletions(-) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 01ce14d7004d..7f6df02cf7ed 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -12,12 +12,17 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include +#include static struct amba_device rtc_device = { .dev = { @@ -127,3 +132,137 @@ void cm_control(u32 mask, u32 set) } EXPORT_SYMBOL(cm_control); + +/* + * Where is the timer (VA)? + */ +#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) +#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) +#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) +#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) +#elif TIMER_INTERVAL >= 0x10000 +#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) +#else +#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) +#endif + +/* + * What does it look like? + */ +typedef struct TimerStruct { + unsigned long TimerLoad; + unsigned long TimerValue; + unsigned long TimerControl; + unsigned long TimerClear; +} TimerStruct_t; + +extern unsigned long (*gettimeoffset)(void); + +static unsigned long timer_reload; + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long integrator_gettimeoffset(void) +{ + volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; + unsigned long ticks1, ticks2, status; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = timer1->TimerValue & 0xffff; + do { + ticks1 = ticks2; + status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); + ticks2 = timer1->TimerValue & 0xffff; + } while (ticks2 > ticks1); + + /* + * Number of ticks since last interrupt. + */ + ticks1 = timer_reload - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + */ + if (status & (1 << IRQ_TIMERINT1)) + ticks1 += timer_reload; + + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + + // ...clear the interrupt + timer1->TimerClear = 1; + + timer_tick(regs); + + return IRQ_HANDLED; +} + +static struct irqaction integrator_timer_irq = { + .name = "Integrator Timer Tick", + .flags = SA_INTERRUPT, + .handler = integrator_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; + unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + + timer_reload = reload; + timer_ctrl |= ctrl; + + if (timer_reload > 0x100000) { + timer_reload >>= 8; + timer_ctrl |= 0x08; /* /256 */ + } else if (timer_reload > 0x010000) { + timer_reload >>= 4; + timer_ctrl |= 0x04; /* /16 */ + } + + /* + * Initialise to a known state (all timers off) + */ + timer0->TimerControl = 0; + timer1->TimerControl = 0; + timer2->TimerControl = 0; + + timer1->TimerLoad = timer_reload; + timer1->TimerValue = timer_reload; + timer1->TimerControl = timer_ctrl; + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + gettimeoffset = integrator_gettimeoffset; +} diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index aa29c76aacc0..ce7bfd941866 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -419,6 +419,8 @@ static void __init intcp_init(void) } } +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ + static void __init intcp_init_time(void) { integrator_time_init(1000000 / HZ, TIMER_CTRL_IE); diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c index e12bcf814d95..39606096fbd6 100644 --- a/arch/arm/mach-integrator/time.c +++ b/arch/arm/mach-integrator/time.c @@ -10,16 +10,9 @@ #include #include #include -#include -#include #include #include -#include -#include -#include - -#include #define RTC_DR (IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0) #define RTC_MR (IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4) @@ -51,140 +44,3 @@ static int integrator_rtc_init(void) } __initcall(integrator_rtc_init); - - -/* - * Where is the timer (VA)? - */ -#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) -#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) -#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) -#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) - -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ - -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - -extern unsigned long (*gettimeoffset)(void); - -static unsigned long timer_reload; - -/* - * Returns number of ms since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - */ -static unsigned long integrator_gettimeoffset(void) -{ - volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; - unsigned long ticks1, ticks2, status; - - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks2 = timer1->TimerValue & 0xffff; - do { - ticks1 = ticks2; - status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = timer1->TimerValue & 0xffff; - } while (ticks2 > ticks1); - - /* - * Number of ticks since last interrupt. - */ - ticks1 = timer_reload - ticks2; - - /* - * Interrupt pending? If so, we've reloaded once already. - */ - if (status & (1 << IRQ_TIMERINT1)) - ticks1 += timer_reload; - - /* - * Convert the ticks to usecs - */ - return TICKS2USECS(ticks1); -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t -integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - - // ...clear the interrupt - timer1->TimerClear = 1; - - timer_tick(regs); - - return IRQ_HANDLED; -} - -static struct irqaction integrator_timer_irq = { - .name = "Integrator Timer Tick", - .flags = SA_INTERRUPT, - .handler = integrator_timer_interrupt -}; - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init integrator_time_init(unsigned long reload, unsigned int ctrl) -{ - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ - - timer_reload = reload; - timer_ctrl |= ctrl; - - if (timer_reload > 0x100000) { - timer_reload >>= 8; - timer_ctrl |= 0x08; /* /256 */ - } else if (timer_reload > 0x010000) { - timer_reload >>= 4; - timer_ctrl |= 0x04; /* /16 */ - } - - /* - * Initialise to a known state (all timers off) - */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; - - timer1->TimerLoad = timer_reload; - timer1->TimerValue = timer_reload; - timer1->TimerControl = timer_ctrl; - - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); - gettimeoffset = integrator_gettimeoffset; -} -- cgit v1.2.3 From e75420f7f8b975d3ef47bbeb1c928fa943e33f3b Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 23 Jun 2004 21:13:37 +0100 Subject: [ARM] Fix platform device registration. Since the platform device registration is now merged into the driver model, remove it from the ARM specific code. --- arch/arm/common/Makefile | 1 - arch/arm/common/platform.c | 35 -------------------------------- arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-versatile/core.c | 4 ++-- 4 files changed, 3 insertions(+), 39 deletions(-) delete mode 100644 arch/arm/common/platform.c diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index a0648d979d08..a1b246af1e10 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -2,7 +2,6 @@ # Makefile for the linux kernel. # -obj-y += platform.o obj-$(CONFIG_ARM_AMBA) += amba.o obj-$(CONFIG_ICST525) += icst525.o obj-$(CONFIG_SA1111) += sa1111.o diff --git a/arch/arm/common/platform.c b/arch/arm/common/platform.c deleted file mode 100644 index 441f321feb55..000000000000 --- a/arch/arm/common/platform.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include - -int __init platform_add_device(struct platform_device *dev) -{ - int i; - - for (i = 0; i < dev->num_resources; i++) { - struct resource *r = &dev->resource[i]; - - r->name = dev->dev.bus_id; - - if (r->flags & IORESOURCE_MEM && - request_resource(&iomem_resource, r)) { - printk(KERN_ERR - "%s%d: failed to claim resource %d\n", - dev->name, dev->id, i); - break; - } - } - if (i == dev->num_resources) - platform_device_register(dev); - return 0; -} - -int __init platform_add_devices(struct platform_device **devs, int num) -{ - int i; - - for (i = 0; i < num; i++) - platform_add_device(devs[i]); - - return 0; -} diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 4fee881855f1..b07e39d21cdf 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -256,7 +256,7 @@ static void __init ap_init(void) unsigned long sc_dec; int i; - platform_add_device(&cfi_flash_device); + platform_device_register(&cfi_flash_device); sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); for (i = 0; i < 4; i++) { diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index a2f88df44ab9..c614d35ad0a7 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -503,8 +503,8 @@ static void __init versatile_init(void) { int i; - platform_add_device(&versatile_flash_device); - platform_add_device(&smc91x_device); + platform_device_register(&versatile_flash_device); + platform_device_register(&smc91x_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; -- cgit v1.2.3 From 50bde7d0f69bbdf0b90baf198620bb838eb5cc74 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 23 Jun 2004 20:01:15 -0300 Subject: [NET] make the struct proto entries related to memory pressure be pointers This is needed because tcpv6_prot has to point to the same place tcp_prot points, as they share the same accounting variables. This fixes a bug noticed by David Miller when using the ipv6_mapped functionality, thanks David! Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/net/sock.h | 12 +++++------ include/net/tcp.h | 7 +++++++ net/core/stream.c | 26 +++++++++++------------ net/ipv4/proc.c | 4 ++-- net/ipv4/sysctl_net_ipv4.c | 12 +++++------ net/ipv4/tcp.c | 46 ++++++++++++++++++++++++++++++++--------- net/ipv4/tcp_input.c | 16 +++++++-------- net/ipv4/tcp_ipv4.c | 16 +++++++++------ net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_timer.c | 2 +- net/ipv6/tcp_ipv6.c | 51 ++++++++++++++++++++++++++-------------------- 11 files changed, 119 insertions(+), 75 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 809a3c687c1c..9da91b9be903 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -541,18 +541,18 @@ struct proto { /* Memory pressure */ void (*enter_memory_pressure)(void); - atomic_t memory_allocated; /* Current allocated memory. */ - atomic_t sockets_allocated; /* Current number of sockets. */ + atomic_t *memory_allocated; /* Current allocated memory. */ + atomic_t *sockets_allocated; /* Current number of sockets. */ /* * Pressure flag: try to collapse. * Technical note: it is used by multiple contexts non atomically. * All the sk_stream_mem_schedule() is of this nature: accounting * is strict, actions are advisory and have some latency. */ - int memory_pressure; - int sysctl_mem[3]; - int sysctl_wmem[3]; - int sysctl_rmem[3]; + int *memory_pressure; + int *sysctl_mem; + int *sysctl_wmem; + int *sysctl_rmem; int max_header; char name[32]; diff --git a/include/net/tcp.h b/include/net/tcp.h index 626a0803e452..3f4c524de3e2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -594,6 +594,9 @@ extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; extern int sysctl_tcp_ecn; extern int sysctl_tcp_dsack; +extern int sysctl_tcp_mem[3]; +extern int sysctl_tcp_wmem[3]; +extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; extern int sysctl_tcp_adv_win_scale; extern int sysctl_tcp_tw_reuse; @@ -611,6 +614,10 @@ extern int sysctl_tcp_bic_low_window; extern int sysctl_tcp_default_win_scale; extern int sysctl_tcp_moderate_rcvbuf; +extern atomic_t tcp_memory_allocated; +extern atomic_t tcp_sockets_allocated; +extern int tcp_memory_pressure; + struct open_request; struct or_calltable { diff --git a/net/core/stream.c b/net/core/stream.c index 1d9c8b932fa1..1e27a57b5a97 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -193,12 +193,12 @@ void __sk_stream_mem_reclaim(struct sock *sk) { if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) { atomic_sub(sk->sk_forward_alloc / SK_STREAM_MEM_QUANTUM, - &sk->sk_prot->memory_allocated); + sk->sk_prot->memory_allocated); sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1; - if (sk->sk_prot->memory_pressure && - (atomic_read(&sk->sk_prot->memory_allocated) < + if (*sk->sk_prot->memory_pressure && + (atomic_read(sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0])) - sk->sk_prot->memory_pressure = 0; + *sk->sk_prot->memory_pressure = 0; } } @@ -209,23 +209,23 @@ int sk_stream_mem_schedule(struct sock *sk, int size, int kind) int amt = sk_stream_pages(size); sk->sk_forward_alloc += amt * SK_STREAM_MEM_QUANTUM; - atomic_add(amt, &sk->sk_prot->memory_allocated); + atomic_add(amt, sk->sk_prot->memory_allocated); /* Under limit. */ - if (atomic_read(&sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) { - if (sk->sk_prot->memory_pressure) - sk->sk_prot->memory_pressure = 0; + if (atomic_read(sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) { + if (*sk->sk_prot->memory_pressure) + *sk->sk_prot->memory_pressure = 0; return 1; } /* Over hard limit. */ - if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) { + if (atomic_read(sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) { sk->sk_prot->enter_memory_pressure(); goto suppress_allocation; } /* Under pressure. */ - if (atomic_read(&sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1]) + if (atomic_read(sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1]) sk->sk_prot->enter_memory_pressure(); if (kind) { @@ -234,8 +234,8 @@ int sk_stream_mem_schedule(struct sock *sk, int size, int kind) } else if (sk->sk_wmem_queued < sk->sk_prot->sysctl_wmem[0]) return 1; - if (!sk->sk_prot->memory_pressure || - sk->sk_prot->sysctl_mem[2] > atomic_read(&sk->sk_prot->sockets_allocated) * + if (!*sk->sk_prot->memory_pressure || + sk->sk_prot->sysctl_mem[2] > atomic_read(sk->sk_prot->sockets_allocated) * sk_stream_pages(sk->sk_wmem_queued + atomic_read(&sk->sk_rmem_alloc) + sk->sk_forward_alloc)) @@ -255,7 +255,7 @@ suppress_allocation: /* Alas. Undo changes. */ sk->sk_forward_alloc -= amt * SK_STREAM_MEM_QUANTUM; - atomic_sub(amt, &sk->sk_prot->memory_allocated); + atomic_sub(amt, sk->sk_prot->memory_allocated); return 0; } diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 35164af84e34..be47cbec57be 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -65,8 +65,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) socket_seq_show(seq); seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count), - tcp_tw_count, atomic_read(&tcp_prot.sockets_allocated), - atomic_read(&tcp_prot.memory_allocated)); + tcp_tw_count, atomic_read(&tcp_sockets_allocated), + atomic_read(&tcp_memory_allocated)); seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot)); seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues, diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 81c31a3b10b3..6b0b74430e28 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -508,24 +508,24 @@ ctl_table ipv4_table[] = { { .ctl_name = NET_TCP_MEM, .procname = "tcp_mem", - .data = &tcp_prot.sysctl_mem, - .maxlen = sizeof(tcp_prot.sysctl_mem), + .data = &sysctl_tcp_mem, + .maxlen = sizeof(sysctl_tcp_mem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_WMEM, .procname = "tcp_wmem", - .data = &tcp_prot.sysctl_wmem, - .maxlen = sizeof(tcp_prot.sysctl_wmem), + .data = &sysctl_tcp_wmem, + .maxlen = sizeof(sysctl_tcp_wmem), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = NET_TCP_RMEM, .procname = "tcp_rmem", - .data = &tcp_prot.sysctl_rmem, - .maxlen = sizeof(tcp_prot.sysctl_rmem), + .data = &sysctl_tcp_rmem, + .maxlen = sizeof(sysctl_tcp_rmem), .mode = 0644, .proc_handler = &proc_dointvec }, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 554de667bfee..33ca080f8727 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -278,14 +278,40 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0); int sysctl_tcp_default_win_scale; +int sysctl_tcp_mem[3]; +int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; +int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; + +EXPORT_SYMBOL(sysctl_tcp_mem); +EXPORT_SYMBOL(sysctl_tcp_rmem); +EXPORT_SYMBOL(sysctl_tcp_wmem); + +atomic_t tcp_memory_allocated; /* Current allocated memory. */ +atomic_t tcp_sockets_allocated; /* Current number of TCP sockets. */ + +EXPORT_SYMBOL(tcp_memory_allocated); +EXPORT_SYMBOL(tcp_sockets_allocated); + +/* + * Pressure flag: try to collapse. + * Technical note: it is used by multiple contexts non atomically. + * All the sk_stream_mem_schedule() is of this nature: accounting + * is strict, actions are advisory and have some latency. + */ +int tcp_memory_pressure; + +EXPORT_SYMBOL(tcp_memory_pressure); + void tcp_enter_memory_pressure(void) { - if (!tcp_prot.memory_pressure) { + if (!tcp_memory_pressure) { NET_INC_STATS(TCPMemoryPressures); - tcp_prot.memory_pressure = 1; + tcp_memory_pressure = 1; } } +EXPORT_SYMBOL(tcp_enter_memory_pressure); + /* * LISTEN is a special case for poll.. */ @@ -1722,7 +1748,7 @@ adjudge_to_death: sk_stream_mem_reclaim(sk); if (atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "TCP: too many of orphaned " "sockets\n"); @@ -2269,15 +2295,15 @@ void __init tcp_init(void) } tcp_port_rover = sysctl_local_port_range[0] - 1; - tcp_prot.sysctl_mem[0] = 768 << order; - tcp_prot.sysctl_mem[1] = 1024 << order; - tcp_prot.sysctl_mem[2] = 1536 << order; + sysctl_tcp_mem[0] = 768 << order; + sysctl_tcp_mem[1] = 1024 << order; + sysctl_tcp_mem[2] = 1536 << order; if (order < 3) { - tcp_prot.sysctl_wmem[2] = 64 * 1024; - tcp_prot.sysctl_rmem[0] = PAGE_SIZE; - tcp_prot.sysctl_rmem[1] = 43689; - tcp_prot.sysctl_rmem[2] = 2 * 43689; + sysctl_tcp_wmem[2] = 64 * 1024; + sysctl_tcp_rmem[0] = PAGE_SIZE; + sysctl_tcp_rmem[1] = 43689; + sysctl_tcp_rmem[2] = 2 * 43689; } printk(KERN_INFO "TCP: Hash tables configured " diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 235ecbbd7a77..69dcc9f123bf 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -207,7 +207,7 @@ static void tcp_fixup_sndbuf(struct sock *sk) sizeof(struct sk_buff); if (sk->sk_sndbuf < 3 * sndmem) - sk->sk_sndbuf = min(3 * sndmem, tcp_prot.sysctl_wmem[2]); + sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -291,7 +291,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk) while (tcp_win_from_space(rcvmem) < tp->advmss) rcvmem += 128; if (sk->sk_rcvbuf < 4 * rcvmem) - sk->sk_rcvbuf = min(4 * rcvmem, tcp_prot.sysctl_rmem[2]); + sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]); } /* 4. Try to fixup all. It is made iimediately after connection enters @@ -347,12 +347,12 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp) * do not clamp window. Try to expand rcvbuf instead. */ if (ofo_win) { - if (sk->sk_rcvbuf < tcp_prot.sysctl_rmem[2] && + if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && !tcp_prot.memory_pressure && - atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), - tcp_prot.sysctl_rmem[2]); + sysctl_tcp_rmem[2]); } if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { app_win += ofo_win; @@ -473,7 +473,7 @@ void tcp_rcv_space_adjust(struct sock *sk) rcvmem = (tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff)); space *= rcvmem; - space = min(space, tcp_prot.sysctl_rmem[2]); + space = min(space, sysctl_tcp_rmem[2]); if (space > sk->sk_rcvbuf) sk->sk_rcvbuf = space; } @@ -3837,14 +3837,14 @@ static void tcp_new_space(struct sock *sk) if (tp->packets_out < tp->snd_cwnd && !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && !tcp_prot.memory_pressure && - atomic_read(&tcp_prot.memory_allocated) < tcp_prot.sysctl_mem[0]) { + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { int sndmem = max_t(u32, tp->mss_clamp, tp->mss_cache) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering + 1); sndmem *= 2*demanded; if (sndmem > sk->sk_sndbuf) - sk->sk_sndbuf = min(sndmem, tcp_prot.sysctl_wmem[2]); + sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]); tp->snd_cwnd_stamp = tcp_time_stamp; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1f18e6aab18b..35ca34b6b052 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2086,10 +2086,10 @@ static int tcp_v4_init_sock(struct sock *sk) tp->af_specific = &ipv4_specific; - sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; - sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; + sk->sk_sndbuf = sysctl_tcp_wmem[1]; + sk->sk_rcvbuf = sysctl_tcp_rmem[1]; - atomic_inc(&tcp_prot.sockets_allocated); + atomic_inc(&tcp_sockets_allocated); return 0; } @@ -2113,7 +2113,7 @@ static int tcp_v4_destroy_sock(struct sock *sk) if (tp->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_prot.sockets_allocated); + atomic_dec(&tcp_sockets_allocated); return 0; } @@ -2600,8 +2600,12 @@ struct proto tcp_prot = { .unhash = tcp_unhash, .get_port = tcp_v4_get_port, .enter_memory_pressure = tcp_enter_memory_pressure, - .sysctl_wmem = { 4 * 1024, 16 * 1024, 128 * 1024 }, - .sysctl_rmem = { 4 * 1024, 87380, 87380 * 2 }, + .sockets_allocated = &tcp_sockets_allocated, + .memory_allocated = &tcp_memory_allocated, + .memory_pressure = &tcp_memory_pressure, + .sysctl_mem = sysctl_tcp_mem, + .sysctl_wmem = sysctl_tcp_wmem, + .sysctl_rmem = sysctl_tcp_rmem, .max_header = MAX_TCP_HEADER, }; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 4f36e164eb07..dacd76e33133 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -801,7 +801,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, #ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); #endif - atomic_inc(&tcp_prot.sockets_allocated); + atomic_inc(&tcp_sockets_allocated); if (sock_flag(newsk, SOCK_KEEPOPEN)) tcp_reset_keepalive_timer(newsk, diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 876f9f410277..840f621886c8 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -113,7 +113,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset) if (orphans >= sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_read(&tcp_prot.memory_allocated) > tcp_prot.sysctl_mem[2])) { + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "Out of socket memory\n"); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a1b6dfb0193c..d2855de92260 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1883,10 +1883,10 @@ static int tcp_v6_init_sock(struct sock *sk) sk->sk_write_space = sk_stream_write_space; sk->sk_use_write_queue = 1; - sk->sk_sndbuf = tcp_prot.sysctl_wmem[1]; - sk->sk_rcvbuf = tcp_prot.sysctl_rmem[1]; + sk->sk_sndbuf = sysctl_tcp_wmem[1]; + sk->sk_rcvbuf = sysctl_tcp_rmem[1]; - atomic_inc(&tcp_prot.sockets_allocated); + atomic_inc(&tcp_sockets_allocated); return 0; } @@ -1910,7 +1910,7 @@ static int tcp_v6_destroy_sock(struct sock *sk) if (tcp_sk(sk)->bind_hash) tcp_put_port(sk); - atomic_dec(&tcp_prot.sockets_allocated); + atomic_dec(&tcp_sockets_allocated); return inet6_destroy_sock(sk); } @@ -2079,24 +2079,31 @@ void tcp6_proc_exit(void) #endif struct proto tcpv6_prot = { - .name = "TCPv6", - .close = tcp_close, - .connect = tcp_v6_connect, - .disconnect = tcp_disconnect, - .accept = tcp_accept, - .ioctl = tcp_ioctl, - .init = tcp_v6_init_sock, - .destroy = tcp_v6_destroy_sock, - .shutdown = tcp_shutdown, - .setsockopt = tcp_setsockopt, - .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, - .recvmsg = tcp_recvmsg, - .backlog_rcv = tcp_v6_do_rcv, - .hash = tcp_v6_hash, - .unhash = tcp_unhash, - .get_port = tcp_v6_get_port, - .max_header = MAX_TCP_HEADER, + .name = "TCPv6", + .close = tcp_close, + .connect = tcp_v6_connect, + .disconnect = tcp_disconnect, + .accept = tcp_accept, + .ioctl = tcp_ioctl, + .init = tcp_v6_init_sock, + .destroy = tcp_v6_destroy_sock, + .shutdown = tcp_shutdown, + .setsockopt = tcp_setsockopt, + .getsockopt = tcp_getsockopt, + .sendmsg = tcp_sendmsg, + .recvmsg = tcp_recvmsg, + .backlog_rcv = tcp_v6_do_rcv, + .hash = tcp_v6_hash, + .unhash = tcp_unhash, + .get_port = tcp_v6_get_port, + .enter_memory_pressure = tcp_enter_memory_pressure, + .sockets_allocated = &tcp_sockets_allocated, + .memory_allocated = &tcp_memory_allocated, + .memory_pressure = &tcp_memory_pressure, + .sysctl_mem = sysctl_tcp_mem, + .sysctl_wmem = sysctl_tcp_wmem, + .sysctl_rmem = sysctl_tcp_rmem, + .max_header = MAX_TCP_HEADER, }; static struct inet6_protocol tcpv6_protocol = { -- cgit v1.2.3 From 0cf97231877d1121679e8891d29201a5c61cdd24 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 24 Jun 2004 01:26:14 +0100 Subject: [ARM PATCH] 1943/1: OMAP compile fix Patch from Tony Lindgren This patch fixes OMAP compile after the ARM timer changes in cset 1.1821.5.3 and dma-mapping device address translation in cset 1.1821.5.3. --- arch/arm/mach-omap/bus.c | 39 --------------------------------------- arch/arm/mach-omap/time.c | 5 +++++ 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/arch/arm/mach-omap/bus.c b/arch/arm/mach-omap/bus.c index 07da30d52b3a..24a57f2a8dd0 100644 --- a/arch/arm/mach-omap/bus.c +++ b/arch/arm/mach-omap/bus.c @@ -81,40 +81,6 @@ static struct bus_type omap_bus_types[OMAP_NR_BUSES] = { }, }; -#ifdef CONFIG_ARCH_OMAP1510 -/* - * NOTE: This code _should_ go somewhere else. But let's wait for the - * dma-mapping code to settle down first. - */ - -/* - * Test for Local Bus device in order to do address translation between - * dma_handle and Local Bus address. - */ -inline int dmadev_uses_omap_lbus(struct device * dev) -{ - if (dev == NULL || !cpu_is_omap1510()) - return 0; - return dev->bus == &omap_bus_types[OMAP_BUS_LBUS] ? 1 : 0; -} - -/* - * Translate bus address to Local Bus address for dma-mapping - */ -inline int dmadev_to_lbus(dma_addr_t addr) -{ - return bus_to_lbus(addr); -} - -/* - * Translate Local Bus address to bus address for dma-mapping - */ -inline int lbus_to_dmadev(dma_addr_t addr) -{ - return lbus_to_bus(addr); -} -#endif - static int omap_bus_match(struct device *dev, struct device_driver *drv) { struct omap_dev *omapdev = OMAP_DEV(dev); @@ -278,8 +244,3 @@ EXPORT_SYMBOL(omap_driver_unregister); EXPORT_SYMBOL(omap_device_register); EXPORT_SYMBOL(omap_device_unregister); -#ifdef CONFIG_ARCH_OMAP1510 -EXPORT_SYMBOL(dmadev_uses_omap_lbus); -EXPORT_SYMBOL(dmadev_to_lbus); -EXPORT_SYMBOL(lbus_to_dmadev); -#endif diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c index d62e22614394..cb3c5d6f7be6 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap/time.c @@ -28,7 +28,12 @@ */ #include +#include +#include #include +#include +#include + #include #include #include -- cgit v1.2.3 From cbd6a6035a6c7b754b68b9cd582ca5dcdc6be319 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Jun 2004 02:15:06 +0100 Subject: [ARM] Fix EBSA110 timer functions. Unfortunately this broke in Deepak's merge. Fix it. --- arch/arm/mach-ebsa110/core.c | 3 +- arch/arm/mach-ebsa110/time.c | 118 ------------------------------------------- 2 files changed, 2 insertions(+), 119 deletions(-) delete mode 100644 arch/arm/mach-ebsa110/time.c diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 6f20b86a69c4..07c556392a03 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -11,6 +11,7 @@ */ #include #include +#include #include #include @@ -174,7 +175,7 @@ static struct irqaction ebsa110_timer_irq = { /* * Set up timer interrupt. */ -void __init ebsa110_time_init(void) +static void __init ebsa110_init_time(void) { /* * Timer 1, mode 2, LSB/MSB diff --git a/arch/arm/mach-ebsa110/time.c b/arch/arm/mach-ebsa110/time.c deleted file mode 100644 index c482e372b012..000000000000 --- a/arch/arm/mach-ebsa110/time.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/time.h - * - * Copyright (C) 1996,1997,1998 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * No real time clock on the evalulation board! - * - * Changelog: - * 10-Oct-1996 RMK Created - * 04-Dec-1997 RMK Updated for new arch/arm/kernel/time.c - * 07-Aug-1998 RMK Updated for arch/arm/kernel/leds.c - * 28-Dec-1998 APH Made leds code optional - */ - -#include -#include - -extern unsigned long (*gettimeoffset)(void); - -#define PIT_CTRL (PIT_BASE + 0x0d) -#define PIT_T2 (PIT_BASE + 0x09) -#define PIT_T1 (PIT_BASE + 0x05) -#define PIT_T0 (PIT_BASE + 0x01) - -/* - * This is the rate at which your MCLK signal toggles (in Hz) - * This was measured on a 10 digit frequency counter sampling - * over 1 second. - */ -#define MCLK 47894000 - -/* - * This is the rate at which the PIT timers get clocked - */ -#define CLKBY7 (MCLK / 7) - -/* - * This is the counter value. We tick at 200Hz on this platform. - */ -#define COUNT ((CLKBY7 + (HZ / 2)) / HZ) - -/* - * Get the time offset from the system PIT. Note that if we have missed an - * interrupt, then the PIT counter will roll over (ie, be negative). - * This actually works out to be convenient. - */ -static unsigned long ebsa110_gettimeoffset(void) -{ - unsigned long offset, count; - - __raw_writeb(0x40, PIT_CTRL); - count = __raw_readb(PIT_T1); - count |= __raw_readb(PIT_T1) << 8; - - /* - * If count > COUNT, make the number negative. - */ - if (count > COUNT) - count |= 0xffff0000; - - offset = COUNT; - offset -= count; - - /* - * `offset' is in units of timer counts. Convert - * offset to units of microseconds. - */ - offset = offset * (1000000 / HZ) / COUNT; - - return offset; -} - -static irqreturn_t -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - u32 count; - - /* latch and read timer 1 */ - __raw_writeb(0x40, PIT_CTRL); - count = __raw_readb(PIT_T1); - count |= __raw_readb(PIT_T1) << 8; - - count += COUNT; - - __raw_writeb(count & 0xff, PIT_T1); - __raw_writeb(count >> 8, PIT_T1); - - do_leds(); - do_timer(regs); - do_profile(regs); - - return IRQ_HANDLED; -} - -/* - * Set up timer interrupt. - */ -void __init time_init(void) -{ - /* - * Timer 1, mode 2, LSB/MSB - */ - __raw_writeb(0x70, PIT_CTRL); - __raw_writeb(COUNT & 0xff, PIT_T1); - __raw_writeb(COUNT >> 8, PIT_T1); - - gettimeoffset = ebsa110_gettimeoffset; - - timer_irq.handler = timer_interrupt; - - setup_irq(IRQ_EBSA110_TIMER0, &timer_irq); -} - - -- cgit v1.2.3 From 9a399b0b64d50ff94c40019abc849df11c4de168 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Jun 2004 02:23:46 +0100 Subject: [ARM] Fix Footbridge timer functions. --- arch/arm/mach-footbridge/time.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c index d4b9c9f87fff..e9f5708b4421 100644 --- a/arch/arm/mach-footbridge/time.c +++ b/arch/arm/mach-footbridge/time.c @@ -275,7 +275,7 @@ void __init footbridge_init_time(void) *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; footbridge_timer_irq.name = "Timer1 Timer Tick"; - footbrdige_timer_irq.handler = timer1_interrupt; + footbridge_timer_irq.handler = timer1_interrupt; setup_irq(IRQ_TIMER1, &footbridge_timer_irq); @@ -289,8 +289,8 @@ void __init footbridge_init_time(void) gettimeoffset = isa_gettimeoffset; footbridge_timer_irq.name = "ISA Timer Tick"; - footbrdige_timer_irq.handler = isa_timer_interrupt; + footbridge_timer_irq.handler = isa_timer_interrupt; - setup_irq(IRQ_ISA, &footbridge_timer_irq); + setup_irq(IRQ_ISA_TIMER, &footbridge_timer_irq); } } -- cgit v1.2.3 From 54567d5db749f7c3e646a4882d3f97a2ee77b692 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Jun 2004 02:40:38 +0100 Subject: [ARM] Fix acornfb build error. --- drivers/video/acornfb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index d91a2f8ddb39..0c3aa4a7f796 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -1246,6 +1246,8 @@ acornfb_detect_monitortype(void) /* * This enables the unused memory to be freed on older Acorn machines. + * We are freeing memory on behalf of the architecture initialisation + * code here. */ static inline void free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) @@ -1268,7 +1270,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) */ page = virt_to_page(virtual_start); ClearPageReserved(page); - atomic_set(&page->count, 1); + set_page_count(page, 1); free_page(virtual_start); virtual_start += PAGE_SIZE; -- cgit v1.2.3 From 36f9f2094996483001457fb02398d4b7eae170bd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:48:56 -0700 Subject: [PATCH] Allow i386 to reenable interrupts on lock contention From: Zwane Mwaikambo Following up on Keith's code, I adapted the i386 code to allow enabling interrupts during contested locks depending on previous interrupt enable status. Obviously there will be a text increase (only for non CONFIG_SPINLINE case), although it doesn't seem so bad, there will be an increased exit latency when we attempt a lock acquisition after spinning due to the extra instructions. How much this will affect performance I'm not sure yet as I haven't had time to micro bench. text data bss dec hex filename 2628024 921731 0 3549755 362a3b vmlinux-after 2621369 921731 0 3543100 36103c vmlinux-before 2618313 919222 0 3537535 35fa7f vmlinux-spinline The code has been stress tested on a 16x NUMAQ (courtesy OSDL). Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-i386/spinlock.h | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 8bd4f23a562e..d6dbfd469565 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -42,7 +42,6 @@ typedef struct { #define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0) #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) -#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) #define spin_lock_string \ "\n1:\t" \ @@ -56,6 +55,23 @@ typedef struct { "jmp 1b\n" \ LOCK_SECTION_END +#define spin_lock_string_flags \ + "\n1:\t" \ + "lock ; decb %0\n\t" \ + "js 2f\n\t" \ + LOCK_SECTION_START("") \ + "2:\t" \ + "testl $0x200, %1\n\t" \ + "jz 3f\n\t" \ + "sti\n\t" \ + "3:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jle 3b\n\t" \ + "cli\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END + /* * This works. Despite all the confusion. * (except on PPro SMP or if we are using OOSTORE) @@ -126,6 +142,20 @@ here: :"=m" (lock->lock) : : "memory"); } +static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) +{ +#ifdef CONFIG_DEBUG_SPINLOCK + __label__ here; +here: + if (unlikely(lock->magic != SPINLOCK_MAGIC)) { + printk("eip: %p\n", &&here); + BUG(); + } +#endif + __asm__ __volatile__( + spin_lock_string_flags + :"=m" (lock->lock) : "r" (flags) : "memory"); +} /* * Read-write spinlocks, allowing multiple readers -- cgit v1.2.3 From 4d4f4cc4d8b2626252b76d09584faa0713e9fbeb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:07 -0700 Subject: [PATCH] jbd needs to wait for locked buffers From: Chris Mason jbd needs to wait for any io to complete on the buffer before changing the end_io function. Using set_buffer_locked means that it can change the end_io function while the page is in the middle of writeback, and the writeback bit on the page will never get cleared. Since we set the buffer dirty earlier on, if the page was previously dirty, pdflush or memory pressure might trigger a writepage call, which will race with jbd's set_buffer_locked. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/commit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index c1eb3c536474..72e56d62c373 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -503,7 +503,7 @@ write_out_data: start_journal_io: for (i = 0; i < bufs; i++) { struct buffer_head *bh = wbuf[i]; - set_buffer_locked(bh); + lock_buffer(bh); clear_buffer_dirty(bh); set_buffer_uptodate(bh); bh->b_end_io = journal_end_buffer_io_sync; -- cgit v1.2.3 From b884e83821944633fb02295fd0470398090ac782 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:21 -0700 Subject: [PATCH] Move saved_command_line to init/main.c From: Rusty Russell Currently every arch declares its own char saved_command_line[]. Make sure every arch defines COMMAND_LINE_SIZE in asm/setup.h, and declare saved_command_line in linux/init.h (init/main.c contains the definition). Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/setup.c | 1 - arch/arm/kernel/setup.c | 1 - arch/arm26/kernel/setup.c | 1 - arch/cris/kernel/setup.c | 3 -- arch/h8300/kernel/setup.c | 4 +-- arch/i386/boot/compressed/misc.c | 31 +++++++++---------- arch/i386/kernel/setup.c | 1 - arch/ia64/kernel/setup.c | 4 --- arch/m68k/kernel/setup.c | 1 - arch/m68k/q40/config.c | 1 - arch/m68knommu/kernel/setup.c | 4 +-- arch/mips/kernel/setup.c | 1 - arch/parisc/kernel/setup.c | 2 -- arch/ppc/kernel/setup.c | 1 - arch/ppc/platforms/lopec_setup.c | 1 - arch/ppc/platforms/pmac_setup.c | 2 -- arch/ppc/platforms/pplus.c | 2 -- arch/ppc/platforms/prep_setup.c | 1 - arch/ppc64/kernel/head.S | 3 +- arch/ppc64/kernel/setup.c | 1 - arch/s390/kernel/setup.c | 1 - arch/sh/kernel/setup.c | 2 -- arch/sparc/kernel/setup.c | 3 +- arch/sparc/kernel/sparc_ksyms.c | 2 +- arch/sparc64/kernel/setup.c | 3 +- arch/sparc64/kernel/sparc64_ksyms.c | 2 +- arch/um/kernel/user_util.c | 1 - arch/v850/kernel/setup.c | 4 +-- arch/x86_64/kernel/setup.c | 1 - drivers/sbus/char/openprom.c | 1 - fs/proc/kcore.c | 3 +- fs/proc/proc_misc.c | 1 - include/asm-alpha/setup.h | 6 ++++ include/asm-alpha/system.h | 1 - include/asm-cris/setup.h | 3 ++ include/asm-h8300/setup.h | 7 ++++- include/asm-i386/param.h | 1 + include/asm-ia64/setup.h | 6 ++++ include/asm-m68k/setup.h | 1 + include/asm-m68knommu/setup.h | 4 +++ include/asm-mips/bootinfo.h | 3 +- include/asm-mips/setup.h | 8 +++++ include/asm-parisc/setup.h | 12 +++----- include/asm-ppc/machdep.h | 1 - include/asm-ppc/setup.h | 3 ++ include/asm-ppc64/machdep.h | 3 +- include/asm-ppc64/setup.h | 2 +- include/asm-sh/setup.h | 8 +++++ include/asm-sparc/setup.h | 1 + include/asm-sparc64/setup.h | 1 + include/asm-um/setup.h | 6 ++++ include/asm-v850/setup.h | 6 ++++ include/asm-x86_64/bootsetup.h | 1 - include/asm-x86_64/setup.h | 6 +--- include/linux/init.h | 22 ++++++++++---- init/main.c | 60 +++++++++++++++++++++++++++++++++++-- 56 files changed, 172 insertions(+), 90 deletions(-) create mode 100644 include/asm-alpha/setup.h create mode 100644 include/asm-ia64/setup.h create mode 100644 include/asm-mips/setup.h create mode 100644 include/asm-sh/setup.h create mode 100644 include/asm-um/setup.h create mode 100644 include/asm-v850/setup.h diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 1dff8e6c9881..4e93fe9cc6b6 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -122,7 +122,6 @@ static void get_sysnames(unsigned long, unsigned long, unsigned long, static void determine_cpu_caches (unsigned int); static char command_line[COMMAND_LINE_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; /* * The format of "screen_info" is strange, and due to early diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d159659677b0..835010c55597 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -97,7 +97,6 @@ unsigned char aux_device_present; char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); -char saved_command_line[COMMAND_LINE_SIZE]; unsigned long phys_initrd_start __initdata = 0; unsigned long phys_initrd_size __initdata = 0; diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c index afb7db526bd3..e02d41867a72 100644 --- a/arch/arm26/kernel/setup.c +++ b/arch/arm26/kernel/setup.c @@ -76,7 +76,6 @@ struct processor processor; unsigned char aux_device_present; char elf_platform[ELF_PLATFORM_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned long phys_initrd_start __initdata = 0; unsigned long phys_initrd_size __initdata = 0; diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 95a9f4408075..f95b82503281 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -29,10 +29,7 @@ unsigned char aux_device_present; extern int root_mountflags; extern char _etext, _edata, _end; -#define COMMAND_LINE_SIZE 256 - static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; extern const unsigned long text_start, edata; /* set by the linker script */ extern unsigned long dram_start, dram_end; diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index bf5822c5659e..0d9e932372d3 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -54,8 +55,7 @@ unsigned long rom_length; unsigned long memory_start; unsigned long memory_end; -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index 200ac3efd01f..fa67045234a3 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -87,12 +87,11 @@ static void gzip_release(void **); */ static unsigned char *real_mode; /* Pointer to real-mode data */ -#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) +#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) #ifndef STANDARD_MEMORY_BIOS_CALL -#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) +#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) #endif -#define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) -#define EDID_INFO (*(struct edid_info *)(real_mode+0x440)) +#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) extern char input_data[]; extern int input_len; @@ -174,8 +173,8 @@ static void putstr(const char *s) int x,y,pos; char c; - x = SCREEN_INFO.orig_x; - y = SCREEN_INFO.orig_y; + x = RM_SCREEN_INFO.orig_x; + y = RM_SCREEN_INFO.orig_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { @@ -196,8 +195,8 @@ static void putstr(const char *s) } } - SCREEN_INFO.orig_x = x; - SCREEN_INFO.orig_y = y; + RM_SCREEN_INFO.orig_x = x; + RM_SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ outb_p(14, vidport); @@ -306,9 +305,9 @@ struct { static void setup_normal_output_buffer(void) { #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < 1024) error("Less than 2MB of memory"); + if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif output_data = (char *)0x100000; /* Points to 1M */ free_mem_end_ptr = (long)real_mode; @@ -323,9 +322,11 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) { high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); + if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < + (3*1024)) + error("Less than 4MB of memory"); #endif mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX @@ -358,7 +359,7 @@ asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; - if (SCREEN_INFO.orig_video_mode == 7) { + if (RM_SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; } else { @@ -366,8 +367,8 @@ asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) vidport = 0x3d4; } - lines = SCREEN_INFO.orig_video_lines; - cols = SCREEN_INFO.orig_video_cols; + lines = RM_SCREEN_INFO.orig_video_lines; + cols = RM_SCREEN_INFO.orig_video_cols; if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); else setup_output_buffer_if_we_run_high(mv); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index fc466fb4488a..c077386a4568 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -127,7 +127,6 @@ unsigned long saved_videomode; #define RAMDISK_LOAD_FLAG 0x4000 static char command_line[COMMAND_LINE_SIZE]; - char saved_command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index aa2cb4fc3e54..3f4dc188995b 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -88,10 +88,6 @@ unsigned char aux_device_present = 0xaa; /* XXX remove this when legacy I unsigned long ia64_max_iommu_merge_mask = ~0UL; EXPORT_SYMBOL(ia64_max_iommu_merge_mask); -#define COMMAND_LINE_SIZE 512 - -char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */ - /* * We use a special marker for the end of memory and it uses the extra (+1) slot */ diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 2ede4125bd13..7680eabc3337 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -62,7 +62,6 @@ struct mem_info m68k_memory[NUM_MEMINFO]; static struct mem_info m68k_ramdisk; static char m68k_command_line[CL_SIZE]; -char saved_command_line[CL_SIZE]; char m68k_debug_device[6] = ""; diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 1f8977e7948e..90d82d961abe 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -64,7 +64,6 @@ void q40_set_vectors (void); extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ ); -extern char *saved_command_line; extern char m68k_debug_device[]; static void q40_mem_console_write(struct console *co, const char *b, unsigned int count); diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index bd6a4a89f65f..bb680024f1d7 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -44,8 +45,7 @@ unsigned long rom_length; unsigned long memory_start; unsigned long memory_end; -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; /* setup some dummy routines */ static void dummy_waitbut(void) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a1336d16c57e..8a5acf174730 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -71,7 +71,6 @@ EXPORT_SYMBOL(mips_machgroup); struct boot_mem_map boot_mem_map; static char command_line[CL_SIZE]; - char saved_command_line[CL_SIZE]; char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE; /* diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 820adb178f70..98b6f4c2cf6f 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -45,8 +45,6 @@ #include #include -#define COMMAND_LINE_SIZE 1024 -char saved_command_line[COMMAND_LINE_SIZE]; char command_line[COMMAND_LINE_SIZE]; /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 18a2f147d412..a46602e33b80 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -54,7 +54,6 @@ extern void ppc6xx_idle(void); extern void power4_idle(void); extern boot_infos_t *boot_infos; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned char aux_device_present; struct ide_machdep_calls ppc_ide_md; char *sysmap; diff --git a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c index c231f67d73c6..d675b76a9838 100644 --- a/arch/ppc/platforms/lopec_setup.c +++ b/arch/ppc/platforms/lopec_setup.c @@ -33,7 +33,6 @@ #include #include -extern char saved_command_line[]; extern void lopec_find_bridges(void); /* diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index d89cfe2ae765..b05cee1f7216 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -103,8 +103,6 @@ int has_l2cache = 0; static int current_root_goodness = -1; -extern char saved_command_line[]; - extern int pmac_newworld; #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c index 6fc3ca978728..673641ff4bf5 100644 --- a/arch/ppc/platforms/pplus.c +++ b/arch/ppc/platforms/pplus.c @@ -48,8 +48,6 @@ TODC_ALLOC(); -extern char saved_command_line[]; - extern void pplus_setup_hose(void); extern void pplus_set_VIA_IDE_native(void); diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 7c3623bcce39..4362597e191e 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -76,7 +76,6 @@ extern void rs_nvram_write_val(int addr, extern void ibm_prep_init(void); extern void prep_find_bridges(void); -extern char saved_command_line[]; int _prep_type; diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 83601a8b05f4..0f0f276607de 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -2222,4 +2223,4 @@ stab_array: */ .globl cmd_line cmd_line: - .space 512 /* COMMAND_LINE_SIZE */ + .space COMMAND_LINE_SIZE diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index f13739566fa9..aec2d763e9f9 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -82,7 +82,6 @@ unsigned long decr_overclock_proc0_set = 0; int powersave_nap; -char saved_command_line[COMMAND_LINE_SIZE]; unsigned char aux_device_present; void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index d549ad5c2724..8b4c40d8f7bf 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -76,7 +76,6 @@ extern int _text,_etext, _edata, _end; #include static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; static struct resource code_resource = { "Kernel code", 0x100000, 0 }; static struct resource data_resource = { "Kernel data", 0, 0 }; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 574ac24f8e51..3c1b4c799e62 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -85,14 +85,12 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name); #define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) -#define COMMAND_LINE_SIZE 256 #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f }, diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index e4558e7f0df7..ba8a2fab320e 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -244,8 +244,7 @@ extern unsigned short ram_flags; extern int root_mountflags; -char saved_command_line[256]; -char reboot_command[256]; +char reboot_command[COMMAND_LINE_SIZE]; enum sparc_cpu sparc_cpu_model; struct tt_entry *sparc_ttable; diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 601c97a31dd0..fdaacfa478c7 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -74,7 +75,6 @@ extern void *__memscan_zero(void *, size_t); extern void *__memscan_generic(void *, int, size_t); extern int __memcmp(const void *, const void *, __kernel_size_t); extern int __strncmp(const char *, const char *, __kernel_size_t); -extern char saved_command_line[]; extern void bcopy (const char *, char *, int); extern int __ashrdi3(int, int); diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 3d097a4bb2c3..f463ca2e61c8 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -451,8 +451,7 @@ extern unsigned short ram_flags; extern int root_mountflags; -char saved_command_line[256]; -char reboot_command[256]; +char reboot_command[COMMAND_LINE_SIZE]; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 909a13aeb1d8..888d540a1672 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -76,7 +77,6 @@ extern int __memcmp(const void *, const void *, __kernel_size_t); extern int __strncmp(const char *, const char *, __kernel_size_t); extern __kernel_size_t __strlen(const char *); extern __kernel_size_t strlen(const char *); -extern char saved_command_line[]; extern void linux_sparc_syscall(void); extern void rtrap(void); extern void show_regs(struct pt_regs *); diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c index a953a08c1a14..9e4fbae93617 100644 --- a/arch/um/kernel/user_util.c +++ b/arch/um/kernel/user_util.c @@ -34,7 +34,6 @@ #define COMMAND_LINE_SIZE _POSIX_ARG_MAX /* Changed in linux_main and setup_arch, which run before SMP is started */ -char saved_command_line[COMMAND_LINE_SIZE] = { 0 }; char command_line[COMMAND_LINE_SIZE] = { 0 }; void add_arg(char *cmd_line, char *arg) diff --git a/arch/v850/kernel/setup.c b/arch/v850/kernel/setup.c index 960802a756ae..49675035cf9d 100644 --- a/arch/v850/kernel/setup.c +++ b/arch/v850/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -40,8 +41,7 @@ extern char _root_fs_image_start __attribute__ ((__weak__)); extern char _root_fs_image_end __attribute__ ((__weak__)); -char command_line[512]; -char saved_command_line[512]; +char command_line[COMMAND_LINE_SIZE]; /* Memory not used by the kernel. */ static unsigned long total_ram_pages; diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 094949f96ace..84417fc01841 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -100,7 +100,6 @@ extern int root_mountflags; extern char _text, _etext, _edata, _end; char command_line[COMMAND_LINE_SIZE]; -char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f, IORESOURCE_BUSY | IORESOURCE_IO }, diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index c140f63b366b..82bfa900c619 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -149,7 +149,6 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, char buffer[OPROMMAXPARAM+1], *buf; struct openpromio *opp; int bufsize, len, error = 0; - extern char saved_command_line[]; static int cnt; if (cmd == OPROMSETOPT) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 1f55db799b51..3b1f58300d36 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -84,8 +85,6 @@ kclist_del(void *addr) return 0; } -extern char saved_command_line[]; - static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) { size_t try, size; diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index a46bd705e93b..415d6ee489b4 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -518,7 +518,6 @@ static int filesystems_read_proc(char *page, char **start, off_t off, static int cmdline_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - extern char saved_command_line[]; int len; len = sprintf(page, "%s\n", saved_command_line); diff --git a/include/asm-alpha/setup.h b/include/asm-alpha/setup.h new file mode 100644 index 000000000000..2e023a4aa317 --- /dev/null +++ b/include/asm-alpha/setup.h @@ -0,0 +1,6 @@ +#ifndef __ALPHA_SETUP_H +#define __ALPHA_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index 606a0553c688..1e5ac92d2073 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -43,7 +43,6 @@ */ #define PARAM ZERO_PGE #define COMMAND_LINE ((char*)(PARAM + 0x0000)) -#define COMMAND_LINE_SIZE 256 #define INITRD_START (*(unsigned long *) (PARAM+0x100)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x108)) diff --git a/include/asm-cris/setup.h b/include/asm-cris/setup.h index 832c197edf48..b90728652d1a 100644 --- a/include/asm-cris/setup.h +++ b/include/asm-cris/setup.h @@ -1,3 +1,6 @@ #ifndef _CRIS_SETUP_H #define _CRIS_SETUP_H + +#define COMMAND_LINE_SIZE 256 + #endif diff --git a/include/asm-h8300/setup.h b/include/asm-h8300/setup.h index 4fc416e80bef..e2c600e96733 100644 --- a/include/asm-h8300/setup.h +++ b/include/asm-h8300/setup.h @@ -1 +1,6 @@ -/* Nothing do */ +#ifndef __H8300_SETUP_H +#define __H8300_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h index e0a47502836d..b6440526e42a 100644 --- a/include/asm-i386/param.h +++ b/include/asm-i386/param.h @@ -18,5 +18,6 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#define COMMAND_LINE_SIZE 256 #endif diff --git a/include/asm-ia64/setup.h b/include/asm-ia64/setup.h new file mode 100644 index 000000000000..ea29b57affcb --- /dev/null +++ b/include/asm-ia64/setup.h @@ -0,0 +1,6 @@ +#ifndef __IA64_SETUP_H +#define __IA64_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h index 47b4627ef846..ce2762822a2b 100644 --- a/include/asm-m68k/setup.h +++ b/include/asm-m68k/setup.h @@ -357,6 +357,7 @@ extern int m68k_is040or060; #define NUM_MEMINFO 4 #define CL_SIZE 256 +#define COMMAND_LINE_SIZE CL_SIZE #ifndef __ASSEMBLY__ extern int m68k_num_memory; /* # of memory blocks found (and used) */ diff --git a/include/asm-m68knommu/setup.h b/include/asm-m68knommu/setup.h index ff4565ead5d7..d2b0fcce41b2 100644 --- a/include/asm-m68knommu/setup.h +++ b/include/asm-m68knommu/setup.h @@ -1 +1,5 @@ #include + +/* We have a bigger command line buffer. */ +#undef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE 512 diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index aacab4d6ebf6..c9c257c201eb 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -12,6 +12,7 @@ #define _ASM_BOOTINFO_H #include +#include /* * The MACH_GROUP_ IDs are the equivalent to PCI vendor IDs; the remaining @@ -209,7 +210,7 @@ #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ -#define CL_SIZE (256) +#define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); diff --git a/include/asm-mips/setup.h b/include/asm-mips/setup.h new file mode 100644 index 000000000000..737fa4a6912e --- /dev/null +++ b/include/asm-mips/setup.h @@ -0,0 +1,8 @@ +#ifdef __KERNEL__ +#ifndef _MIPS_SETUP_H +#define _MIPS_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif /* __SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-parisc/setup.h b/include/asm-parisc/setup.h index ae25cc4275d3..7da2e5b8747e 100644 --- a/include/asm-parisc/setup.h +++ b/include/asm-parisc/setup.h @@ -1,10 +1,6 @@ -/* - * Just a place holder. We don't want to have to test x86 before - * we include stuff - */ +#ifndef _PARISC_SETUP_H +#define _PARISC_SETUP_H -#ifndef _i386_SETUP_H -#define _i386_SETUP_H +#define COMMAND_LINE_SIZE 1024 - -#endif /* _i386_SETUP_H */ +#endif /* _PARISC_SETUP_H */ diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 4ace72fc4e7b..fca154980c17 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -106,7 +106,6 @@ struct machdep_calls { }; extern struct machdep_calls ppc_md; -#define COMMAND_LINE_SIZE 512 extern char cmd_line[COMMAND_LINE_SIZE]; extern void setup_pci_ptrs(void); diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h index cd458c4f1642..d2d19ee103df 100644 --- a/include/asm-ppc/setup.h +++ b/include/asm-ppc/setup.h @@ -6,6 +6,9 @@ #define m68k_memory memory #include +/* We have a bigger command line buffer. */ +#undef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE 512 #endif /* _PPC_SETUP_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index bb961a029fae..f0b00cc458c7 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h @@ -11,6 +11,7 @@ #include #include +#include #include struct pt_regs; @@ -112,9 +113,7 @@ struct machdep_calls { }; extern struct machdep_calls ppc_md; -#define COMMAND_LINE_SIZE 512 extern char cmd_line[COMMAND_LINE_SIZE]; -extern char saved_command_line[COMMAND_LINE_SIZE]; /* Functions to produce codes on the leds. * The SRC code should be unique for the message category and should diff --git a/include/asm-ppc64/setup.h b/include/asm-ppc64/setup.h index d6e62d15a5dd..b257b8348c73 100644 --- a/include/asm-ppc64/setup.h +++ b/include/asm-ppc64/setup.h @@ -1,6 +1,6 @@ #ifndef _PPC_SETUP_H #define _PPC_SETUP_H -/* This is a place holder include */ +#define COMMAND_LINE_SIZE 512 #endif /* _PPC_SETUP_H */ diff --git a/include/asm-sh/setup.h b/include/asm-sh/setup.h new file mode 100644 index 000000000000..d19de7c8df4e --- /dev/null +++ b/include/asm-sh/setup.h @@ -0,0 +1,8 @@ +#ifdef __KERNEL__ +#ifndef _SH_SETUP_H +#define _SH_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +#endif /* _SH_SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-sparc/setup.h b/include/asm-sparc/setup.h index d8aaa7205345..b3af958a2ad2 100644 --- a/include/asm-sparc/setup.h +++ b/include/asm-sparc/setup.h @@ -5,5 +5,6 @@ #ifndef _SPARC_SETUP_H #define _SPARC_SETUP_H +#define COMMAND_LINE_SIZE 256 #endif /* _SPARC_SETUP_H */ diff --git a/include/asm-sparc64/setup.h b/include/asm-sparc64/setup.h index 97ae5d456702..b356ee2cda92 100644 --- a/include/asm-sparc64/setup.h +++ b/include/asm-sparc64/setup.h @@ -5,5 +5,6 @@ #ifndef _SPARC64_SETUP_H #define _SPARC64_SETUP_H +#define COMMAND_LINE_SIZE 256 #endif /* _SPARC64_SETUP_H */ diff --git a/include/asm-um/setup.h b/include/asm-um/setup.h new file mode 100644 index 000000000000..e5787bb80e79 --- /dev/null +++ b/include/asm-um/setup.h @@ -0,0 +1,6 @@ +#ifndef SETUP_H_INCLUDED +#define SETUP_H_INCLUDED + +#define COMMAND_LINE_SIZE 512 + +#endif /* SETUP_H_INCLUDED */ diff --git a/include/asm-v850/setup.h b/include/asm-v850/setup.h new file mode 100644 index 000000000000..c48a9b97d05b --- /dev/null +++ b/include/asm-v850/setup.h @@ -0,0 +1,6 @@ +#ifndef _V850_SETUP_H +#define _V850_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#endif /* __SETUP_H */ diff --git a/include/asm-x86_64/bootsetup.h b/include/asm-x86_64/bootsetup.h index ee1557748b0e..8fe68a93b798 100644 --- a/include/asm-x86_64/bootsetup.h +++ b/include/asm-x86_64/bootsetup.h @@ -30,7 +30,6 @@ extern char x86_boot_params[2048]; #define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) #define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE saved_command_line -#define COMMAND_LINE_SIZE 256 #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 diff --git a/include/asm-x86_64/setup.h b/include/asm-x86_64/setup.h index 7079a136ca8e..985d4e3c79da 100644 --- a/include/asm-x86_64/setup.h +++ b/include/asm-x86_64/setup.h @@ -1,10 +1,6 @@ -/* - * Just a place holder. We don't want to have to test x86 before - * we include stuff - */ - #ifndef _x8664_SETUP_H #define _x8664_SETUP_H +#define COMMAND_LINE_SIZE 256 #endif diff --git a/include/linux/init.h b/include/linux/init.h index 45069e275b3d..641657ebe067 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -3,6 +3,7 @@ #include #include +#include /* These macros are used to mark some functions or * initialized data (doesn't apply to uninitialized data) @@ -66,6 +67,9 @@ typedef void (*exitcall_t)(void); extern initcall_t __con_initcall_start, __con_initcall_end; extern initcall_t __security_initcall_start, __security_initcall_end; + +/* Defined in init/main.c */ +extern char saved_command_line[COMMAND_LINE_SIZE]; #endif #ifndef MODULE @@ -107,25 +111,33 @@ extern initcall_t __security_initcall_start, __security_initcall_end; struct obs_kernel_param { const char *str; int (*setup_func)(char *); + int early; }; -/* OBSOLETE: see moduleparam.h for the right way. */ -#define __setup_param(str, unique_id, fn) \ +/* Only for really core code. See moduleparam.h for the normal way. */ +#define __setup_param(str, unique_id, fn, early) \ static char __setup_str_##unique_id[] __initdata = str; \ static struct obs_kernel_param __setup_##unique_id \ __attribute_used__ \ __attribute__((__section__(".init.setup"))) \ - = { __setup_str_##unique_id, fn } + = { __setup_str_##unique_id, fn, early } #define __setup_null_param(str, unique_id) \ - __setup_param(str, unique_id, NULL) + __setup_param(str, unique_id, NULL, 0) #define __setup(str, fn) \ - __setup_param(str, fn, fn) + __setup_param(str, fn, fn, 0) #define __obsolete_setup(str) \ __setup_null_param(str, __LINE__) +/* NOTE: fn is as per module_param, not __setup! Emits warning if fn + * returns non-zero. */ +#define early_param(str, fn) \ + __setup_param(str, fn, fn, 1) + +/* Relies on saved_command_line being set */ +void __init parse_early_param(void); #endif /* __ASSEMBLY__ */ /** diff --git a/init/main.c b/init/main.c index 1e58b66b2144..4d99b928aeb4 100644 --- a/init/main.c +++ b/init/main.c @@ -111,6 +111,9 @@ extern void time_init(void); void (*late_time_init)(void); extern void softirq_init(void); +/* Untouched command line (eg. for /proc) saved by arch-specific code. */ +char saved_command_line[COMMAND_LINE_SIZE]; + static char *execute_command; /* Setup configured maximum number of CPUs to activate */ @@ -157,8 +160,14 @@ static int __init obsolete_checksetup(char *line) do { int n = strlen(p->str); if (!strncmp(line, p->str, n)) { - if (!p->setup_func) { - printk(KERN_WARNING "Parameter %s is obsolete, ignored\n", p->str); + if (p->early) { + /* Already done in parse_early_param? (Needs + * exact match on param part) */ + if (line[n] == '\0' || line[n] == '=') + return 1; + } else if (!p->setup_func) { + printk(KERN_WARNING "Parameter %s is obsolete," + " ignored\n", p->str); return 1; } else if (p->setup_func(line + n)) return 1; @@ -393,6 +402,38 @@ static void noinline rest_init(void) cpu_idle(); } +/* Check for early params. */ +static int __init do_early_param(char *param, char *val) +{ + struct obs_kernel_param *p; + extern struct obs_kernel_param __setup_start, __setup_end; + + for (p = &__setup_start; p < &__setup_end; p++) { + if (p->early && strcmp(param, p->str) == 0) { + if (p->setup_func(val) != 0) + printk(KERN_WARNING + "Malformed early option '%s'\n", param); + } + } + /* We accept everything at this stage. */ + return 0; +} + +/* Arch code calls this early on, or if not, just before other parsing. */ +void __init parse_early_param(void) +{ + static __initdata int done = 0; + static __initdata char tmp_cmdline[COMMAND_LINE_SIZE]; + + if (done) + return; + + /* All fall through to do_early_param. */ + strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE); + parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); + done = 1; +} + /* * Activate the first processor. */ @@ -400,7 +441,6 @@ static void noinline rest_init(void) asmlinkage void __init start_kernel(void) { char * command_line; - extern char saved_command_line[]; extern struct kernel_param __start___param[], __stop___param[]; /* * Interrupts are still disabled. Do necessary setups, then @@ -428,6 +468,7 @@ asmlinkage void __init start_kernel(void) build_all_zonelists(); page_alloc_init(); printk("Kernel command line: %s\n", saved_command_line); + parse_early_param(); parse_args("Booting kernel", command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); @@ -676,3 +717,16 @@ static int init(void * unused) panic("No init found. Try passing init= option to kernel."); } + +static int early_param_test(char *rest) +{ + printk("early_parm_test: %s\n", rest ?: "(null)"); + return rest ? 0 : -EINVAL; +} +early_param("testsetup", early_param_test); +static int early_setup_test(char *rest) +{ + printk("early_setup_test: %s\n", rest ?: "(null)"); + return 0; +} +__setup("testsetup_long", early_setup_test); -- cgit v1.2.3 From 5c60169a01af712b0b1aa1f5db3fcb8776b22d9f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:33 -0700 Subject: [PATCH] rcu lock update: Add per-cpu batch counter From: Manfred Spraul Below is the one of my patches from my rcu lock update. Jack Steiner tested the first one on a 512p and it resolved the rcu cache line trashing. All were tested on osdl with STP. Step one for reducing cacheline trashing within rcupdate.c: The current code uses the rcu_cpu_mask bitmap both for keeping track of the cpus that haven't gone through a quiescent state and for checking if a cpu should look for quiescent states. The bitmap is frequently changed and the check is done by polling - together this causes cache line trashing. If it's cheaper to access a (mostly) read-only cacheline than a cacheline that is frequently dirtied, then it's possible to reduce the trashing by splitting the rcu_cpu_mask bitmap into two cachelines: The patch adds a generation counter and moves it into a separate cacheline. This allows to removes all accesses to rcu_cpumask (in the read-write cacheline) from rcu_pending and at least 50% of the accesses from rcu_check_quiescent_state. rcu_pending and all but one call per cpu to rcu_check_quiescent_state access the read-only cacheline. Probably not enough for 512p, but it's a start, just for 128 byte more memory use, without slowing down rcu grace periods. Obviously the read-only cacheline is not really read-only: it's written once per grace period to indicate that a new grace period is running. Tests on an 8-way Pentium III with reaim showed some improvement: oprofile hits: Reference: http://khack.osdl.org/stp/293075/ Hits % 23741 0.0994 rcu_pending 19057 0.0798 rcu_check_quiescent_state 6530 0.0273 rcu_check_callbacks Patched: http://khack.osdl.org/stp/293076/ 8291 0.0579 rcu_pending 5475 0.0382 rcu_check_quiescent_state 3604 0.0252 rcu_check_callbacks The total runtime differs between both runs, thus the % number must be compared: Around 50% faster. I've uninlined rcu_pending for the test. Tested with reaim and kernbench. Description: - per-cpu quiescbatch and qs_pending fields introduced: quiescbatch contains the number of the last quiescent period that the cpu has seen and qs_pending is set if the cpu has not yet reported the quiescent state for the current period. With these two fields a cpu can test if it should report a quiescent state without having to look at the frequently written rcu_cpu_mask bitmap. - curbatch split into two fields: rcu_ctrlblk.batch.completed and rcu_ctrlblk.batch.cur. This makes it possible to figure out if a grace period is running (completed != cur) without accessing the rcu_cpu_mask bitmap. - rcu_ctrlblk.maxbatch removed and replaced with a true/false next_pending flag: next_pending=1 means that another grace period should be started immediately after the end of the current period. Previously, this was achieved by maxbatch: curbatch==maxbatch means don't start, curbatch!= maxbatch means start. A flag improves the readability: The only possible values for maxbatch were curbatch and curbatch+1. - rcu_ctrlblk split into two cachelines for better performance. - common code from rcu_offline_cpu and rcu_check_quiescent_state merged into cpu_quiet. - rcu_offline_cpu: replace spin_lock_irq with spin_lock_bh, there are no accesses from irq context (and there are accesses to the spinlock with enabled interrupts from tasklet context). - rcu_restart_cpu introduced, s390 should call it after changing nohz: Theoretically the global batch counter could wrap around and end up at RCU_quiescbatch(cpu). Then the cpu would not look for a quiescent state and rcu would lock up. Signed-off-by: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 48 +++++++++++----- kernel/rcupdate.c | 142 +++++++++++++++++++++++++++++------------------ 2 files changed, 122 insertions(+), 68 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 58048abd7446..f9981251d542 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -65,11 +65,18 @@ struct rcu_head { /* Control variables for rcupdate callback mechanism. */ struct rcu_ctrlblk { - spinlock_t mutex; /* Guard this struct */ - long curbatch; /* Current batch number. */ - long maxbatch; /* Max requested batch number. */ - cpumask_t rcu_cpu_mask; /* CPUs that need to switch in order */ - /* for current batch to proceed. */ + /* "const" members: only changed when starting/ending a grace period */ + struct { + long cur; /* Current batch number. */ + long completed; /* Number of the last completed batch */ + } batch ____cacheline_maxaligned_in_smp; + /* remaining members: bookkeeping of the progress of the grace period */ + struct { + spinlock_t mutex; /* Guard this struct */ + int next_pending; /* Is the next batch already waiting? */ + cpumask_t rcu_cpu_mask; /* CPUs that need to switch */ + /* in order for current batch to proceed. */ + } state ____cacheline_maxaligned_in_smp; }; /* Is batch a before batch b ? */ @@ -90,9 +97,14 @@ static inline int rcu_batch_after(long a, long b) * curlist - current batch for which quiescent cycle started if any */ struct rcu_data { + /* 1) quiescent state handling : */ + long quiescbatch; /* Batch # for grace period */ long qsctr; /* User-mode/idle loop etc. */ long last_qsctr; /* value of qsctr at beginning */ /* of rcu grace period */ + int qs_pending; /* core waits for quiesc state */ + + /* 2) batch handling */ long batch; /* Batch # for current RCU batch */ struct list_head nxtlist; struct list_head curlist; @@ -101,24 +113,31 @@ struct rcu_data { DECLARE_PER_CPU(struct rcu_data, rcu_data); extern struct rcu_ctrlblk rcu_ctrlblk; +#define RCU_quiescbatch(cpu) (per_cpu(rcu_data, (cpu)).quiescbatch) #define RCU_qsctr(cpu) (per_cpu(rcu_data, (cpu)).qsctr) #define RCU_last_qsctr(cpu) (per_cpu(rcu_data, (cpu)).last_qsctr) +#define RCU_qs_pending(cpu) (per_cpu(rcu_data, (cpu)).qs_pending) #define RCU_batch(cpu) (per_cpu(rcu_data, (cpu)).batch) #define RCU_nxtlist(cpu) (per_cpu(rcu_data, (cpu)).nxtlist) #define RCU_curlist(cpu) (per_cpu(rcu_data, (cpu)).curlist) -#define RCU_QSCTR_INVALID 0 - static inline int rcu_pending(int cpu) { - if ((!list_empty(&RCU_curlist(cpu)) && - rcu_batch_before(RCU_batch(cpu), rcu_ctrlblk.curbatch)) || - (list_empty(&RCU_curlist(cpu)) && - !list_empty(&RCU_nxtlist(cpu))) || - cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) + /* This cpu has pending rcu entries and the grace period + * for them has completed. + */ + if (!list_empty(&RCU_curlist(cpu)) && + !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) + return 1; + /* This cpu has no pending entries, but there are new entries */ + if (list_empty(&RCU_curlist(cpu)) && + !list_empty(&RCU_nxtlist(cpu))) + return 1; + /* The rcu core waits for a quiescent state from the cpu */ + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur || RCU_qs_pending(cpu)) return 1; - else - return 0; + /* nothing to do */ + return 0; } #define rcu_read_lock() preempt_disable() @@ -126,6 +145,7 @@ static inline int rcu_pending(int cpu) extern void rcu_init(void); extern void rcu_check_callbacks(int cpu, int user); +extern void rcu_restart_cpu(int cpu); /* Exported interfaces */ extern void FASTCALL(call_rcu(struct rcu_head *head, diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 13a1b5a5825f..d665d001e030 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -47,8 +47,8 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = - { .mutex = SPIN_LOCK_UNLOCKED, .curbatch = 1, - .maxbatch = 1, .rcu_cpu_mask = CPU_MASK_NONE }; + { .batch = { .cur = -300, .completed = -300 }, + .state = {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE } }; DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; /* Fake initialization required by compiler */ @@ -96,26 +96,60 @@ static void rcu_do_batch(struct list_head *list) } } +/* + * Grace period handling: + * The grace period handling consists out of two steps: + * - A new grace period is started. + * This is done by rcu_start_batch. The start is not broadcasted to + * all cpus, they must pick this up by comparing rcu_ctrlblk.batch.cur with + * RCU_quiescbatch(cpu). All cpus are recorded in the + * rcu_ctrlblk.state.rcu_cpu_mask bitmap. + * - All cpus must go through a quiescent state. + * Since the start of the grace period is not broadcasted, at least two + * calls to rcu_check_quiescent_state are required: + * The first call just notices that a new grace period is running. The + * following calls check if there was a quiescent state since the beginning + * of the grace period. If so, it updates rcu_ctrlblk.state.rcu_cpu_mask. If + * the bitmap is empty, then the grace period is completed. + * rcu_check_quiescent_state calls rcu_start_batch(0) to start the next grace + * period (if necessary). + */ /* * Register a new batch of callbacks, and start it up if there is currently no * active batch and the batch to be registered has not already occurred. - * Caller must hold the rcu_ctrlblk lock. + * Caller must hold the rcu_ctrlblk.state lock. */ -static void rcu_start_batch(long newbatch) +static void rcu_start_batch(int next_pending) { cpumask_t active; - if (rcu_batch_before(rcu_ctrlblk.maxbatch, newbatch)) { - rcu_ctrlblk.maxbatch = newbatch; + if (next_pending) + rcu_ctrlblk.state.next_pending = 1; + + if (rcu_ctrlblk.state.next_pending && + rcu_ctrlblk.batch.completed == rcu_ctrlblk.batch.cur) { + rcu_ctrlblk.state.next_pending = 0; + /* Can't change, since spin lock held. */ + active = nohz_cpu_mask; + cpus_complement(active); + cpus_and(rcu_ctrlblk.state.rcu_cpu_mask, cpu_online_map, active); + rcu_ctrlblk.batch.cur++; } - if (rcu_batch_before(rcu_ctrlblk.maxbatch, rcu_ctrlblk.curbatch) || - !cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) { - return; +} + +/* + * cpu went through a quiescent state since the beginning of the grace period. + * Clear it from the cpu mask and complete the grace period if it was the last + * cpu. Start another grace period if someone has further entries pending + */ +static void cpu_quiet(int cpu) +{ + cpu_clear(cpu, rcu_ctrlblk.state.rcu_cpu_mask); + if (cpus_empty(rcu_ctrlblk.state.rcu_cpu_mask)) { + /* batch completed ! */ + rcu_ctrlblk.batch.completed = rcu_ctrlblk.batch.cur; + rcu_start_batch(0); } - /* Can't change, since spin lock held. */ - active = nohz_cpu_mask; - cpus_complement(active); - cpus_and(rcu_ctrlblk.rcu_cpu_mask, cpu_online_map, active); } /* @@ -127,7 +161,19 @@ static void rcu_check_quiescent_state(void) { int cpu = smp_processor_id(); - if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur) { + /* new grace period: record qsctr value. */ + RCU_qs_pending(cpu) = 1; + RCU_last_qsctr(cpu) = RCU_qsctr(cpu); + RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.cur; + return; + } + + /* Grace period already completed for this cpu? + * qs_pending is checked instead of the actual bitmap to avoid + * cacheline trashing. + */ + if (!RCU_qs_pending(cpu)) return; /* @@ -135,27 +181,19 @@ static void rcu_check_quiescent_state(void) * we may miss one quiescent state of that CPU. That is * tolerable. So no need to disable interrupts. */ - if (RCU_last_qsctr(cpu) == RCU_QSCTR_INVALID) { - RCU_last_qsctr(cpu) = RCU_qsctr(cpu); - return; - } if (RCU_qsctr(cpu) == RCU_last_qsctr(cpu)) return; + RCU_qs_pending(cpu) = 0; - spin_lock(&rcu_ctrlblk.mutex); - if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) - goto out_unlock; - - cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask); - RCU_last_qsctr(cpu) = RCU_QSCTR_INVALID; - if (!cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) - goto out_unlock; - - rcu_ctrlblk.curbatch++; - rcu_start_batch(rcu_ctrlblk.maxbatch); + spin_lock(&rcu_ctrlblk.state.mutex); + /* + * RCU_quiescbatch/batch.cur and the cpu bitmap can come out of sync + * during cpu startup. Ignore the quiescent state. + */ + if (likely(RCU_quiescbatch(cpu) == rcu_ctrlblk.batch.cur)) + cpu_quiet(cpu); -out_unlock: - spin_unlock(&rcu_ctrlblk.mutex); + spin_unlock(&rcu_ctrlblk.state.mutex); } @@ -185,25 +223,11 @@ static void rcu_offline_cpu(int cpu) * we can block indefinitely waiting for it, so flush * it here */ - spin_lock_irq(&rcu_ctrlblk.mutex); - if (cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) - goto unlock; - - cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask); - if (cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) { - rcu_ctrlblk.curbatch++; - /* We may avoid calling start batch if - * we are starting the batch only - * because of the DEAD CPU (the current - * CPU will start a new batch anyway for - * the callbacks we will move to current CPU). - * However, we will avoid this optimisation - * for now. - */ - rcu_start_batch(rcu_ctrlblk.maxbatch); - } + spin_lock_bh(&rcu_ctrlblk.state.mutex); + if (rcu_ctrlblk.batch.cur != rcu_ctrlblk.batch.completed) + cpu_quiet(cpu); unlock: - spin_unlock_irq(&rcu_ctrlblk.mutex); + spin_unlock_bh(&rcu_ctrlblk.state.mutex); rcu_move_batch(&RCU_curlist(cpu)); rcu_move_batch(&RCU_nxtlist(cpu)); @@ -213,6 +237,14 @@ unlock: #endif +void rcu_restart_cpu(int cpu) +{ + spin_lock_bh(&rcu_ctrlblk.state.mutex); + RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + RCU_qs_pending(cpu) = 0; + spin_unlock_bh(&rcu_ctrlblk.state.mutex); +} + /* * This does the RCU processing work from tasklet context. */ @@ -222,7 +254,7 @@ static void rcu_process_callbacks(unsigned long unused) LIST_HEAD(list); if (!list_empty(&RCU_curlist(cpu)) && - rcu_batch_after(rcu_ctrlblk.curbatch, RCU_batch(cpu))) { + !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) { __list_splice(&RCU_curlist(cpu), &list); INIT_LIST_HEAD(&RCU_curlist(cpu)); } @@ -236,10 +268,10 @@ static void rcu_process_callbacks(unsigned long unused) /* * start the next batch of callbacks */ - spin_lock(&rcu_ctrlblk.mutex); - RCU_batch(cpu) = rcu_ctrlblk.curbatch + 1; - rcu_start_batch(RCU_batch(cpu)); - spin_unlock(&rcu_ctrlblk.mutex); + spin_lock(&rcu_ctrlblk.state.mutex); + RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; + rcu_start_batch(1); + spin_unlock(&rcu_ctrlblk.state.mutex); } else { local_irq_enable(); } @@ -263,6 +295,8 @@ static void __devinit rcu_online_cpu(int cpu) tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL); INIT_LIST_HEAD(&RCU_nxtlist(cpu)); INIT_LIST_HEAD(&RCU_curlist(cpu)); + RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + RCU_qs_pending(cpu) = 0; } static int __devinit rcu_cpu_notify(struct notifier_block *self, -- cgit v1.2.3 From 720e8a63908eb18aad1721c1429e89fbf7cf0ca6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:44 -0700 Subject: [PATCH] rcu lock update: Use a sequence lock for starting batches From: Manfred Spraul Step two for reducing cacheline trashing within rcupdate.c: rcu_process_callbacks always acquires rcu_ctrlblk.state.mutex and calls rcu_start_batch, even if the batch is already running or already scheduled to run. This can be avoided with a sequence lock: A sequence lock allows to read the current batch number and next_pending atomically. If next_pending is already set, then there is no need to acquire the global mutex. This means that for each grace period, there will be - one write access to the rcu_ctrlblk.batch cacheline - lots of read accesses to rcu_ctrlblk.batch (3-10*cpus_online()). Behavior similar to the jiffies cacheline, shouldn't be a problem. - cpus_online()+1 write accesses to rcu_ctrlblk.state, all of them starting with spin_lock(&rcu_ctrlblk.state.mutex). For large enough cpus_online() this will be a problem, but all except two of the spin_lock calls only protect the rcu_cpu_mask bitmap, thus a hierarchical bitmap would allow to split the write accesses to multiple cachelines. Tested on an 8-way with reaim. Unfortunately it probably won't help with Jack Steiner's 'ls' test since in this test only one cpu generates rcu entries. Signed-off-by: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 6 +++++- kernel/rcupdate.c | 29 +++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index f9981251d542..883fc03ed4ef 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -41,6 +41,7 @@ #include #include #include +#include /** * struct rcu_head - callback structure for use with RCU @@ -69,11 +70,14 @@ struct rcu_ctrlblk { struct { long cur; /* Current batch number. */ long completed; /* Number of the last completed batch */ + int next_pending; /* Is the next batch already waiting? */ + seqcount_t lock; /* for atomically reading cur and */ + /* next_pending. Spinlock not used, */ + /* protected by state.mutex */ } batch ____cacheline_maxaligned_in_smp; /* remaining members: bookkeeping of the progress of the grace period */ struct { spinlock_t mutex; /* Guard this struct */ - int next_pending; /* Is the next batch already waiting? */ cpumask_t rcu_cpu_mask; /* CPUs that need to switch */ /* in order for current batch to proceed. */ } state ____cacheline_maxaligned_in_smp; diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index d665d001e030..dc1ac448d07c 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -47,7 +47,7 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = - { .batch = { .cur = -300, .completed = -300 }, + { .batch = { .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO }, .state = {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE } }; DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; @@ -124,16 +124,18 @@ static void rcu_start_batch(int next_pending) cpumask_t active; if (next_pending) - rcu_ctrlblk.state.next_pending = 1; + rcu_ctrlblk.batch.next_pending = 1; - if (rcu_ctrlblk.state.next_pending && + if (rcu_ctrlblk.batch.next_pending && rcu_ctrlblk.batch.completed == rcu_ctrlblk.batch.cur) { - rcu_ctrlblk.state.next_pending = 0; /* Can't change, since spin lock held. */ active = nohz_cpu_mask; cpus_complement(active); cpus_and(rcu_ctrlblk.state.rcu_cpu_mask, cpu_online_map, active); + write_seqcount_begin(&rcu_ctrlblk.batch.lock); + rcu_ctrlblk.batch.next_pending = 0; rcu_ctrlblk.batch.cur++; + write_seqcount_end(&rcu_ctrlblk.batch.lock); } } @@ -261,6 +263,8 @@ static void rcu_process_callbacks(unsigned long unused) local_irq_disable(); if (!list_empty(&RCU_nxtlist(cpu)) && list_empty(&RCU_curlist(cpu))) { + int next_pending, seq; + __list_splice(&RCU_nxtlist(cpu), &RCU_curlist(cpu)); INIT_LIST_HEAD(&RCU_nxtlist(cpu)); local_irq_enable(); @@ -268,10 +272,19 @@ static void rcu_process_callbacks(unsigned long unused) /* * start the next batch of callbacks */ - spin_lock(&rcu_ctrlblk.state.mutex); - RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; - rcu_start_batch(1); - spin_unlock(&rcu_ctrlblk.state.mutex); + do { + seq = read_seqcount_begin(&rcu_ctrlblk.batch.lock); + /* determine batch number */ + RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; + next_pending = rcu_ctrlblk.batch.next_pending; + } while (read_seqcount_retry(&rcu_ctrlblk.batch.lock, seq)); + + if (!next_pending) { + /* and start it/schedule start if it's a new batch */ + spin_lock(&rcu_ctrlblk.state.mutex); + rcu_start_batch(1); + spin_unlock(&rcu_ctrlblk.state.mutex); + } } else { local_irq_enable(); } -- cgit v1.2.3 From 72914d307d2ab4630212644a46cf75746d04440d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:49:55 -0700 Subject: [PATCH] rcu lock update: Code move & cleanup From: Manfred Spraul Step three for reducing cacheline trashing within rcupdate.c: Cleanup and code move from to kernel/rcupdate.c: Remove internal details from the header file. Signed-off-by: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 27 +++++----------- kernel/rcupdate.c | 81 +++++++++++++++++++++++++++--------------------- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 883fc03ed4ef..967b2d47014b 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -64,24 +64,13 @@ struct rcu_head { -/* Control variables for rcupdate callback mechanism. */ +/* Global control variables for rcupdate callback mechanism. */ struct rcu_ctrlblk { - /* "const" members: only changed when starting/ending a grace period */ - struct { - long cur; /* Current batch number. */ - long completed; /* Number of the last completed batch */ - int next_pending; /* Is the next batch already waiting? */ - seqcount_t lock; /* for atomically reading cur and */ - /* next_pending. Spinlock not used, */ - /* protected by state.mutex */ - } batch ____cacheline_maxaligned_in_smp; - /* remaining members: bookkeeping of the progress of the grace period */ - struct { - spinlock_t mutex; /* Guard this struct */ - cpumask_t rcu_cpu_mask; /* CPUs that need to switch */ - /* in order for current batch to proceed. */ - } state ____cacheline_maxaligned_in_smp; -}; + long cur; /* Current batch number. */ + long completed; /* Number of the last completed batch */ + int next_pending; /* Is the next batch already waiting? */ + seqcount_t lock; /* For atomic reads of cur and next_pending. */ +} ____cacheline_maxaligned_in_smp; /* Is batch a before batch b ? */ static inline int rcu_batch_before(long a, long b) @@ -131,14 +120,14 @@ static inline int rcu_pending(int cpu) * for them has completed. */ if (!list_empty(&RCU_curlist(cpu)) && - !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) + !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) return 1; /* This cpu has no pending entries, but there are new entries */ if (list_empty(&RCU_curlist(cpu)) && !list_empty(&RCU_nxtlist(cpu))) return 1; /* The rcu core waits for a quiescent state from the cpu */ - if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur || RCU_qs_pending(cpu)) + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.cur || RCU_qs_pending(cpu)) return 1; /* nothing to do */ return 0; diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index dc1ac448d07c..0e13bdbb9fd7 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -47,8 +47,17 @@ /* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = - { .batch = { .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO }, - .state = {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE } }; + { .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO }; + +/* Bookkeeping of the progress of the grace period */ +struct { + spinlock_t mutex; /* Guard this struct and writes to rcu_ctrlblk */ + cpumask_t rcu_cpu_mask; /* CPUs that need to switch in order */ + /* for current batch to proceed. */ +} rcu_state ____cacheline_maxaligned_in_smp = + {.mutex = SPIN_LOCK_UNLOCKED, .rcu_cpu_mask = CPU_MASK_NONE }; + + DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; /* Fake initialization required by compiler */ @@ -101,15 +110,15 @@ static void rcu_do_batch(struct list_head *list) * The grace period handling consists out of two steps: * - A new grace period is started. * This is done by rcu_start_batch. The start is not broadcasted to - * all cpus, they must pick this up by comparing rcu_ctrlblk.batch.cur with + * all cpus, they must pick this up by comparing rcu_ctrlblk.cur with * RCU_quiescbatch(cpu). All cpus are recorded in the - * rcu_ctrlblk.state.rcu_cpu_mask bitmap. + * rcu_state.rcu_cpu_mask bitmap. * - All cpus must go through a quiescent state. * Since the start of the grace period is not broadcasted, at least two * calls to rcu_check_quiescent_state are required: * The first call just notices that a new grace period is running. The * following calls check if there was a quiescent state since the beginning - * of the grace period. If so, it updates rcu_ctrlblk.state.rcu_cpu_mask. If + * of the grace period. If so, it updates rcu_state.rcu_cpu_mask. If * the bitmap is empty, then the grace period is completed. * rcu_check_quiescent_state calls rcu_start_batch(0) to start the next grace * period (if necessary). @@ -117,25 +126,25 @@ static void rcu_do_batch(struct list_head *list) /* * Register a new batch of callbacks, and start it up if there is currently no * active batch and the batch to be registered has not already occurred. - * Caller must hold the rcu_ctrlblk.state lock. + * Caller must hold rcu_state.mutex. */ static void rcu_start_batch(int next_pending) { cpumask_t active; if (next_pending) - rcu_ctrlblk.batch.next_pending = 1; + rcu_ctrlblk.next_pending = 1; - if (rcu_ctrlblk.batch.next_pending && - rcu_ctrlblk.batch.completed == rcu_ctrlblk.batch.cur) { + if (rcu_ctrlblk.next_pending && + rcu_ctrlblk.completed == rcu_ctrlblk.cur) { /* Can't change, since spin lock held. */ active = nohz_cpu_mask; cpus_complement(active); - cpus_and(rcu_ctrlblk.state.rcu_cpu_mask, cpu_online_map, active); - write_seqcount_begin(&rcu_ctrlblk.batch.lock); - rcu_ctrlblk.batch.next_pending = 0; - rcu_ctrlblk.batch.cur++; - write_seqcount_end(&rcu_ctrlblk.batch.lock); + cpus_and(rcu_state.rcu_cpu_mask, cpu_online_map, active); + write_seqcount_begin(&rcu_ctrlblk.lock); + rcu_ctrlblk.next_pending = 0; + rcu_ctrlblk.cur++; + write_seqcount_end(&rcu_ctrlblk.lock); } } @@ -146,10 +155,10 @@ static void rcu_start_batch(int next_pending) */ static void cpu_quiet(int cpu) { - cpu_clear(cpu, rcu_ctrlblk.state.rcu_cpu_mask); - if (cpus_empty(rcu_ctrlblk.state.rcu_cpu_mask)) { + cpu_clear(cpu, rcu_state.rcu_cpu_mask); + if (cpus_empty(rcu_state.rcu_cpu_mask)) { /* batch completed ! */ - rcu_ctrlblk.batch.completed = rcu_ctrlblk.batch.cur; + rcu_ctrlblk.completed = rcu_ctrlblk.cur; rcu_start_batch(0); } } @@ -163,11 +172,11 @@ static void rcu_check_quiescent_state(void) { int cpu = smp_processor_id(); - if (RCU_quiescbatch(cpu) != rcu_ctrlblk.batch.cur) { + if (RCU_quiescbatch(cpu) != rcu_ctrlblk.cur) { /* new grace period: record qsctr value. */ RCU_qs_pending(cpu) = 1; RCU_last_qsctr(cpu) = RCU_qsctr(cpu); - RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.cur; + RCU_quiescbatch(cpu) = rcu_ctrlblk.cur; return; } @@ -187,15 +196,15 @@ static void rcu_check_quiescent_state(void) return; RCU_qs_pending(cpu) = 0; - spin_lock(&rcu_ctrlblk.state.mutex); + spin_lock(&rcu_state.mutex); /* * RCU_quiescbatch/batch.cur and the cpu bitmap can come out of sync * during cpu startup. Ignore the quiescent state. */ - if (likely(RCU_quiescbatch(cpu) == rcu_ctrlblk.batch.cur)) + if (likely(RCU_quiescbatch(cpu) == rcu_ctrlblk.cur)) cpu_quiet(cpu); - spin_unlock(&rcu_ctrlblk.state.mutex); + spin_unlock(&rcu_state.mutex); } @@ -225,11 +234,11 @@ static void rcu_offline_cpu(int cpu) * we can block indefinitely waiting for it, so flush * it here */ - spin_lock_bh(&rcu_ctrlblk.state.mutex); - if (rcu_ctrlblk.batch.cur != rcu_ctrlblk.batch.completed) + spin_lock_bh(&rcu_state.mutex); + if (rcu_ctrlblk.cur != rcu_ctrlblk.completed) cpu_quiet(cpu); unlock: - spin_unlock_bh(&rcu_ctrlblk.state.mutex); + spin_unlock_bh(&rcu_state.mutex); rcu_move_batch(&RCU_curlist(cpu)); rcu_move_batch(&RCU_nxtlist(cpu)); @@ -241,10 +250,10 @@ unlock: void rcu_restart_cpu(int cpu) { - spin_lock_bh(&rcu_ctrlblk.state.mutex); - RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + spin_lock_bh(&rcu_state.mutex); + RCU_quiescbatch(cpu) = rcu_ctrlblk.completed; RCU_qs_pending(cpu) = 0; - spin_unlock_bh(&rcu_ctrlblk.state.mutex); + spin_unlock_bh(&rcu_state.mutex); } /* @@ -256,7 +265,7 @@ static void rcu_process_callbacks(unsigned long unused) LIST_HEAD(list); if (!list_empty(&RCU_curlist(cpu)) && - !rcu_batch_before(rcu_ctrlblk.batch.completed,RCU_batch(cpu))) { + !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) { __list_splice(&RCU_curlist(cpu), &list); INIT_LIST_HEAD(&RCU_curlist(cpu)); } @@ -273,17 +282,17 @@ static void rcu_process_callbacks(unsigned long unused) * start the next batch of callbacks */ do { - seq = read_seqcount_begin(&rcu_ctrlblk.batch.lock); + seq = read_seqcount_begin(&rcu_ctrlblk.lock); /* determine batch number */ - RCU_batch(cpu) = rcu_ctrlblk.batch.cur + 1; - next_pending = rcu_ctrlblk.batch.next_pending; - } while (read_seqcount_retry(&rcu_ctrlblk.batch.lock, seq)); + RCU_batch(cpu) = rcu_ctrlblk.cur + 1; + next_pending = rcu_ctrlblk.next_pending; + } while (read_seqcount_retry(&rcu_ctrlblk.lock, seq)); if (!next_pending) { /* and start it/schedule start if it's a new batch */ - spin_lock(&rcu_ctrlblk.state.mutex); + spin_lock(&rcu_state.mutex); rcu_start_batch(1); - spin_unlock(&rcu_ctrlblk.state.mutex); + spin_unlock(&rcu_state.mutex); } } else { local_irq_enable(); @@ -308,7 +317,7 @@ static void __devinit rcu_online_cpu(int cpu) tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL); INIT_LIST_HEAD(&RCU_nxtlist(cpu)); INIT_LIST_HEAD(&RCU_curlist(cpu)); - RCU_quiescbatch(cpu) = rcu_ctrlblk.batch.completed; + RCU_quiescbatch(cpu) = rcu_ctrlblk.completed; RCU_qs_pending(cpu) = 0; } -- cgit v1.2.3 From b659a6fbb927a79acd606c4466d03cb615879f9f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:06 -0700 Subject: [PATCH] reduce rcu_head size - core From: Dipankar Sarma This reduces the RCU head size by using a singly linked to maintain them. The ordering of the callbacks is still maintained as before by using a tail pointer for the next list. Signed-Off-By : Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 24 +++++++++++++----------- kernel/rcupdate.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 967b2d47014b..8fafbdf06866 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -36,7 +36,6 @@ #ifdef __KERNEL__ #include -#include #include #include #include @@ -45,21 +44,20 @@ /** * struct rcu_head - callback structure for use with RCU - * @list: list_head to queue the update requests + * @next: next update requests in a list * @func: actual update function to call after the grace period. * @arg: argument to be passed to the actual update function. */ struct rcu_head { - struct list_head list; + struct rcu_head *next; void (*func)(void *obj); void *arg; }; -#define RCU_HEAD_INIT(head) \ - { .list = LIST_HEAD_INIT(head.list), .func = NULL, .arg = NULL } +#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL, .arg = NULL } #define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head) #define INIT_RCU_HEAD(ptr) do { \ - INIT_LIST_HEAD(&(ptr)->list); (ptr)->func = NULL; (ptr)->arg = NULL; \ + (ptr)->next = NULL; (ptr)->func = NULL; (ptr)->arg = NULL; \ } while (0) @@ -99,8 +97,9 @@ struct rcu_data { /* 2) batch handling */ long batch; /* Batch # for current RCU batch */ - struct list_head nxtlist; - struct list_head curlist; + struct rcu_head *nxtlist; + struct rcu_head **nxttail; + struct rcu_head *curlist; }; DECLARE_PER_CPU(struct rcu_data, rcu_data); @@ -113,22 +112,25 @@ extern struct rcu_ctrlblk rcu_ctrlblk; #define RCU_batch(cpu) (per_cpu(rcu_data, (cpu)).batch) #define RCU_nxtlist(cpu) (per_cpu(rcu_data, (cpu)).nxtlist) #define RCU_curlist(cpu) (per_cpu(rcu_data, (cpu)).curlist) +#define RCU_nxttail(cpu) (per_cpu(rcu_data, (cpu)).nxttail) static inline int rcu_pending(int cpu) { /* This cpu has pending rcu entries and the grace period * for them has completed. */ - if (!list_empty(&RCU_curlist(cpu)) && + if (RCU_curlist(cpu) && !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) return 1; + /* This cpu has no pending entries, but there are new entries */ - if (list_empty(&RCU_curlist(cpu)) && - !list_empty(&RCU_nxtlist(cpu))) + if (!RCU_curlist(cpu) && RCU_nxtlist(cpu)) return 1; + /* The rcu core waits for a quiescent state from the cpu */ if (RCU_quiescbatch(cpu) != rcu_ctrlblk.cur || RCU_qs_pending(cpu)) return 1; + /* nothing to do */ return 0; } diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 0e13bdbb9fd7..cdb59f12a5fa 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -82,9 +82,11 @@ void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg head->func = func; head->arg = arg; + head->next = NULL; local_irq_save(flags); cpu = smp_processor_id(); - list_add_tail(&head->list, &RCU_nxtlist(cpu)); + *RCU_nxttail(cpu) = head; + RCU_nxttail(cpu) = &head->next; local_irq_restore(flags); } @@ -92,16 +94,14 @@ void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg * Invoke the completed RCU callbacks. They are expected to be in * a per-cpu list. */ -static void rcu_do_batch(struct list_head *list) +static void rcu_do_batch(struct rcu_head *list) { - struct list_head *entry; - struct rcu_head *head; + struct rcu_head *next; - while (!list_empty(list)) { - entry = list->next; - list_del(entry); - head = list_entry(entry, struct rcu_head, list); - head->func(head->arg); + while (list) { + next = list->next; + list->func(list->arg); + list = next; } } @@ -262,20 +262,21 @@ void rcu_restart_cpu(int cpu) static void rcu_process_callbacks(unsigned long unused) { int cpu = smp_processor_id(); - LIST_HEAD(list); + struct rcu_head *rcu_list = NULL; - if (!list_empty(&RCU_curlist(cpu)) && - !rcu_batch_before(rcu_ctrlblk.completed,RCU_batch(cpu))) { - __list_splice(&RCU_curlist(cpu), &list); - INIT_LIST_HEAD(&RCU_curlist(cpu)); + if (RCU_curlist(cpu) && + !rcu_batch_before(rcu_ctrlblk.completed, RCU_batch(cpu))) { + rcu_list = RCU_curlist(cpu); + RCU_curlist(cpu) = NULL; } local_irq_disable(); - if (!list_empty(&RCU_nxtlist(cpu)) && list_empty(&RCU_curlist(cpu))) { + if (RCU_nxtlist(cpu) && !RCU_curlist(cpu)) { int next_pending, seq; - __list_splice(&RCU_nxtlist(cpu), &RCU_curlist(cpu)); - INIT_LIST_HEAD(&RCU_nxtlist(cpu)); + RCU_curlist(cpu) = RCU_nxtlist(cpu); + RCU_nxtlist(cpu) = NULL; + RCU_nxttail(cpu) = &RCU_nxtlist(cpu); local_irq_enable(); /* @@ -298,8 +299,8 @@ static void rcu_process_callbacks(unsigned long unused) local_irq_enable(); } rcu_check_quiescent_state(); - if (!list_empty(&list)) - rcu_do_batch(&list); + if (rcu_list) + rcu_do_batch(rcu_list); } void rcu_check_callbacks(int cpu, int user) @@ -315,8 +316,7 @@ static void __devinit rcu_online_cpu(int cpu) { memset(&per_cpu(rcu_data, cpu), 0, sizeof(struct rcu_data)); tasklet_init(&RCU_tasklet(cpu), rcu_process_callbacks, 0UL); - INIT_LIST_HEAD(&RCU_nxtlist(cpu)); - INIT_LIST_HEAD(&RCU_curlist(cpu)); + RCU_nxttail(cpu) = &RCU_nxtlist(cpu); RCU_quiescbatch(cpu) = rcu_ctrlblk.completed; RCU_qs_pending(cpu) = 0; } -- cgit v1.2.3 From 8c1ce9d6d628945ff23f844dbe9f21f5d5383b99 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:18 -0700 Subject: [PATCH] rcu: avoid passing an argument to the callback function From: Dipankar Sarma This patch changes the call_rcu() API and avoids passing an argument to the callback function as suggested by Rusty. Instead, it is assumed that the user has embedded the rcu head into a structure that is useful in the callback and the rcu_head pointer is passed to the callback. The callback can use container_of() to get the pointer to its structure and work with it. Together with the rcu-singly-link patch, it reduces the rcu_head size by 50%. Considering that we use these in things like struct dentry and struct dst_entry, this is good savings in space. An example : struct my_struct { struct rcu_head rcu; int x; int y; }; void my_rcu_callback(struct rcu_head *head) { struct my_struct *p = container_of(head, struct my_struct, rcu); free(p); } void my_delete(struct my_struct *p) { ... call_rcu(&p->rcu, my_rcu_callback); ... } Signed-Off-By: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/mm/tlb.c | 7 ++++--- fs/dcache.c | 6 +++--- include/linux/rcupdate.h | 10 ++++------ include/net/dst.h | 6 ++++++ ipc/util.c | 25 ++++++++++++++++++++----- kernel/auditsc.c | 7 ++++--- kernel/rcupdate.c | 26 ++++++++++++++++---------- net/bridge/br_if.c | 12 +++++++++--- net/decnet/dn_route.c | 4 ++-- net/ipv4/route.c | 4 ++-- net/sched/sch_generic.c | 6 +++--- security/selinux/netif.c | 6 +++--- 12 files changed, 76 insertions(+), 43 deletions(-) diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c index 980443bebed1..8825e14cb35a 100644 --- a/arch/ppc64/mm/tlb.c +++ b/arch/ppc64/mm/tlb.c @@ -158,9 +158,10 @@ void pte_free_now(struct page *ptepage) pte_free(ptepage); } -static void pte_free_rcu_callback(void *arg) +static void pte_free_rcu_callback(struct rcu_head *head) { - struct pte_freelist_batch *batch = arg; + struct pte_freelist_batch *batch = + container_of(head, struct pte_freelist_batch, rcu); unsigned int i; for (i = 0; i < batch->index; i++) @@ -171,7 +172,7 @@ static void pte_free_rcu_callback(void *arg) void pte_free_submit(struct pte_freelist_batch *batch) { INIT_RCU_HEAD(&batch->rcu); - call_rcu(&batch->rcu, pte_free_rcu_callback, batch); + call_rcu(&batch->rcu, pte_free_rcu_callback); } void pte_free_finish(void) diff --git a/fs/dcache.c b/fs/dcache.c index 4c632e1261dc..02df5d45b82e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -65,9 +65,9 @@ struct dentry_stat_t dentry_stat = { .age_limit = 45, }; -static void d_callback(void *arg) +static void d_callback(struct rcu_head *head) { - struct dentry * dentry = (struct dentry *)arg; + struct dentry * dentry = container_of(head, struct dentry, d_rcu); if (dname_external(dentry)) kfree(dentry->d_name.name); @@ -82,7 +82,7 @@ static void d_free(struct dentry *dentry) { if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); - call_rcu(&dentry->d_rcu, d_callback, dentry); + call_rcu(&dentry->d_rcu, d_callback); } /* diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 8fafbdf06866..10c4b8f24f08 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -46,18 +46,16 @@ * struct rcu_head - callback structure for use with RCU * @next: next update requests in a list * @func: actual update function to call after the grace period. - * @arg: argument to be passed to the actual update function. */ struct rcu_head { struct rcu_head *next; - void (*func)(void *obj); - void *arg; + void (*func)(struct rcu_head *head); }; -#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL, .arg = NULL } +#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL } #define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head) #define INIT_RCU_HEAD(ptr) do { \ - (ptr)->next = NULL; (ptr)->func = NULL; (ptr)->arg = NULL; \ + (ptr)->next = NULL; (ptr)->func = NULL; \ } while (0) @@ -144,7 +142,7 @@ extern void rcu_restart_cpu(int cpu); /* Exported interfaces */ extern void FASTCALL(call_rcu(struct rcu_head *head, - void (*func)(void *arg), void *arg)); + void (*func)(struct rcu_head *head))); extern void synchronize_kernel(void); #endif /* __KERNEL__ */ diff --git a/include/net/dst.h b/include/net/dst.h index ed2504c6b4e9..543ff945bb2f 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -183,6 +183,12 @@ static inline void dst_free(struct dst_entry * dst) __dst_free(dst); } +static inline void dst_rcu_free(struct rcu_head *head) +{ + struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head); + dst_free(dst); +} + static inline void dst_confirm(struct dst_entry *dst) { if (dst) diff --git a/ipc/util.c b/ipc/util.c index 81a145eded63..727c33233f5f 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -333,25 +333,40 @@ void* ipc_rcu_alloc(int size) * Since RCU callback function is called in bh, * we need to defer the vfree to schedule_work */ -static void ipc_schedule_free(void* arg) +static void ipc_schedule_free(struct rcu_head *head) { - struct ipc_rcu_vmalloc *free = arg; + struct ipc_rcu_vmalloc *free = + container_of(head, struct ipc_rcu_vmalloc, rcu); INIT_WORK(&free->work, vfree, free); schedule_work(&free->work); } +/** + * ipc_immediate_free - free ipc + rcu space + * + * Free from the RCU callback context + * + */ +static void ipc_immediate_free(struct rcu_head *head) +{ + struct ipc_rcu_kmalloc *free = + container_of(head, struct ipc_rcu_kmalloc, rcu); + kfree(free); +} + + + void ipc_rcu_free(void* ptr, int size) { if (rcu_use_vmalloc(size)) { struct ipc_rcu_vmalloc *free; free = ptr - sizeof(*free); - call_rcu(&free->rcu, ipc_schedule_free, free); + call_rcu(&free->rcu, ipc_schedule_free); } else { struct ipc_rcu_kmalloc *free; free = ptr - sizeof(*free); - /* kfree takes a "const void *" so gcc warns. So we cast. */ - call_rcu(&free->rcu, (void (*)(void *))kfree, free); + call_rcu(&free->rcu, ipc_immediate_free); } } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 342b57141fd9..e688c73f6a9e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -177,9 +177,10 @@ static inline int audit_add_rule(struct audit_entry *entry, return 0; } -static void audit_free_rule(void *arg) +static void audit_free_rule(struct rcu_head *head) { - kfree(arg); + struct audit_entry *e = container_of(head, struct audit_entry, rcu); + kfree(e); } /* Note that audit_add_rule and audit_del_rule are called via @@ -195,7 +196,7 @@ static inline int audit_del_rule(struct audit_rule *rule, list_for_each_entry(e, list, list) { if (!audit_compare_rule(rule, &e->rule)) { list_del_rcu(&e->list); - call_rcu(&e->rcu, audit_free_rule, e); + call_rcu(&e->rcu, audit_free_rule); return 0; } } diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index cdb59f12a5fa..7282889a5fd9 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -68,20 +68,19 @@ static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; * call_rcu - Queue an RCU update request. * @head: structure to be used for queueing the RCU updates. * @func: actual update function to be invoked after the grace period - * @arg: argument to be passed to the update function * * The update function will be invoked as soon as all CPUs have performed * a context switch or been seen in the idle loop or in a user process. * The read-side of critical section that use call_rcu() for updation must * be protected by rcu_read_lock()/rcu_read_unlock(). */ -void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg) +void fastcall call_rcu(struct rcu_head *head, + void (*func)(struct rcu_head *rcu)) { int cpu; unsigned long flags; head->func = func; - head->arg = arg; head->next = NULL; local_irq_save(flags); cpu = smp_processor_id(); @@ -100,7 +99,7 @@ static void rcu_do_batch(struct rcu_head *list) while (list) { next = list->next; - list->func(list->arg); + list->func(list); list = next; } } @@ -358,11 +357,18 @@ void __init rcu_init(void) register_cpu_notifier(&rcu_nb); } +struct rcu_synchronize { + struct rcu_head head; + struct completion completion; +}; /* Because of FASTCALL declaration of complete, we use this wrapper */ -static void wakeme_after_rcu(void *completion) +static void wakeme_after_rcu(struct rcu_head *head) { - complete(completion); + struct rcu_synchronize *rcu; + + rcu = container_of(head, struct rcu_synchronize, head); + complete(&rcu->completion); } /** @@ -371,14 +377,14 @@ static void wakeme_after_rcu(void *completion) */ void synchronize_kernel(void) { - struct rcu_head rcu; - DECLARE_COMPLETION(completion); + struct rcu_synchronize rcu; + init_completion(&rcu.completion); /* Will wake me after RCU finished */ - call_rcu(&rcu, wakeme_after_rcu, &completion); + call_rcu(&rcu.head, wakeme_after_rcu); /* Wait for it */ - wait_for_completion(&completion); + wait_for_completion(&rcu.completion); } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 20275604941a..6bb2ed24718f 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -75,9 +75,8 @@ static int br_initial_port_cost(struct net_device *dev) return 100; /* assume old 10Mbps */ } -static void destroy_nbp(void *arg) +static void destroy_nbp(struct net_bridge_port *p) { - struct net_bridge_port *p = arg; struct net_device *dev = p->dev; dev->br_port = NULL; @@ -88,6 +87,13 @@ static void destroy_nbp(void *arg) br_sysfs_freeif(p); } +static void destroy_nbp_rcu(struct rcu_head *head) +{ + struct net_bridge_port *p = + container_of(head, struct net_bridge_port, rcu); + destroy_nbp(p); +} + /* called with RTNL */ static void del_nbp(struct net_bridge_port *p) { @@ -108,7 +114,7 @@ static void del_nbp(struct net_bridge_port *p) del_timer_sync(&p->forward_delay_timer); del_timer_sync(&p->hold_timer); - call_rcu(&p->rcu, destroy_nbp, p); + call_rcu(&p->rcu, destroy_nbp_rcu); } /* called with RTNL */ diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 90d0583f56f4..c181467ddca3 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -146,14 +146,14 @@ static __inline__ unsigned dn_hash(unsigned short src, unsigned short dst) static inline void dnrt_free(struct dn_route *rt) { - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static inline void dnrt_drop(struct dn_route *rt) { if (rt) dst_release(&rt->u.dst); - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static void dn_dst_check_expire(unsigned long dummy) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a570e709f738..46aeef6fa4e1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -439,13 +439,13 @@ static struct file_operations rt_cpu_seq_fops = { static __inline__ void rt_free(struct rtable *rt) { - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static __inline__ void rt_drop(struct rtable *rt) { ip_rt_put(rt); - call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); + call_rcu(&rt->u.dst.rcu_head, dst_rcu_free); } static __inline__ int rt_fast_clean(struct rtable *rth) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 111dad476d2b..db8cab2cf1d5 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -411,9 +411,9 @@ void qdisc_reset(struct Qdisc *qdisc) /* this is the rcu callback function to clean up a qdisc when there * are no further references to it */ -static void __qdisc_destroy (void * arg) +static void __qdisc_destroy(struct rcu_head *head) { - struct Qdisc *qdisc = (struct Qdisc *) arg; + struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu); struct Qdisc_ops *ops = qdisc->ops; #ifdef CONFIG_NET_ESTIMATOR @@ -448,7 +448,7 @@ void qdisc_destroy(struct Qdisc *qdisc) } } - call_rcu(&qdisc->q_rcu, __qdisc_destroy, qdisc); + call_rcu(&qdisc->q_rcu, __qdisc_destroy); } diff --git a/security/selinux/netif.c b/security/selinux/netif.c index 4cbf8f259d93..d23bd7e6345e 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -134,9 +134,9 @@ out: return netif; } -static void sel_netif_free(void *p) +static void sel_netif_free(struct rcu_head *p) { - struct sel_netif *netif = p; + struct sel_netif *netif = container_of(p, struct sel_netif, rcu_head); DEBUGP("%s: %s\n", __FUNCTION__, netif->nsec.dev->name); kfree(netif); @@ -151,7 +151,7 @@ static void sel_netif_destroy(struct sel_netif *netif) sel_netif_total--; spin_unlock_bh(&sel_netif_lock); - call_rcu(&netif->rcu_head, sel_netif_free, netif); + call_rcu(&netif->rcu_head, sel_netif_free); } void sel_netif_put(struct sel_netif *netif) -- cgit v1.2.3 From d2cec97bc421d6f9c2ee0d9bd8e0ce47d0022cac Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:29 -0700 Subject: [PATCH] cpumask: make cpu_present_map real even on non-smp From: Paul Jackson This patch makes cpu_present_map a real map for all configurations, instead of a constant for non-SMP. It also moves the definition of cpu_present_map out of kernel/cpu.c into kernel/sched.c, because cpu.c isn't compiled into non-SMP kernels. The pattern is that each of the possible, present and online cpu maps are actual kernel global cpumask_t variables, for all configurations. They are documented in include/linux/cpumask.h. Some of the UP (NR_CPUS=1) code cheats, and hardcodes the assumption that the single bit position of these maps is always set, as an optimization. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cpumask.h | 13 +++++-------- kernel/cpu.c | 8 -------- kernel/sched.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 4293a465d87b..dced3ec2b0c8 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -10,15 +10,12 @@ extern cpumask_t cpu_online_map; extern cpumask_t cpu_possible_map; -extern cpumask_t cpu_present_map; #define num_online_cpus() cpus_weight(cpu_online_map) #define num_possible_cpus() cpus_weight(cpu_possible_map) -#define num_present_cpus() cpus_weight(cpu_present_map) #define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) #define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) -#define cpu_present(cpu) cpu_isset(cpu, cpu_present_map) #define for_each_cpu_mask(cpu, mask) \ for (cpu = first_cpu_const(mk_cpumask_const(mask)); \ @@ -27,26 +24,26 @@ extern cpumask_t cpu_present_map; #define for_each_cpu(cpu) for_each_cpu_mask(cpu, cpu_possible_map) #define for_each_online_cpu(cpu) for_each_cpu_mask(cpu, cpu_online_map) -#define for_each_present_cpu(cpu) for_each_cpu_mask(cpu, cpu_present_map) #else #define cpu_online_map cpumask_of_cpu(0) #define cpu_possible_map cpumask_of_cpu(0) -#define cpu_present_map cpumask_of_cpu(0) #define num_online_cpus() 1 #define num_possible_cpus() 1 -#define num_present_cpus() 1 #define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) -#define cpu_present(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++) #define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) -#define for_each_present_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #endif +extern cpumask_t cpu_present_map; +#define num_present_cpus() cpus_weight(cpu_present_map) +#define cpu_present(cpu) cpu_isset(cpu, cpu_present_map) +#define for_each_present_cpu(cpu) for_each_cpu_mask(cpu, cpu_present_map) + #define cpumask_scnprintf(buf, buflen, map) \ bitmap_scnprintf(buf, buflen, cpus_addr(map), NR_CPUS) diff --git a/kernel/cpu.c b/kernel/cpu.c index 72b984c67eb3..083521327e64 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -20,14 +20,6 @@ DECLARE_MUTEX(cpucontrol); static struct notifier_block *cpu_chain; -/* - * Represents all cpu's present in the system - * In systems capable of hotplug, this map could dynamically grow - * as new cpu's are detected in the system via any platform specific - * method, such as ACPI for e.g. - */ -cpumask_t cpu_present_map; -EXPORT_SYMBOL(cpu_present_map); /* Need to know about CPUs going up/down? */ int register_cpu_notifier(struct notifier_block *nb) diff --git a/kernel/sched.c b/kernel/sched.c index 8f49ba1202c3..a614d7ebf7c3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2941,6 +2941,16 @@ out_unlock: return retval; } +/* + * Represents all cpu's present in the system + * In systems capable of hotplug, this map could dynamically grow + * as new cpu's are detected in the system via any platform specific + * method, such as ACPI for e.g. + */ + +cpumask_t cpu_present_map; +EXPORT_SYMBOL(cpu_present_map); + /** * sys_sched_getaffinity - get the cpu affinity of a process * @pid: pid of the process -- cgit v1.2.3 From ea0c19290646e6bb7cd3657db83eac3a0d641418 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:40 -0700 Subject: [PATCH] cpumask: bitmap cleanup preparation for cpumask overhaul From: Paul Jackson Document the bitmap bit model and handling of unused bits. Tighten up bitmap so it does not generate nonzero bits in the unused tail if it is not given any on input. Add intersects, subset, xor and andnot operators. Change bitmap_complement to take two operands. Add a couple of missing 'const' qualifiers on bitops test_bit and bitmap_equal args. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/smpboot.c | 2 +- include/asm-generic/bitops.h | 2 +- include/asm-generic/cpumask_array.h | 2 +- include/asm-i386/mpspec.h | 2 +- include/asm-x86_64/mpspec.h | 2 +- include/linux/bitmap.h | 12 ++++- lib/bitmap.c | 87 ++++++++++++++++++++++++++++++++++--- mm/mempolicy.c | 14 +++--- 8 files changed, 102 insertions(+), 21 deletions(-) diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index ba2cba68da14..06937402b31c 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -827,7 +827,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) if (apicid == boot_cpu_id || (apicid == BAD_APICID)) continue; - if (!cpu_isset(apicid, phys_cpu_present_map)) + if (!physid_isset(apicid, phys_cpu_present_map)) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h index 23ac5227b702..ce31b739fd80 100644 --- a/include/asm-generic/bitops.h +++ b/include/asm-generic/bitops.h @@ -42,7 +42,7 @@ extern __inline__ int clear_bit(int nr, long * addr) return retval; } -extern __inline__ int test_bit(int nr, long * addr) +extern __inline__ int test_bit(int nr, const unsigned long * addr) { int mask; diff --git a/include/asm-generic/cpumask_array.h b/include/asm-generic/cpumask_array.h index ddd6e1185dba..1be08ae2e93b 100644 --- a/include/asm-generic/cpumask_array.h +++ b/include/asm-generic/cpumask_array.h @@ -17,7 +17,7 @@ #define cpus_and(dst,src1,src2) bitmap_and((dst).mask,(src1).mask, (src2).mask, NR_CPUS) #define cpus_or(dst,src1,src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS) #define cpus_clear(map) bitmap_zero((map).mask, NR_CPUS) -#define cpus_complement(map) bitmap_complement((map).mask, NR_CPUS) +#define cpus_complement(map) bitmap_complement((map).mask, (map).mask, NR_CPUS) #define cpus_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, NR_CPUS) #define cpus_empty(map) bitmap_empty(map.mask, NR_CPUS) #define cpus_addr(map) ((map).mask) diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index b2cc2feeb8a4..31a9717c1a8b 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h @@ -53,7 +53,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, MAX_APICS) +#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h index fd707a6a8bcd..a9a6f16672f2 100644 --- a/include/asm-x86_64/mpspec.h +++ b/include/asm-x86_64/mpspec.h @@ -212,7 +212,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, MAX_APICS) +#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index c301d121c8d0..bc93e0167a81 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -13,8 +13,8 @@ int bitmap_empty(const unsigned long *bitmap, int bits); int bitmap_full(const unsigned long *bitmap, int bits); int bitmap_equal(const unsigned long *bitmap1, - unsigned long *bitmap2, int bits); -void bitmap_complement(unsigned long *bitmap, int bits); + const unsigned long *bitmap2, int bits); +void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits); static inline void bitmap_zero(unsigned long *bitmap, int bits) { @@ -41,6 +41,14 @@ void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); +void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +int bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +int bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); int bitmap_weight(const unsigned long *bitmap, int bits); int bitmap_scnprintf(char *buf, unsigned int buflen, const unsigned long *maskp, int bits); diff --git a/lib/bitmap.c b/lib/bitmap.c index 779d30365e46..a96433e37102 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -12,6 +12,26 @@ #include #include +/* + * bitmaps provide an array of bits, implemented using an an + * array of unsigned longs. The number of valid bits in a + * given bitmap need not be an exact multiple of BITS_PER_LONG. + * + * The possible unused bits in the last, partially used word + * of a bitmap are 'don't care'. The implementation makes + * no particular effort to keep them zero. It ensures that + * their value will not affect the results of any operation. + * The bitmap operations that return Boolean (bitmap_empty, + * for example) or scalar (bitmap_weight, for example) results + * carefully filter out these unused bits from impacting their + * results. + * + * These operations actually hold to a slightly stronger rule: + * if you don't input any bitmaps to these ops that have some + * unused bits set, then they won't output any set unused bits + * in output bitmaps. + */ + int bitmap_empty(const unsigned long *bitmap, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -43,7 +63,7 @@ int bitmap_full(const unsigned long *bitmap, int bits) EXPORT_SYMBOL(bitmap_full); int bitmap_equal(const unsigned long *bitmap1, - unsigned long *bitmap2, int bits) + const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) @@ -59,13 +79,14 @@ int bitmap_equal(const unsigned long *bitmap1, } EXPORT_SYMBOL(bitmap_equal); -void bitmap_complement(unsigned long *bitmap, int bits) +void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) { - int k; - int nr = BITS_TO_LONGS(bits); + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + dst[k] = ~src[k]; - for (k = 0; k < nr; ++k) - bitmap[k] = ~bitmap[k]; + if (bits % BITS_PER_LONG) + dst[k] = ~src[k] & ((1UL << (bits % BITS_PER_LONG)) - 1); } EXPORT_SYMBOL(bitmap_complement); @@ -173,6 +194,60 @@ void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, } EXPORT_SYMBOL(bitmap_or); +void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] ^ bitmap2[k]; +} +EXPORT_SYMBOL(bitmap_xor); + +void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] & ~bitmap2[k]; +} +EXPORT_SYMBOL(bitmap_andnot); + +int bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap1[k] & bitmap2[k]) + return 1; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] & bitmap2[k]) & + ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 1; + return 0; +} +EXPORT_SYMBOL(bitmap_intersects); + +int bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap1[k] & ~bitmap2[k]) + return 0; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] & ~bitmap2[k]) & + ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + return 1; +} +EXPORT_SYMBOL(bitmap_subset); + #if BITS_PER_LONG == 32 int bitmap_weight(const unsigned long *bitmap, int bits) { diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 4f1fc840550a..d06eabbf74f0 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -93,14 +93,12 @@ static struct mempolicy default_policy = { /* Check if all specified nodes are online */ static int nodes_online(unsigned long *nodes) { - DECLARE_BITMAP(offline, MAX_NUMNODES); - - bitmap_copy(offline, node_online_map, MAX_NUMNODES); - if (bitmap_empty(offline, MAX_NUMNODES)) - set_bit(0, offline); - bitmap_complement(offline, MAX_NUMNODES); - bitmap_and(offline, offline, nodes, MAX_NUMNODES); - if (!bitmap_empty(offline, MAX_NUMNODES)) + DECLARE_BITMAP(online2, MAX_NUMNODES); + + bitmap_copy(online2, node_online_map, MAX_NUMNODES); + if (bitmap_empty(online2, MAX_NUMNODES)) + set_bit(0, online2); + if (!bitmap_subset(nodes, online2, MAX_NUMNODES)) return -EINVAL; return 0; } -- cgit v1.2.3 From d6cf71d3086ea9be652ac95616cd111157fdd4c5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:50:51 -0700 Subject: [PATCH] cpumask: bitmap inlining and optimizations From: Paul Jackson These bitmap improvements make it a suitable basis for fully supporting cpumask_t and nodemask_t. Inline macros with compile-time checks enable generating tight code on both small and large systems (large meaning cpumask_t requires more than one unsigned long's worth of bits). The existing bitmap_ macros in lib/bitmap.c are renamed to __bitmap_, and wrappers for each bitmap_ are exposed in include/linux/bitmap.h This patch _includes_ Bill Irwins rewrite of the bitmap_shift operators to not require a fixed length intermediate bitmap. Improved comments list each available operator for easy browsing. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bitmap.h | 264 ++++++++++++++++++++++++++++++++++++++++++------- lib/bitmap.c | 91 ++++++++--------- 2 files changed, 275 insertions(+), 80 deletions(-) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index bc93e0167a81..9dadd08e2b53 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -3,57 +3,249 @@ #ifndef __ASSEMBLY__ -#include -#include #include -#include #include #include -int bitmap_empty(const unsigned long *bitmap, int bits); -int bitmap_full(const unsigned long *bitmap, int bits); -int bitmap_equal(const unsigned long *bitmap1, +/* + * bitmaps provide bit arrays that consume one or more unsigned + * longs. The bitmap interface and available operations are listed + * here, in bitmap.h + * + * Function implementations generic to all architectures are in + * lib/bitmap.c. Functions implementations that are architecture + * specific are in various include/asm-/bitops.h headers + * and other arch/ specific files. + * + * See lib/bitmap.c for more details. + */ + +/* + * The available bitmap operations and their rough meaning in the + * case that the bitmap is a single unsigned long are thus: + * + * bitmap_zero(dst, nbits) *dst = 0UL + * bitmap_fill(dst, nbits) *dst = ~0UL + * bitmap_copy(dst, src, nbits) *dst = *src + * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 + * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 + * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 + * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) + * bitmap_complement(dst, src, nbits) *dst = ~(*src) + * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? + * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? + * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2? + * bitmap_empty(src, nbits) Are all bits zero in *src? + * bitmap_full(src, nbits) Are all bits set in *src? + * bitmap_weight(src, nbits) Hamming Weight: number set bits + * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n + * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n + * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf + * bitmap_parse(ubuf, ulen, dst, nbits) Parse bitmap dst from buf + */ + +/* + * Also the following operations in asm/bitops.h apply to bitmaps. + * + * set_bit(bit, addr) *addr |= bit + * clear_bit(bit, addr) *addr &= ~bit + * change_bit(bit, addr) *addr ^= bit + * test_bit(bit, addr) Is bit set in *addr? + * test_and_set_bit(bit, addr) Set bit and return old value + * test_and_clear_bit(bit, addr) Clear bit and return old value + * test_and_change_bit(bit, addr) Change bit and return old value + * find_first_zero_bit(addr, nbits) Position first zero bit in *addr + * find_first_bit(addr, nbits) Position first set bit in *addr + * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit + * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit + */ + +/* + * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used + * to declare an array named 'name' of just enough unsigned longs to + * contain all bit positions from 0 to 'bits' - 1. + */ + +/* + * lib/bitmap.c provides these functions: + */ + +extern int __bitmap_empty(const unsigned long *bitmap, int bits); +extern int __bitmap_full(const unsigned long *bitmap, int bits); +extern int __bitmap_equal(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern void __bitmap_complement(unsigned long *dst, const unsigned long *src, + int bits); +extern void __bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int shift, int bits); +extern void __bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int shift, int bits); +extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); -void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits); +extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern int __bitmap_intersects(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern int __bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +extern int __bitmap_weight(const unsigned long *bitmap, int bits); + +extern int bitmap_scnprintf(char *buf, unsigned int len, + const unsigned long *src, int nbits); +extern int bitmap_parse(const char __user *ubuf, unsigned int ulen, + unsigned long *dst, int nbits); -static inline void bitmap_zero(unsigned long *bitmap, int bits) +#define BITMAP_LAST_WORD_MASK(nbits) \ +( \ + ((nbits) % BITS_PER_LONG) ? \ + (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ +) + +static inline void bitmap_zero(unsigned long *dst, int nbits) { - memset(bitmap, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long)); + if (nbits <= BITS_PER_LONG) + *dst = 0UL; + else { + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memset(dst, 0, len); + } } -static inline void bitmap_fill(unsigned long *bitmap, int bits) +static inline void bitmap_fill(unsigned long *dst, int nbits) { - memset(bitmap, 0xff, BITS_TO_LONGS(bits)*sizeof(unsigned long)); + size_t nlongs = BITS_TO_LONGS(nbits); + if (nlongs > 1) { + int len = (nlongs - 1) * sizeof(unsigned long); + memset(dst, 0xff, len); + } + dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); } -static inline void bitmap_copy(unsigned long *dst, - const unsigned long *src, int bits) +static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, + int nbits) { - int len = BITS_TO_LONGS(bits)*sizeof(unsigned long); - memcpy(dst, src, len); + if (nbits <= BITS_PER_LONG) + *dst = *src; + else { + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memcpy(dst, src, len); + } } -void bitmap_shift_right(unsigned long *dst, - const unsigned long *src, int shift, int bits); -void bitmap_shift_left(unsigned long *dst, - const unsigned long *src, int shift, int bits); -void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -int bitmap_intersects(const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -int bitmap_subset(const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); -int bitmap_weight(const unsigned long *bitmap, int bits); -int bitmap_scnprintf(char *buf, unsigned int buflen, - const unsigned long *maskp, int bits); -int bitmap_parse(const char __user *ubuf, unsigned int ubuflen, - unsigned long *maskp, int bits); +static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 & *src2; + else + __bitmap_and(dst, src1, src2, nbits); +} + +static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 | *src2; + else + __bitmap_or(dst, src1, src2, nbits); +} + +static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 ^ *src2; + else + __bitmap_xor(dst, src1, src2, nbits); +} + +static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src1 & ~(*src2); + else + __bitmap_andnot(dst, src1, src2, nbits); +} + +static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, + int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); + else + __bitmap_complement(dst, src, nbits); +} + +static inline int bitmap_equal(const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_equal(src1, src2, nbits); +} + +static inline int bitmap_intersects(const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; + else + return __bitmap_intersects(src1, src2, nbits); +} + +static inline int bitmap_subset(const unsigned long *src1, + const unsigned long *src2, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_subset(src1, src2, nbits); +} + +static inline int bitmap_empty(const unsigned long *src, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_empty(src, nbits); +} + +static inline int bitmap_full(const unsigned long *src, int nbits) +{ + if (nbits <= BITS_PER_LONG) + return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_full(src, nbits); +} + +static inline int bitmap_weight(const unsigned long *src, int nbits) +{ + return __bitmap_weight(src, nbits); +} + +static inline void bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int n, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = *src >> n; + else + __bitmap_shift_right(dst, src, n, nbits); +} + +static inline void bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int n, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); + else + __bitmap_shift_left(dst, src, n, nbits); +} #endif /* __ASSEMBLY__ */ diff --git a/lib/bitmap.c b/lib/bitmap.c index a96433e37102..7eb16be309b5 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -15,7 +15,8 @@ /* * bitmaps provide an array of bits, implemented using an an * array of unsigned longs. The number of valid bits in a - * given bitmap need not be an exact multiple of BITS_PER_LONG. + * given bitmap does _not_ need to be an exact multiple of + * BITS_PER_LONG. * * The possible unused bits in the last, partially used word * of a bitmap are 'don't care'. The implementation makes @@ -30,9 +31,14 @@ * if you don't input any bitmaps to these ops that have some * unused bits set, then they won't output any set unused bits * in output bitmaps. + * + * The byte ordering of bitmaps is more natural on little + * endian architectures. See the big-endian headers + * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h + * for the best explanations of this ordering. */ -int bitmap_empty(const unsigned long *bitmap, int bits) +int __bitmap_empty(const unsigned long *bitmap, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) @@ -40,14 +46,14 @@ int bitmap_empty(const unsigned long *bitmap, int bits) return 0; if (bits % BITS_PER_LONG) - if (bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_empty); +EXPORT_SYMBOL(__bitmap_empty); -int bitmap_full(const unsigned long *bitmap, int bits) +int __bitmap_full(const unsigned long *bitmap, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) @@ -55,14 +61,14 @@ int bitmap_full(const unsigned long *bitmap, int bits) return 0; if (bits % BITS_PER_LONG) - if (~bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_full); +EXPORT_SYMBOL(__bitmap_full); -int bitmap_equal(const unsigned long *bitmap1, +int __bitmap_equal(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -71,27 +77,26 @@ int bitmap_equal(const unsigned long *bitmap1, return 0; if (bits % BITS_PER_LONG) - if ((bitmap1[k] ^ bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) + if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_equal); +EXPORT_SYMBOL(__bitmap_equal); -void bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) +void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) { int k, lim = bits/BITS_PER_LONG; for (k = 0; k < lim; ++k) dst[k] = ~src[k]; if (bits % BITS_PER_LONG) - dst[k] = ~src[k] & ((1UL << (bits % BITS_PER_LONG)) - 1); + dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits); } -EXPORT_SYMBOL(bitmap_complement); +EXPORT_SYMBOL(__bitmap_complement); /* - * bitmap_shift_right - logical right shift of the bits in a bitmap + * __bitmap_shift_right - logical right shift of the bits in a bitmap * @dst - destination bitmap * @src - source bitmap * @nbits - shift by this many bits @@ -101,7 +106,7 @@ EXPORT_SYMBOL(bitmap_complement); * direction. Zeros are fed into the vacated MS positions and the * LS bits shifted off the bottom are lost. */ -void bitmap_shift_right(unsigned long *dst, +void __bitmap_shift_right(unsigned long *dst, const unsigned long *src, int shift, int bits) { int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG; @@ -131,10 +136,11 @@ void bitmap_shift_right(unsigned long *dst, if (off) memset(&dst[lim - off], 0, off*sizeof(unsigned long)); } -EXPORT_SYMBOL(bitmap_shift_right); +EXPORT_SYMBOL(__bitmap_shift_right); + /* - * bitmap_shift_left - logical left shift of the bits in a bitmap + * __bitmap_shift_left - logical left shift of the bits in a bitmap * @dst - destination bitmap * @src - source bitmap * @nbits - shift by this many bits @@ -144,7 +150,8 @@ EXPORT_SYMBOL(bitmap_shift_right); * direction. Zeros are fed into the vacated LS bit positions * and those MS bits shifted off the top are lost. */ -void bitmap_shift_left(unsigned long *dst, + +void __bitmap_shift_left(unsigned long *dst, const unsigned long *src, int shift, int bits) { int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG; @@ -170,9 +177,9 @@ void bitmap_shift_left(unsigned long *dst, if (off) memset(dst, 0, off*sizeof(unsigned long)); } -EXPORT_SYMBOL(bitmap_shift_left); +EXPORT_SYMBOL(__bitmap_shift_left); -void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -181,9 +188,9 @@ void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] & bitmap2[k]; } -EXPORT_SYMBOL(bitmap_and); +EXPORT_SYMBOL(__bitmap_and); -void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -192,9 +199,9 @@ void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] | bitmap2[k]; } -EXPORT_SYMBOL(bitmap_or); +EXPORT_SYMBOL(__bitmap_or); -void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -203,9 +210,9 @@ void bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] ^ bitmap2[k]; } -EXPORT_SYMBOL(bitmap_xor); +EXPORT_SYMBOL(__bitmap_xor); -void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, +void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k; @@ -214,9 +221,9 @@ void bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] & ~bitmap2[k]; } -EXPORT_SYMBOL(bitmap_andnot); +EXPORT_SYMBOL(__bitmap_andnot); -int bitmap_intersects(const unsigned long *bitmap1, +int __bitmap_intersects(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -225,14 +232,13 @@ int bitmap_intersects(const unsigned long *bitmap1, return 1; if (bits % BITS_PER_LONG) - if ((bitmap1[k] & bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) + if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) return 1; return 0; } -EXPORT_SYMBOL(bitmap_intersects); +EXPORT_SYMBOL(__bitmap_intersects); -int bitmap_subset(const unsigned long *bitmap1, +int __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits) { int k, lim = bits/BITS_PER_LONG; @@ -241,15 +247,14 @@ int bitmap_subset(const unsigned long *bitmap1, return 0; if (bits % BITS_PER_LONG) - if ((bitmap1[k] & ~bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) + if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) return 0; return 1; } -EXPORT_SYMBOL(bitmap_subset); +EXPORT_SYMBOL(__bitmap_subset); #if BITS_PER_LONG == 32 -int bitmap_weight(const unsigned long *bitmap, int bits) +int __bitmap_weight(const unsigned long *bitmap, int bits) { int k, w = 0, lim = bits/BITS_PER_LONG; @@ -257,13 +262,12 @@ int bitmap_weight(const unsigned long *bitmap, int bits) w += hweight32(bitmap[k]); if (bits % BITS_PER_LONG) - w += hweight32(bitmap[k] & - ((1UL << (bits % BITS_PER_LONG)) - 1)); + w += hweight32(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); return w; } #else -int bitmap_weight(const unsigned long *bitmap, int bits) +int __bitmap_weight(const unsigned long *bitmap, int bits) { int k, w = 0, lim = bits/BITS_PER_LONG; @@ -271,13 +275,12 @@ int bitmap_weight(const unsigned long *bitmap, int bits) w += hweight64(bitmap[k]); if (bits % BITS_PER_LONG) - w += hweight64(bitmap[k] & - ((1UL << (bits % BITS_PER_LONG)) - 1)); + w += hweight64(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); return w; } #endif -EXPORT_SYMBOL(bitmap_weight); +EXPORT_SYMBOL(__bitmap_weight); /* * Bitmap printing & parsing functions: first version by Bill Irwin, @@ -394,7 +397,7 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen, if (nchunks == 0 && chunk == 0) continue; - bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits); + __bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits); *maskp |= chunk; nchunks++; nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ; -- cgit v1.2.3 From f3344dc35c26c28647ae4a6b9cdd9df3fa65777e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:00 -0700 Subject: [PATCH] cpumask: rewrite cpumask.h - single bitmap based implementation From: Paul Jackson Major rewrite of cpumask to use a single implementation, as a struct-wrapped bitmap. This patch leaves some 26 include/asm-*/cpumask*.h header files orphaned - to be removed next patch. Some nine cpumask macros for const variants and to coerce and promote between an unsigned long and a cpumask are obsolete. Simple emulation wrappers are provided in this patch for these obsolete macros, which can be removed once each of the 3 archs (i386, ppc64, x86_64) using them are recoded in follow-on patches to not need them. The CPU_MASK_ALL macro now avoids leaving possible garbage one bits in any unused portion of the high word. An inproved comment lists all available operators, for convenient browsing. From: Mikael Pettersson 2.6.7-rc3-mm1 changed CPU_MASK_NONE into something that isn't a valid rvalue (it only works inside struct initializers). This caused compile-time errors in perfctr in UP x86 builds. From: Arnd Bergmann cpumask-5-10-rewrite-cpumaskh-single-bitmap-based from 2.6.7-rc3-mm1 causes include2/asm/smp.h:54:1: warning: "cpu_online" redefined Signed-off-by: Paul Jackson Signed-off-by: Mikael Pettersson Signed-off-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/irq.c | 6 +- include/asm-s390/smp.h | 6 - include/linux/cpumask.h | 388 ++++++++++++++++++++++++++++++++++++++++++---- kernel/rcupdate.c | 7 +- kernel/sched.c | 5 + 5 files changed, 368 insertions(+), 44 deletions(-) diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index b7f6a1eb922f..35243558bfc0 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -691,9 +691,10 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp) * Just Do It. */ struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask = get_smpaff_in_irqaction(ap); + cpumask_t cpu_mask; unsigned int buddy, ticks; + cpus_addr(cpu_mask)[0] = get_smpaff_in_irqaction(ap); cpus_and(cpu_mask, cpu_mask, cpu_online_map); if (cpus_empty(cpu_mask)) cpu_mask = cpu_online_map; @@ -1210,9 +1211,10 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, { struct ino_bucket *bp = ivector_table + (long)data; struct irqaction *ap = bp->irq_info; - cpumask_t mask = get_smpaff_in_irqaction(ap); + cpumask_t mask; int len; + cpus_addr(mask)[0] = get_smpaff_in_irqaction(ap); if (cpus_empty(mask)) mask = cpu_online_map; diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 7e613240088e..70d06261bb9e 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -31,10 +31,6 @@ typedef struct extern int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic, int wait, int cpu); - -extern cpumask_t cpu_online_map; -extern cpumask_t cpu_possible_map; - #define NO_PROC_ID 0xFF /* No processor magic marker */ /* @@ -51,8 +47,6 @@ extern cpumask_t cpu_possible_map; #define smp_processor_id() (S390_lowcore.cpu_data.cpu_nr) -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - extern __inline__ __u16 hard_smp_processor_id(void) { __u16 cpu_address; diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index dced3ec2b0c8..f05bf9402dfc 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -1,53 +1,379 @@ #ifndef __LINUX_CPUMASK_H #define __LINUX_CPUMASK_H +/* + * Cpumasks provide a bitmap suitable for representing the + * set of CPU's in a system, one bit position per CPU number. + * + * See detailed comments in the file linux/bitmap.h describing the + * data type on which these cpumasks are based. + * + * For details of cpumask_scnprintf() and cpumask_parse(), + * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c. + * + * The available cpumask operations are: + * + * void cpu_set(cpu, mask) turn on bit 'cpu' in mask + * void cpu_clear(cpu, mask) turn off bit 'cpu' in mask + * void cpus_setall(mask) set all bits + * void cpus_clear(mask) clear all bits + * int cpu_isset(cpu, mask) true iff bit 'cpu' set in mask + * int cpu_test_and_set(cpu, mask) test and set bit 'cpu' in mask + * + * void cpus_and(dst, src1, src2) dst = src1 & src2 [intersection] + * void cpus_or(dst, src1, src2) dst = src1 | src2 [union] + * void cpus_xor(dst, src1, src2) dst = src1 ^ src2 + * void cpus_andnot(dst, src1, src2) dst = src1 & ~src2 + * void cpus_complement(dst, src) dst = ~src + * + * int cpus_equal(mask1, mask2) Does mask1 == mask2? + * int cpus_intersects(mask1, mask2) Do mask1 and mask2 intersect? + * int cpus_subset(mask1, mask2) Is mask1 a subset of mask2? + * int cpus_empty(mask) Is mask empty (no bits sets)? + * int cpus_full(mask) Is mask full (all bits sets)? + * int cpus_weight(mask) Hamming weigh - number of set bits + * + * void cpus_shift_right(dst, src, n) Shift right + * void cpus_shift_left(dst, src, n) Shift left + * + * int first_cpu(mask) Number lowest set bit, or NR_CPUS + * int next_cpu(cpu, mask) Next cpu past 'cpu', or NR_CPUS + * + * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set + * CPU_MASK_ALL Initializer - all bits set + * CPU_MASK_NONE Initializer - no bits set + * unsigned long *cpus_addr(mask) Array of unsigned long's in mask + * + * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing + * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask + * + * int num_online_cpus() Number of online CPUs + * int num_possible_cpus() Number of all possible CPUs + * int cpu_online(cpu) Is some cpu online? + * int cpu_possible(cpu) Is some cpu possible? + * void cpu_set_online(cpu) set cpu in cpu_online_map + * void cpu_set_offline(cpu) clear cpu in cpu_online_map + * int any_online_cpu(mask) First online cpu in mask + * + * for_each_cpu_mask(cpu, mask) for-loop cpu over mask + * for_each_cpu(cpu) for-loop cpu over cpu_possible_map + * for_each_online_cpu(cpu) for-loop cpu over cpu_online_map + * + * Subtlety: + * 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway) + * to generate slightly worse code. Note for example the additional + * 40 lines of assembly code compiling the "for each possible cpu" + * loops buried in the disk_stat_read() macros calls when compiling + * drivers/block/genhd.c (arch i386, CONFIG_SMP=y). So use a simple + * one-line #define for cpu_isset(), instead of wrapping an inline + * inside a macro, the way we do the other calls. + */ + #include #include -#include #include -#ifdef CONFIG_SMP +typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; +extern cpumask_t _unused_cpumask_arg_; -extern cpumask_t cpu_online_map; -extern cpumask_t cpu_possible_map; +#define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) +static inline void __cpu_set(int cpu, volatile cpumask_t *dstp) +{ + set_bit(cpu, dstp->bits); +} -#define num_online_cpus() cpus_weight(cpu_online_map) -#define num_possible_cpus() cpus_weight(cpu_possible_map) +#define cpu_clear(cpu, dst) __cpu_clear((cpu), &(dst)) +static inline void __cpu_clear(int cpu, volatile cpumask_t *dstp) +{ + clear_bit(cpu, dstp->bits); +} -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) +#define cpus_setall(dst) __cpus_setall(&(dst), NR_CPUS) +static inline void __cpus_setall(cpumask_t *dstp, int nbits) +{ + bitmap_fill(dstp->bits, nbits); +} -#define for_each_cpu_mask(cpu, mask) \ - for (cpu = first_cpu_const(mk_cpumask_const(mask)); \ - cpu < NR_CPUS; \ - cpu = next_cpu_const(cpu, mk_cpumask_const(mask))) +#define cpus_clear(dst) __cpus_clear(&(dst), NR_CPUS) +static inline void __cpus_clear(cpumask_t *dstp, int nbits) +{ + bitmap_zero(dstp->bits, nbits); +} -#define for_each_cpu(cpu) for_each_cpu_mask(cpu, cpu_possible_map) -#define for_each_online_cpu(cpu) for_each_cpu_mask(cpu, cpu_online_map) -#else -#define cpu_online_map cpumask_of_cpu(0) -#define cpu_possible_map cpumask_of_cpu(0) +/* No static inline type checking - see Subtlety (1) above. */ +#define cpu_isset(cpu, cpumask) test_bit((cpu), (cpumask).bits) + +#define cpu_test_and_set(cpu, cpumask) __cpu_test_and_set((cpu), &(cpumask)) +static inline int __cpu_test_and_set(int cpu, cpumask_t *addr) +{ + return test_and_set_bit(cpu, addr->bits); +} + +#define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_and(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_or(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_xor(dst, src1, src2) __cpus_xor(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_xor(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_andnot(dst, src1, src2) \ + __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS) +static inline void __cpus_andnot(cpumask_t *dstp, cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits); +} + +#define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS) +static inline void __cpus_complement(cpumask_t *dstp, + cpumask_t *srcp, int nbits) +{ + bitmap_complement(dstp->bits, srcp->bits, nbits); +} + +#define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS) +static inline int __cpus_equal(cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + return bitmap_equal(src1p->bits, src2p->bits, nbits); +} + +#define cpus_intersects(src1, src2) __cpus_intersects(&(src1), &(src2), NR_CPUS) +static inline int __cpus_intersects(cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + return bitmap_intersects(src1p->bits, src2p->bits, nbits); +} + +#define cpus_subset(src1, src2) __cpus_subset(&(src1), &(src2), NR_CPUS) +static inline int __cpus_subset(cpumask_t *src1p, + cpumask_t *src2p, int nbits) +{ + return bitmap_subset(src1p->bits, src2p->bits, nbits); +} + +#define cpus_empty(src) __cpus_empty(&(src), NR_CPUS) +static inline int __cpus_empty(cpumask_t *srcp, int nbits) +{ + return bitmap_empty(srcp->bits, nbits); +} + +#define cpus_full(cpumask) __cpus_full(&(cpumask), NR_CPUS) +static inline int __cpus_full(cpumask_t *srcp, int nbits) +{ + return bitmap_full(srcp->bits, nbits); +} + +#define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS) +static inline int __cpus_weight(cpumask_t *srcp, int nbits) +{ + return bitmap_weight(srcp->bits, nbits); +} + +#define cpus_shift_right(dst, src, n) \ + __cpus_shift_right(&(dst), &(src), (n), NR_CPUS) +static inline void __cpus_shift_right(cpumask_t *dstp, + cpumask_t *srcp, int n, int nbits) +{ + bitmap_shift_right(dstp->bits, srcp->bits, n, nbits); +} + +#define cpus_shift_left(dst, src, n) \ + __cpus_shift_left(&(dst), &(src), (n), NR_CPUS) +static inline void __cpus_shift_left(cpumask_t *dstp, + cpumask_t *srcp, int n, int nbits) +{ + bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); +} + +#define first_cpu(src) __first_cpu(&(src), NR_CPUS) +static inline int __first_cpu(cpumask_t *srcp, int nbits) +{ + return find_first_bit(srcp->bits, nbits); +} -#define num_online_cpus() 1 -#define num_possible_cpus() 1 +#define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS) +static inline int __next_cpu(int n, cpumask_t *srcp, int nbits) +{ + return find_next_bit(srcp->bits, nbits, n+1); +} -#define cpu_online(cpu) ({ BUG_ON((cpu) != 0); 1; }) -#define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) +#define cpumask_of_cpu(cpu) \ +({ \ + typeof(_unused_cpumask_arg_) m; \ + if (sizeof(m) == sizeof(unsigned long)) { \ + m.bits[0] = 1UL<<(cpu); \ + } else { \ + cpus_clear(m); \ + cpu_set((cpu), m); \ + } \ + m; \ +}) + +#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) + +#if NR_CPUS <= BITS_PER_LONG + +#define CPU_MASK_ALL \ +((cpumask_t) { { \ + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ +} }) + +#else + +#define CPU_MASK_ALL \ +((cpumask_t) { { \ + [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL, \ + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ +} }) -#define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++) -#define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) -#define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #endif +#define CPU_MASK_NONE \ +((cpumask_t) { { \ + [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \ +} }) + +#define cpus_addr(src) ((src).bits) + +#define cpumask_scnprintf(buf, len, src) \ + __cpumask_scnprintf((buf), (len), &(src), NR_CPUS) +static inline int __cpumask_scnprintf(char *buf, int len, + cpumask_t *srcp, int nbits) +{ + return bitmap_scnprintf(buf, len, srcp->bits, nbits); +} + +#define cpumask_parse(ubuf, ulen, src) \ + __cpumask_parse((ubuf), (ulen), &(src), NR_CPUS) +static inline int __cpumask_parse(const char __user *buf, int len, + cpumask_t *srcp, int nbits) +{ + return bitmap_parse(buf, len, srcp->bits, nbits); +} + +#if NR_CPUS > 1 +#define for_each_cpu_mask(cpu, mask) \ + for ((cpu) = first_cpu(mask); \ + (cpu) < NR_CPUS; \ + (cpu) = next_cpu((cpu), (mask))) +#else /* NR_CPUS == 1 */ +#define for_each_cpu_mask(cpu, mask) for ((cpu) = 0; (cpu) < 1; (cpu)++) +#endif /* NR_CPUS */ + +/* + * The following particular system cpumasks and operations manage + * possible, present and online cpus. Each of them is a fixed size + * bitmap of size NR_CPUS. + * + * #ifdef CONFIG_HOTPLUG_CPU + * cpu_possible_map - all NR_CPUS bits set + * cpu_present_map - has bit 'cpu' set iff cpu is populated + * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler + * #else + * cpu_possible_map - has bit 'cpu' set iff cpu is populated + * cpu_present_map - copy of cpu_possible_map + * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler + * #endif + * + * In either case, NR_CPUS is fixed at compile time, as the static + * size of these bitmaps. The cpu_possible_map is fixed at boot + * time, as the set of CPU id's that it is possible might ever + * be plugged in at anytime during the life of that system boot. + * The cpu_present_map is dynamic(*), representing which CPUs + * are currently plugged in. And cpu_online_map is the dynamic + * subset of cpu_present_map, indicating those CPUs available + * for scheduling. + * + * If HOTPLUG is enabled, then cpu_possible_map is forced to have + * all NR_CPUS bits set, otherwise it is just the set of CPUs that + * ACPI reports present at boot. + * + * If HOTPLUG is enabled, then cpu_present_map varies dynamically, + * depending on what ACPI reports as currently plugged in, otherwise + * cpu_present_map is just a copy of cpu_possible_map. + * + * (*) Well, cpu_present_map is dynamic in the hotplug case. If not + * hotplug, it's a copy of cpu_possible_map, hence fixed at boot. + * + * Subtleties: + * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode + * assumption that their single CPU is online. The UP + * cpu_{online,possible,present}_maps are placebos. Changing them + * will have no useful affect on the following num_*_cpus() + * and cpu_*() macros in the UP case. This ugliness is a UP + * optimization - don't waste any instructions or memory references + * asking if you're online or how many CPUs there are if there is + * only one CPU. + * 2) Most SMP arch's #define some of these maps to be some + * other map specific to that arch. Therefore, the following + * must be #define macros, not inlines. To see why, examine + * the assembly code produced by the following. Note that + * set1() writes phys_x_map, but set2() writes x_map: + * int x_map, phys_x_map; + * #define set1(a) x_map = a + * inline void set2(int a) { x_map = a; } + * #define x_map phys_x_map + * main(){ set1(3); set2(5); } + */ + +extern cpumask_t cpu_possible_map; +extern cpumask_t cpu_online_map; extern cpumask_t cpu_present_map; -#define num_present_cpus() cpus_weight(cpu_present_map) -#define cpu_present(cpu) cpu_isset(cpu, cpu_present_map) -#define for_each_present_cpu(cpu) for_each_cpu_mask(cpu, cpu_present_map) -#define cpumask_scnprintf(buf, buflen, map) \ - bitmap_scnprintf(buf, buflen, cpus_addr(map), NR_CPUS) +#if NR_CPUS > 1 +#define num_online_cpus() cpus_weight(cpu_online_map) +#define num_possible_cpus() cpus_weight(cpu_possible_map) +#define num_present_cpus() cpus_weight(cpu_present_map) +#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) +#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) +#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) +#else +#define num_online_cpus() 1 +#define num_possible_cpus() 1 +#define num_present_cpus() 1 +#define cpu_online(cpu) ((cpu) == 0) +#define cpu_possible(cpu) ((cpu) == 0) +#define cpu_present(cpu) ((cpu) == 0) +#endif + +#define any_online_cpu(mask) \ +({ \ + int cpu; \ + for_each_cpu_mask(cpu, (mask)) \ + if (cpu_online(cpu)) \ + break; \ + cpu; \ +}) + +#define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) +#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) +#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) -#define cpumask_parse(buf, buflen, map) \ - bitmap_parse(buf, buflen, cpus_addr(map), NR_CPUS) +/* Begin obsolete cpumask operator emulation */ +#define cpu_isset_const(a,b) cpu_isset(a,b) +#define cpumask_const_t cpumask_t +#define cpus_coerce(m) (cpus_addr(m)[0]) +#define cpus_coerce_const cpus_coerce +#define cpus_promote(x) ({ cpumask_t m; m.bits[0] = x; m; }) +#define cpus_weight_const cpus_weight +#define first_cpu_const first_cpu +#define mk_cpumask_const(x) x +#define next_cpu_const next_cpu +/* End of obsolete cpumask operator emulation */ #endif /* __LINUX_CPUMASK_H */ diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 7282889a5fd9..f35f944abe3d 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -129,17 +129,14 @@ static void rcu_do_batch(struct rcu_head *list) */ static void rcu_start_batch(int next_pending) { - cpumask_t active; - if (next_pending) rcu_ctrlblk.next_pending = 1; if (rcu_ctrlblk.next_pending && rcu_ctrlblk.completed == rcu_ctrlblk.cur) { /* Can't change, since spin lock held. */ - active = nohz_cpu_mask; - cpus_complement(active); - cpus_and(rcu_state.rcu_cpu_mask, cpu_online_map, active); + cpus_andnot(rcu_state.rcu_cpu_mask, cpu_online_map, + nohz_cpu_mask); write_seqcount_begin(&rcu_ctrlblk.lock); rcu_ctrlblk.next_pending = 0; rcu_ctrlblk.cur++; diff --git a/kernel/sched.c b/kernel/sched.c index a614d7ebf7c3..f0103ee1d66a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2951,6 +2951,11 @@ out_unlock: cpumask_t cpu_present_map; EXPORT_SYMBOL(cpu_present_map); +#ifndef CONFIG_SMP +cpumask_t cpu_online_map = CPU_MASK_ALL; +cpumask_t cpu_possible_map = CPU_MASK_ALL; +#endif + /** * sys_sched_getaffinity - get the cpu affinity of a process * @pid: pid of the process -- cgit v1.2.3 From ed880528b07445a2b3932f839727d7d740f03cc4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:14 -0700 Subject: [PATCH] cpumask: remove 26 no longer used cpumask*.h files From: Paul Jackson With the cpumask rewrite in the previous patch, these various include/asm-*/cpumask*.h headers are no longer used. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/cpumask.h | 6 --- include/asm-arm/cpumask.h | 6 --- include/asm-arm26/cpumask.h | 6 --- include/asm-cris/cpumask.h | 6 --- include/asm-generic/cpumask.h | 40 ------------------ include/asm-generic/cpumask_arith.h | 49 ---------------------- include/asm-generic/cpumask_array.h | 54 ------------------------ include/asm-generic/cpumask_const_reference.h | 29 ------------- include/asm-generic/cpumask_const_value.h | 21 ---------- include/asm-generic/cpumask_up.h | 59 --------------------------- include/asm-h8300/cpumask.h | 6 --- include/asm-i386/cpumask.h | 6 --- include/asm-ia64/cpumask.h | 6 --- include/asm-m68k/cpumask.h | 6 --- include/asm-m68knommu/cpumask.h | 6 --- include/asm-mips/cpumask.h | 6 --- include/asm-parisc/cpumask.h | 6 --- include/asm-ppc/cpumask.h | 6 --- include/asm-ppc64/cpumask.h | 6 --- include/asm-s390/cpumask.h | 6 --- include/asm-sh/cpumask.h | 6 --- include/asm-sparc/cpumask.h | 6 --- include/asm-sparc64/cpumask.h | 6 --- include/asm-um/cpumask.h | 6 --- include/asm-v850/cpumask.h | 6 --- include/asm-x86_64/cpumask.h | 6 --- 26 files changed, 372 deletions(-) delete mode 100644 include/asm-alpha/cpumask.h delete mode 100644 include/asm-arm/cpumask.h delete mode 100644 include/asm-arm26/cpumask.h delete mode 100644 include/asm-cris/cpumask.h delete mode 100644 include/asm-generic/cpumask.h delete mode 100644 include/asm-generic/cpumask_arith.h delete mode 100644 include/asm-generic/cpumask_array.h delete mode 100644 include/asm-generic/cpumask_const_reference.h delete mode 100644 include/asm-generic/cpumask_const_value.h delete mode 100644 include/asm-generic/cpumask_up.h delete mode 100644 include/asm-h8300/cpumask.h delete mode 100644 include/asm-i386/cpumask.h delete mode 100644 include/asm-ia64/cpumask.h delete mode 100644 include/asm-m68k/cpumask.h delete mode 100644 include/asm-m68knommu/cpumask.h delete mode 100644 include/asm-mips/cpumask.h delete mode 100644 include/asm-parisc/cpumask.h delete mode 100644 include/asm-ppc/cpumask.h delete mode 100644 include/asm-ppc64/cpumask.h delete mode 100644 include/asm-s390/cpumask.h delete mode 100644 include/asm-sh/cpumask.h delete mode 100644 include/asm-sparc/cpumask.h delete mode 100644 include/asm-sparc64/cpumask.h delete mode 100644 include/asm-um/cpumask.h delete mode 100644 include/asm-v850/cpumask.h delete mode 100644 include/asm-x86_64/cpumask.h diff --git a/include/asm-alpha/cpumask.h b/include/asm-alpha/cpumask.h deleted file mode 100644 index bc3381ad1643..000000000000 --- a/include/asm-alpha/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_ALPHA_CPUMASK_H -#define _ASM_ALPHA_CPUMASK_H - -#include - -#endif /* _ASM_ALPHA_CPUMASK_H */ diff --git a/include/asm-arm/cpumask.h b/include/asm-arm/cpumask.h deleted file mode 100644 index e3cf01fdf9c9..000000000000 --- a/include/asm-arm/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_ARM_CPUMASK_H -#define _ASM_ARM_CPUMASK_H - -#include - -#endif /* _ASM_ARM_CPUMASK_H */ diff --git a/include/asm-arm26/cpumask.h b/include/asm-arm26/cpumask.h deleted file mode 100644 index d181df4ed512..000000000000 --- a/include/asm-arm26/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_ARM26_CPUMASK_H -#define _ASM_ARM26_CPUMASK_H - -#include - -#endif /* _ASM_ARM26_CPUMASK_H */ diff --git a/include/asm-cris/cpumask.h b/include/asm-cris/cpumask.h deleted file mode 100644 index 123b032a6eae..000000000000 --- a/include/asm-cris/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_CRIS_CPUMASK_H -#define _ASM_CRIS_CPUMASK_H - -#include - -#endif /* _ASM_CRIS_CPUMASK_H */ diff --git a/include/asm-generic/cpumask.h b/include/asm-generic/cpumask.h deleted file mode 100644 index a5103259d7a9..000000000000 --- a/include/asm-generic/cpumask.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_H -#define __ASM_GENERIC_CPUMASK_H - -#include -#include -#include -#include -#include - -#if NR_CPUS > BITS_PER_LONG && NR_CPUS != 1 -#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS) - -struct cpumask -{ - unsigned long mask[CPU_ARRAY_SIZE]; -}; - -typedef struct cpumask cpumask_t; - -#else -typedef unsigned long cpumask_t; -#endif - -#ifdef CONFIG_SMP -#if NR_CPUS > BITS_PER_LONG -#include -#else -#include -#endif -#else -#include -#endif - -#if NR_CPUS <= 4*BITS_PER_LONG -#include -#else -#include -#endif - -#endif /* __ASM_GENERIC_CPUMASK_H */ diff --git a/include/asm-generic/cpumask_arith.h b/include/asm-generic/cpumask_arith.h deleted file mode 100644 index b4d25ac46a9f..000000000000 --- a/include/asm-generic/cpumask_arith.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_ARITH_H -#define __ASM_GENERIC_CPUMASK_ARITH_H - -/* - * Arithmetic type -based cpu bitmaps. A single unsigned long is used - * to contain the whole cpu bitmap. - */ - -#define cpu_set(cpu, map) set_bit(cpu, &(map)) -#define cpu_clear(cpu, map) clear_bit(cpu, &(map)) -#define cpu_isset(cpu, map) test_bit(cpu, &(map)) -#define cpu_test_and_set(cpu, map) test_and_set_bit(cpu, &(map)) - -#define cpus_and(dst,src1,src2) do { dst = (src1) & (src2); } while (0) -#define cpus_or(dst,src1,src2) do { dst = (src1) | (src2); } while (0) -#define cpus_clear(map) do { map = 0; } while (0) -#define cpus_complement(map) do { map = ~(map); } while (0) -#define cpus_equal(map1, map2) ((map1) == (map2)) -#define cpus_empty(map) ((map) == 0) -#define cpus_addr(map) (&(map)) - -#if BITS_PER_LONG == 32 -#define cpus_weight(map) hweight32(map) -#elif BITS_PER_LONG == 64 -#define cpus_weight(map) hweight64(map) -#endif - -#define cpus_shift_right(dst, src, n) do { dst = (src) >> (n); } while (0) -#define cpus_shift_left(dst, src, n) do { dst = (src) << (n); } while (0) - -#define any_online_cpu(map) \ -({ \ - cpumask_t __tmp__; \ - cpus_and(__tmp__, map, cpu_online_map); \ - __tmp__ ? first_cpu(__tmp__) : NR_CPUS; \ -}) - -#define CPU_MASK_ALL (~((cpumask_t)0) >> (8*sizeof(cpumask_t) - NR_CPUS)) -#define CPU_MASK_NONE ((cpumask_t)0) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce(map) ((unsigned long)(map)) -#define cpus_promote(map) ({ map; }) -#define cpumask_of_cpu(cpu) ({ ((cpumask_t)1) << (cpu); }) - -#define first_cpu(map) find_first_bit(&(map), NR_CPUS) -#define next_cpu(cpu, map) find_next_bit(&(map), NR_CPUS, cpu + 1) - -#endif /* __ASM_GENERIC_CPUMASK_ARITH_H */ diff --git a/include/asm-generic/cpumask_array.h b/include/asm-generic/cpumask_array.h deleted file mode 100644 index 1be08ae2e93b..000000000000 --- a/include/asm-generic/cpumask_array.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_ARRAY_H -#define __ASM_GENERIC_CPUMASK_ARRAY_H - -/* - * Array-based cpu bitmaps. An array of unsigned longs is used to contain - * the bitmap, and then contained in a structure so it may be passed by - * value. - */ - -#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS) - -#define cpu_set(cpu, map) set_bit(cpu, (map).mask) -#define cpu_clear(cpu, map) clear_bit(cpu, (map).mask) -#define cpu_isset(cpu, map) test_bit(cpu, (map).mask) -#define cpu_test_and_set(cpu, map) test_and_set_bit(cpu, (map).mask) - -#define cpus_and(dst,src1,src2) bitmap_and((dst).mask,(src1).mask, (src2).mask, NR_CPUS) -#define cpus_or(dst,src1,src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS) -#define cpus_clear(map) bitmap_zero((map).mask, NR_CPUS) -#define cpus_complement(map) bitmap_complement((map).mask, (map).mask, NR_CPUS) -#define cpus_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, NR_CPUS) -#define cpus_empty(map) bitmap_empty(map.mask, NR_CPUS) -#define cpus_addr(map) ((map).mask) -#define cpus_weight(map) bitmap_weight((map).mask, NR_CPUS) -#define cpus_shift_right(d, s, n) bitmap_shift_right((d).mask, (s).mask, n, NR_CPUS) -#define cpus_shift_left(d, s, n) bitmap_shift_left((d).mask, (s).mask, n, NR_CPUS) -#define first_cpu(map) find_first_bit((map).mask, NR_CPUS) -#define next_cpu(cpu, map) find_next_bit((map).mask, NR_CPUS, cpu + 1) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce(map) ((map).mask[0]) -#define cpus_promote(map) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ - __cpu_mask.mask[0] = map; \ - __cpu_mask; \ - }) -#define cpumask_of_cpu(cpu) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ - cpu_set(cpu, __cpu_mask); \ - __cpu_mask; \ - }) -#define any_online_cpu(map) \ -({ \ - cpumask_t __tmp__; \ - cpus_and(__tmp__, map, cpu_online_map); \ - find_first_bit(__tmp__.mask, NR_CPUS); \ -}) - - -/* - * um, these need to be usable as static initializers - */ -#define CPU_MASK_ALL ((cpumask_t) { {[0 ... CPU_ARRAY_SIZE-1] = ~0UL} }) -#define CPU_MASK_NONE ((cpumask_t) { {[0 ... CPU_ARRAY_SIZE-1] = 0UL} }) - -#endif /* __ASM_GENERIC_CPUMASK_ARRAY_H */ diff --git a/include/asm-generic/cpumask_const_reference.h b/include/asm-generic/cpumask_const_reference.h deleted file mode 100644 index e98da01bcfdf..000000000000 --- a/include/asm-generic/cpumask_const_reference.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H -#define __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H - -struct cpumask_ref { - const cpumask_t *val; -}; - -typedef const struct cpumask_ref cpumask_const_t; - -#define mk_cpumask_const(map) ((cpumask_const_t){ &(map) }) -#define cpu_isset_const(cpu, map) cpu_isset(cpu, *(map).val) - -#define cpus_and_const(dst,src1,src2) cpus_and(dst,*(src1).val,*(src2).val) -#define cpus_or_const(dst,src1,src2) cpus_or(dst,*(src1).val,*(src2).val) - -#define cpus_equal_const(map1, map2) cpus_equal(*(map1).val, *(map2).val) - -#define cpus_copy_const(map1, map2) bitmap_copy((map1).mask, (map2).val->mask, NR_CPUS) - -#define cpus_empty_const(map) cpus_empty(*(map).val) -#define cpus_weight_const(map) cpus_weight(*(map).val) -#define first_cpu_const(map) first_cpu(*(map).val) -#define next_cpu_const(cpu, map) next_cpu(cpu, *(map).val) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce_const(map) cpus_coerce(*(map).val) -#define any_online_cpu_const(map) any_online_cpu(*(map).val) - -#endif /* __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H */ diff --git a/include/asm-generic/cpumask_const_value.h b/include/asm-generic/cpumask_const_value.h deleted file mode 100644 index 16ca16d286dc..000000000000 --- a/include/asm-generic/cpumask_const_value.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_CONST_VALUE_H -#define __ASM_GENERIC_CPUMASK_CONST_VALUE_H - -typedef const cpumask_t cpumask_const_t; - -#define mk_cpumask_const(map) (map) -#define cpu_isset_const(cpu, map) cpu_isset(cpu, map) -#define cpus_and_const(dst,src1,src2) cpus_and(dst, src1, src2) -#define cpus_or_const(dst,src1,src2) cpus_or(dst, src1, src2) -#define cpus_equal_const(map1, map2) cpus_equal(map1, map2) -#define cpus_empty_const(map) cpus_empty(map) -#define cpus_copy_const(map1, map2) do { map1 = (cpumask_t)map2; } while (0) -#define cpus_weight_const(map) cpus_weight(map) -#define first_cpu_const(map) first_cpu(map) -#define next_cpu_const(cpu, map) next_cpu(cpu, map) - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_coerce_const(map) cpus_coerce(map) -#define any_online_cpu_const(map) any_online_cpu(map) - -#endif /* __ASM_GENERIC_CPUMASK_CONST_VALUE_H */ diff --git a/include/asm-generic/cpumask_up.h b/include/asm-generic/cpumask_up.h deleted file mode 100644 index f55c265a0e3b..000000000000 --- a/include/asm-generic/cpumask_up.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __ASM_GENERIC_CPUMASK_UP_H -#define __ASM_GENERIC_CPUMASK_UP_H - -#define cpus_coerce(map) (map) - -#define cpu_set(cpu, map) do { (void)(cpu); cpus_coerce(map) = 1UL; } while (0) -#define cpu_clear(cpu, map) do { (void)(cpu); cpus_coerce(map) = 0UL; } while (0) -#define cpu_isset(cpu, map) ((void)(cpu), cpus_coerce(map) != 0UL) -#define cpu_test_and_set(cpu, map) ((void)(cpu), test_and_set_bit(0, &(map))) - -#define cpus_and(dst, src1, src2) \ - do { \ - if (cpus_coerce(src1) && cpus_coerce(src2)) \ - cpus_coerce(dst) = 1UL; \ - else \ - cpus_coerce(dst) = 0UL; \ - } while (0) - -#define cpus_or(dst, src1, src2) \ - do { \ - if (cpus_coerce(src1) || cpus_coerce(src2)) \ - cpus_coerce(dst) = 1UL; \ - else \ - cpus_coerce(dst) = 0UL; \ - } while (0) - -#define cpus_clear(map) do { cpus_coerce(map) = 0UL; } while (0) - -#define cpus_complement(map) \ - do { \ - cpus_coerce(map) = !cpus_coerce(map); \ - } while (0) - -#define cpus_equal(map1, map2) (cpus_coerce(map1) == cpus_coerce(map2)) -#define cpus_empty(map) (cpus_coerce(map) == 0UL) -#define cpus_addr(map) (&(map)) -#define cpus_weight(map) (cpus_coerce(map) ? 1UL : 0UL) -#define cpus_shift_right(d, s, n) do { cpus_coerce(d) = 0UL; } while (0) -#define cpus_shift_left(d, s, n) do { cpus_coerce(d) = 0UL; } while (0) -#define first_cpu(map) (cpus_coerce(map) ? 0 : 1) -#define next_cpu(cpu, map) 1 - -/* only ever use this for things that are _never_ used on large boxen */ -#define cpus_promote(map) \ - ({ \ - cpumask_t __tmp__; \ - cpus_coerce(__tmp__) = map; \ - __tmp__; \ - }) -#define cpumask_of_cpu(cpu) ((void)(cpu), cpus_promote(1)) -#define any_online_cpu(map) (cpus_coerce(map) ? 0 : 1) - -/* - * um, these need to be usable as static initializers - */ -#define CPU_MASK_ALL 1UL -#define CPU_MASK_NONE 0UL - -#endif /* __ASM_GENERIC_CPUMASK_UP_H */ diff --git a/include/asm-h8300/cpumask.h b/include/asm-h8300/cpumask.h deleted file mode 100644 index 3b403850c043..000000000000 --- a/include/asm-h8300/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_H8300_CPUMASK_H -#define _ASM_H8300_CPUMASK_H - -#include - -#endif /* _ASM_H8300_CPUMASK_H */ diff --git a/include/asm-i386/cpumask.h b/include/asm-i386/cpumask.h deleted file mode 100644 index 8bf5a829c528..000000000000 --- a/include/asm-i386/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_I386_CPUMASK_H -#define _ASM_I386_CPUMASK_H - -#include - -#endif /* _ASM_I386_CPUMASK_H */ diff --git a/include/asm-ia64/cpumask.h b/include/asm-ia64/cpumask.h deleted file mode 100644 index 7764aef653e8..000000000000 --- a/include/asm-ia64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_IA64_CPUMASK_H -#define _ASM_IA64_CPUMASK_H - -#include - -#endif /* _ASM_IA64_CPUMASK_H */ diff --git a/include/asm-m68k/cpumask.h b/include/asm-m68k/cpumask.h deleted file mode 100644 index b12450332e19..000000000000 --- a/include/asm-m68k/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68K_CPUMASK_H -#define _ASM_M68K_CPUMASK_H - -#include - -#endif /* _ASM_M68K_CPUMASK_H */ diff --git a/include/asm-m68knommu/cpumask.h b/include/asm-m68knommu/cpumask.h deleted file mode 100644 index cd9cc78af838..000000000000 --- a/include/asm-m68knommu/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68KNOMMU_CPUMASK_H -#define _ASM_M68KNOMMU_CPUMASK_H - -#include - -#endif /* _ASM_M68KNOMMU_CPUMASK_H */ diff --git a/include/asm-mips/cpumask.h b/include/asm-mips/cpumask.h deleted file mode 100644 index cf562af10d6f..000000000000 --- a/include/asm-mips/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_MIPS_CPUMASK_H -#define _ASM_MIPS_CPUMASK_H - -#include - -#endif /* _ASM_MIPS_CPUMASK_H */ diff --git a/include/asm-parisc/cpumask.h b/include/asm-parisc/cpumask.h deleted file mode 100644 index 27f4f17fb15a..000000000000 --- a/include/asm-parisc/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PARISC_CPUMASK_H -#define _ASM_PARISC_CPUMASK_H - -#include - -#endif /* _ASM_PARISC_CPUMASK_H */ diff --git a/include/asm-ppc/cpumask.h b/include/asm-ppc/cpumask.h deleted file mode 100644 index 30901089dd41..000000000000 --- a/include/asm-ppc/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PPC_CPUMASK_H -#define _ASM_PPC_CPUMASK_H - -#include - -#endif /* _ASM_PPC_CPUMASK_H */ diff --git a/include/asm-ppc64/cpumask.h b/include/asm-ppc64/cpumask.h deleted file mode 100644 index 0914511db218..000000000000 --- a/include/asm-ppc64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PPC64_CPUMASK_H -#define _ASM_PPC64_CPUMASK_H - -#include - -#endif /* _ASM_PPC64_CPUMASK_H */ diff --git a/include/asm-s390/cpumask.h b/include/asm-s390/cpumask.h deleted file mode 100644 index 4deef1641ec6..000000000000 --- a/include/asm-s390/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_S390_CPUMASK_H -#define _ASM_S390_CPUMASK_H - -#include - -#endif /* _ASM_S390_CPUMASK_H */ diff --git a/include/asm-sh/cpumask.h b/include/asm-sh/cpumask.h deleted file mode 100644 index deaf3bb85d7e..000000000000 --- a/include/asm-sh/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SH_CPUMASK_H -#define _ASM_SH_CPUMASK_H - -#include - -#endif /* _ASM_SH_CPUMASK_H */ diff --git a/include/asm-sparc/cpumask.h b/include/asm-sparc/cpumask.h deleted file mode 100644 index 272f31de7bc1..000000000000 --- a/include/asm-sparc/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SPARC_CPUMASK_H -#define _ASM_SPARC_CPUMASK_H - -#include - -#endif /* _ASM_SPARC_CPUMASK_H */ diff --git a/include/asm-sparc64/cpumask.h b/include/asm-sparc64/cpumask.h deleted file mode 100644 index ee60cae3dcd1..000000000000 --- a/include/asm-sparc64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SPARC64_CPUMASK_H -#define _ASM_SPARC64_CPUMASK_H - -#include - -#endif /* _ASM_SPARC64_CPUMASK_H */ diff --git a/include/asm-um/cpumask.h b/include/asm-um/cpumask.h deleted file mode 100644 index 90f0d003d74e..000000000000 --- a/include/asm-um/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_CPUMASK_H -#define _ASM_UM_CPUMASK_H - -#include - -#endif /* _ASM_UM_CPUMASK_H */ diff --git a/include/asm-v850/cpumask.h b/include/asm-v850/cpumask.h deleted file mode 100644 index 09aebd0c28d7..000000000000 --- a/include/asm-v850/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_V850_CPUMASK_H -#define _ASM_V850_CPUMASK_H - -#include - -#endif /* _ASM_V850_CPUMASK_H */ diff --git a/include/asm-x86_64/cpumask.h b/include/asm-x86_64/cpumask.h deleted file mode 100644 index d9ea497140a1..000000000000 --- a/include/asm-x86_64/cpumask.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_X86_64_CPUMASK_H -#define _ASM_X86_64_CPUMASK_H - -#include - -#endif /* _ASM_X86_64_CPUMASK_H */ -- cgit v1.2.3 From 9eb0dcc1d86252f9f216fd2f09868fdd28272abd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:25 -0700 Subject: [PATCH] cpumask: remove obsolete cpumask macro uses - i386 arch From: Paul Jackson Remove by recoding i386 uses of the obsolete cpumask const, coerce and promote macros. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 2 +- arch/i386/kernel/smp.c | 2 +- arch/i386/mach-voyager/voyager_smp.c | 30 +++++++++++++++--------------- include/asm-i386/genapic.h | 2 +- include/asm-i386/mach-bigsmp/mach_apic.h | 10 +++++----- include/asm-i386/mach-default/mach_apic.h | 10 +++++----- include/asm-i386/mach-es7000/mach_apic.h | 10 +++++----- include/asm-i386/mach-numaq/mach_apic.h | 2 +- include/asm-i386/mach-summit/mach_apic.h | 8 ++++---- include/asm-i386/mach-visws/mach_apic.h | 4 ++-- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 70f329ed696f..28b4d7c4e3c6 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -224,7 +224,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) struct irq_pin_list *entry = irq_2_pin + irq; unsigned int apicid_value; - apicid_value = cpu_mask_to_apicid(mk_cpumask_const(cpumask)); + apicid_value = cpu_mask_to_apicid(cpumask); /* Prepare to do the io_apic_write */ apicid_value = apicid_value << 24; spin_lock_irqsave(&ioapic_lock, flags); diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index c4313dcfe63c..5e3ac93253d2 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -159,7 +159,7 @@ void fastcall send_IPI_self(int vector) */ inline void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) { - unsigned long mask = cpus_coerce(cpumask); + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index b99561d19839..90c918f11f0b 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -153,7 +153,7 @@ static inline void send_CPI_allbutself(__u8 cpi) { __u8 cpu = smp_processor_id(); - __u32 mask = cpus_coerce(cpu_online_map) & ~(1 << cpu); + __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu); send_CPI(mask, cpi); } @@ -402,11 +402,11 @@ find_smp_config(void) /* set up everything for just this CPU, we can alter * this as we start the other CPUs later */ /* now get the CPU disposition from the extended CMOS */ - phys_cpu_present_map = cpus_promote(voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK)); - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; - cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; - printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_coerce(phys_cpu_present_map)); + cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; + cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; + printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]); /* Here we set up the VIC to enable SMP */ /* enable the CPIs by writing the base vector to their register */ outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); @@ -706,12 +706,12 @@ smp_boot_cpus(void) /* now that the cat has probed the Voyager System Bus, sanity * check the cpu map */ if( ((voyager_quad_processors | voyager_extended_vic_processors) - & cpus_coerce(phys_cpu_present_map)) != cpus_coerce(phys_cpu_present_map)) { + & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) { /* should panic */ printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n"); } } else if(voyager_level == 4) - voyager_extended_vic_processors = cpus_coerce(phys_cpu_present_map); + voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0]; /* this sets up the idle task to run on the current cpu */ voyager_extended_cpus = 1; @@ -909,7 +909,7 @@ flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, if (!cpumask) BUG(); - if ((cpumask & cpus_coerce(cpu_online_map)) != cpumask) + if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask) BUG(); if (cpumask & (1 << smp_processor_id())) BUG(); @@ -952,7 +952,7 @@ flush_tlb_current_task(void) preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); local_flush_tlb(); if (cpu_mask) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); @@ -968,7 +968,7 @@ flush_tlb_mm (struct mm_struct * mm) preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if (current->mm) @@ -989,7 +989,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) preempt_disable(); - cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id()); + cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); if (current->active_mm == mm) { if(current->mm) __flush_tlb_one(va); @@ -1098,7 +1098,7 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait) { struct call_data_struct data; - __u32 mask = cpus_coerce(cpu_online_map); + __u32 mask = cpus_addr(cpu_online_map)[0]; mask &= ~(1<= NR_CPUS) - cpu = first_cpu_const(cpu_online_map); + cpu = first_cpu(cpu_online_map); else - cpu = next_cpu_const(cpu, cpu_online_map); + cpu = next_cpu(cpu, cpu_online_map); } while (cpu >= NR_CPUS); - return mk_cpumask_const(cpumask_of_cpu(cpu)); + return cpumask_of_cpu(cpu); } #define TARGET_CPUS (target_cpus()) @@ -149,12 +149,12 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) } /* As we are using single CPU as destination, pick only one CPU here */ -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { int cpu; int apicid; - cpu = first_cpu_const(cpumask); + cpu = first_cpu(cpumask); apicid = cpu_to_logical_apicid(cpu); return apicid; } diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h index 87f688705979..627f1cd084ba 100644 --- a/include/asm-i386/mach-default/mach_apic.h +++ b/include/asm-i386/mach-default/mach_apic.h @@ -6,12 +6,12 @@ #define APIC_DFR_VALUE (APIC_DFR_FLAT) -static inline cpumask_const_t target_cpus(void) +static inline cpumask_t target_cpus(void) { #ifdef CONFIG_SMP - return mk_cpumask_const(cpu_online_map); + return cpu_online_map; #else - return mk_cpumask_const(cpumask_of_cpu(0)); + return cpumask_of_cpu(0); #endif } #define TARGET_CPUS (target_cpus()) @@ -116,9 +116,9 @@ static inline int apic_id_registered(void) return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { - return cpus_coerce_const(cpumask); + return cpus_addr(cpumask)[0]; } static inline void enable_apic_mode(void) diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h index fd0430c77565..888f7f04262d 100644 --- a/include/asm-i386/mach-es7000/mach_apic.h +++ b/include/asm-i386/mach-es7000/mach_apic.h @@ -88,7 +88,7 @@ static inline void clustered_apic_check(void) int apic = bios_cpu_apicid[smp_processor_id()]; printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", (apic_version[apic] == 0x14) ? - "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_coerce(TARGET_CPUS)); + "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]); } static inline int multi_timer_check(int apic, int irq) @@ -158,14 +158,14 @@ static inline int check_phys_apicid_present(int cpu_physical_apicid) return (1); } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - num_bits_set = cpus_weight_const(cpumask); + num_bits_set = cpus_weight(cpumask); /* Return id to all */ if (num_bits_set == NR_CPUS) #if defined CONFIG_ES7000_CLUSTERED_APIC @@ -177,10 +177,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = first_cpu_const(cpumask); + cpu = first_cpu(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpu_isset_const(cpu, cpumask)) { + if (cpu_isset(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index b66e78d7b6df..e40c308b15d3 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -135,7 +135,7 @@ static inline void enable_apic_mode(void) * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { return (int) 0xF; } diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index 9ea48a79d629..4bf36ddba96d 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -139,14 +139,14 @@ static inline void enable_apic_mode(void) { } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { int num_bits_set; int cpus_found = 0; int cpu; int apicid; - num_bits_set = cpus_weight_const(cpumask); + num_bits_set = cpus_weight(cpumask); /* Return id to all */ if (num_bits_set == NR_CPUS) return (int) 0xFF; @@ -154,10 +154,10 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) * The cpus in the mask must all be on the apic cluster. If are not * on the same apicid cluster return default value of TARGET_CPUS. */ - cpu = first_cpu_const(cpumask); + cpu = first_cpu(cpumask); apicid = cpu_to_logical_apicid(cpu); while (cpus_found < num_bits_set) { - if (cpu_isset_const(cpu, cpumask)) { + if (cpu_isset(cpu, cpumask)) { int new_apicid = cpu_to_logical_apicid(cpu); if (apicid_cluster(apicid) != apicid_cluster(new_apicid)){ diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h index 4b92eabb92ff..c367d820f23f 100644 --- a/include/asm-i386/mach-visws/mach_apic.h +++ b/include/asm-i386/mach-visws/mach_apic.h @@ -86,9 +86,9 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { - return cpus_coerce_const(cpumask); + return cpus_addr(cpumask)[0]; } static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) -- cgit v1.2.3 From 7f1c9f57926f2249f01143b18fbc26cb57ef28bf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:37 -0700 Subject: [PATCH] cpumask: remove obsolete cpumask macro uses - other archs From: Paul Jackson Remove by recoding other uses of the obsolete cpumask const, coerce and promote macros. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/open_pic.c | 8 ++++---- arch/ppc64/kernel/rtasd.c | 6 +++--- arch/x86_64/kernel/io_apic.c | 2 +- arch/x86_64/kernel/pci-gart.c | 4 ++-- arch/x86_64/kernel/smp.c | 2 +- include/asm-x86_64/smp.h | 5 ++--- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c index 0eed791f3eb6..874afcb5f1a4 100644 --- a/arch/ppc64/kernel/open_pic.c +++ b/arch/ppc64/kernel/open_pic.c @@ -591,7 +591,7 @@ static inline u32 physmask(u32 cpumask) void openpic_init_processor(u_int cpumask) { openpic_write(&OpenPIC->Global.Processor_Initialization, - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } #ifdef CONFIG_SMP @@ -625,7 +625,7 @@ void openpic_cause_IPI(u_int ipi, u_int cpumask) CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } void openpic_request_IPIs(void) @@ -711,7 +711,7 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask) { check_arg_timer(timer); openpic_write(&OpenPIC->Global.Timer[timer].Destination, - physmask(cpumask & cpus_coerce(cpu_online_map))); + physmask(cpumask & cpus_addr(cpu_online_map)[0])); } @@ -844,7 +844,7 @@ static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask) cpumask_t tmp; cpus_and(tmp, cpumask, cpu_online_map); - openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_coerce(tmp))); + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_addr(tmp)[0])); } #ifdef CONFIG_SMP diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c index eea82c7b29d1..243d2ee8de8a 100644 --- a/arch/ppc64/kernel/rtasd.c +++ b/arch/ppc64/kernel/rtasd.c @@ -415,7 +415,7 @@ static int rtasd(void *unused) } lock_cpu_hotplug(); - cpu = first_cpu_const(mk_cpumask_const(cpu_online_map)); + cpu = first_cpu(cpu_online_map); for (;;) { set_cpus_allowed(current, cpumask_of_cpu(cpu)); do_event_scan(event_scan); @@ -429,9 +429,9 @@ static int rtasd(void *unused) schedule_timeout((HZ*60/rtas_event_scan_rate) / 2); lock_cpu_hotplug(); - cpu = next_cpu_const(cpu, mk_cpumask_const(cpu_online_map)); + cpu = next_cpu(cpu, cpu_online_map); if (cpu == NR_CPUS) - cpu = first_cpu_const(mk_cpumask_const(cpu_online_map)); + cpu = first_cpu(cpu_online_map); } error: diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 718504a32741..3c3a310be3e1 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1384,7 +1384,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) unsigned long flags; unsigned int dest; - dest = cpu_mask_to_apicid(mk_cpumask_const(mask)); + dest = cpu_mask_to_apicid(mask); /* * Only the first 8 bits are valid. diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index fd1c2d79131d..261700eacb18 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -148,7 +148,7 @@ static void flush_gart(struct pci_dev *dev) { unsigned long flags; int bus = dev ? dev->bus->number : -1; - cpumask_const_t bus_cpumask = pcibus_to_cpumask(bus); + cpumask_t bus_cpumask = pcibus_to_cpumask(bus); int flushed = 0; int i; @@ -158,7 +158,7 @@ static void flush_gart(struct pci_dev *dev) u32 w; if (!northbridges[i]) continue; - if (bus >= 0 && !(cpu_isset_const(i, bus_cpumask))) + if (bus >= 0 && !(cpu_isset(i, bus_cpumask))) continue; pci_write_config_dword(northbridges[i], 0x9c, northbridge_flush_word[i] | 1); diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index fec777046b9a..4246255697ab 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -94,7 +94,7 @@ void send_IPI_self(int vector) static inline void send_IPI_mask(cpumask_t cpumask, int vector) { - unsigned long mask = cpus_coerce(cpumask); + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; unsigned long flags; diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 2878896de037..7fe450245697 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -105,7 +105,6 @@ static inline int cpu_present_to_apicid(int mps_cpu) return BAD_APICID; } -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) #endif /* !ASSEMBLY */ #define NO_PROC_ID 0xFF /* No processor magic marker */ @@ -115,9 +114,9 @@ static inline int cpu_present_to_apicid(int mps_cpu) #define TARGET_CPUS 1 #ifndef ASSEMBLY -static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask) +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) { - return cpus_coerce_const(cpumask); + return cpus_addr(cpumask)[0]; } #endif -- cgit v1.2.3 From b8a02d077cb2e53046000591485d4767192f491a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:48 -0700 Subject: [PATCH] x86_64: cpu_online fix Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86_64/smp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 7fe450245697..c210e398a649 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -60,7 +60,6 @@ extern char phys_proc_id[NR_CPUS]; extern cpumask_t cpu_callout_map; #define cpu_possible_map cpu_callout_map -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) static inline int num_booting_cpus(void) { -- cgit v1.2.3 From ea72b2418251ee5b377136929b47ed83a24492cf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:51:59 -0700 Subject: [PATCH] ppc64: cpu_online fix include/asm/smp.h:55:1: warning: "cpu_possible" redefined include/asm/smp.h:54:1: warning: "cpu_online" redefined Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/smp.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h index 3d7e3d7c7663..3b14c7145546 100644 --- a/include/asm-ppc64/smp.h +++ b/include/asm-ppc64/smp.h @@ -51,8 +51,6 @@ extern cpumask_t cpu_possible_map; extern cpumask_t cpu_available_map; #define cpu_present_at_boot(cpu) cpu_isset(cpu, cpu_present_at_boot) -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) #define cpu_available(cpu) cpu_isset(cpu, cpu_available_map) /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. -- cgit v1.2.3 From 5ffa67fc1233d9d065f9b3fcd6bc13425af54f89 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:10 -0700 Subject: [PATCH] cpumask: Remove no longer used obsolete macro emulation From: Paul Jackson Now that the emulation of the obsolete cpumask macros is no longer needed, remove it from cpumask.h Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cpumask.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index f05bf9402dfc..4d2cf59e5089 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -364,16 +364,4 @@ extern cpumask_t cpu_present_map; #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) -/* Begin obsolete cpumask operator emulation */ -#define cpu_isset_const(a,b) cpu_isset(a,b) -#define cpumask_const_t cpumask_t -#define cpus_coerce(m) (cpus_addr(m)[0]) -#define cpus_coerce_const cpus_coerce -#define cpus_promote(x) ({ cpumask_t m; m.bits[0] = x; m; }) -#define cpus_weight_const cpus_weight -#define first_cpu_const first_cpu -#define mk_cpumask_const(x) x -#define next_cpu_const next_cpu -/* End of obsolete cpumask operator emulation */ - #endif /* __LINUX_CPUMASK_H */ -- cgit v1.2.3 From 4b81e400a9ea37a5888434234befaf389a36e72b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:21 -0700 Subject: [PATCH] cpumask: optimize various uses of new cpumasks From: Paul Jackson Make use of for_each_cpu_mask() macro to simplify and optimize a couple of sparc64 per-CPU loops. Optimize a bit of cpumask code for asm-i386/mach-es7000 Convert physids_complement() to use both args in the files include/asm-i386/mpspec.h, include/asm-x86_64/mpspec.h. Remove cpumask hack from asm-x86_64/topology.h routine pcibus_to_cpumask(). Clarify and slightly optimize several cpumask manipulations in kernel/sched.c Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/smp.c | 66 ++++++++++++--------------------- include/asm-i386/mach-es7000/mach_ipi.h | 5 +-- include/asm-i386/mpspec.h | 2 +- include/asm-x86_64/mpspec.h | 2 +- include/asm-x86_64/topology.h | 6 ++- kernel/sched.c | 18 ++++----- 6 files changed, 39 insertions(+), 60 deletions(-) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 64b873212243..58c3792b4af1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -406,14 +406,8 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c int i; __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, mask)) { - spitfire_xcall_helper(data0, data1, data2, pstate, i); - cpu_clear(i, mask); - if (cpus_empty(mask)) - break; - } - } + for_each_cpu_mask(i, mask) + spitfire_xcall_helper(data0, data1, data2, pstate, i); } /* Cheetah now allows to send the whole 64-bytes of data in the interrupt @@ -456,25 +450,19 @@ retry: nack_busy_id = 0; { - cpumask_t work_mask = mask; int i; - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, work_mask)) { - u64 target = (i << 14) | 0x70; - - if (!is_jalapeno) - target |= (nack_busy_id << 24); - __asm__ __volatile__( - "stxa %%g0, [%0] %1\n\t" - "membar #Sync\n\t" - : /* no outputs */ - : "r" (target), "i" (ASI_INTR_W)); - nack_busy_id++; - cpu_clear(i, work_mask); - if (cpus_empty(work_mask)) - break; - } + for_each_cpu_mask(i, mask) { + u64 target = (i << 14) | 0x70; + + if (!is_jalapeno) + target |= (nack_busy_id << 24); + __asm__ __volatile__( + "stxa %%g0, [%0] %1\n\t" + "membar #Sync\n\t" + : /* no outputs */ + : "r" (target), "i" (ASI_INTR_W)); + nack_busy_id++; } } @@ -507,7 +495,6 @@ retry: printk("CPU[%d]: mondo stuckage result[%016lx]\n", smp_processor_id(), dispatch_stat); } else { - cpumask_t work_mask = mask; int i, this_busy_nack = 0; /* Delay some random time with interrupts enabled @@ -518,22 +505,17 @@ retry: /* Clear out the mask bits for cpus which did not * NACK us. */ - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, work_mask)) { - u64 check_mask; - - if (is_jalapeno) - check_mask = (0x2UL << (2*i)); - else - check_mask = (0x2UL << - this_busy_nack); - if ((dispatch_stat & check_mask) == 0) - cpu_clear(i, mask); - this_busy_nack += 2; - cpu_clear(i, work_mask); - if (cpus_empty(work_mask)) - break; - } + for_each_cpu_mask(i, mask) { + u64 check_mask; + + if (is_jalapeno) + check_mask = (0x2UL << (2*i)); + else + check_mask = (0x2UL << + this_busy_nack); + if ((dispatch_stat & check_mask) == 0) + cpu_clear(i, mask); + this_busy_nack += 2; } goto retry; diff --git a/include/asm-i386/mach-es7000/mach_ipi.h b/include/asm-i386/mach-es7000/mach_ipi.h index 6b7a56c1ddd5..cb8a2fdb5c59 100644 --- a/include/asm-i386/mach-es7000/mach_ipi.h +++ b/include/asm-i386/mach-es7000/mach_ipi.h @@ -10,9 +10,8 @@ static inline void send_IPI_mask(cpumask_t mask, int vector) static inline void send_IPI_allbutself(int vector) { - cpumask_t mask = cpumask_of_cpu(smp_processor_id()); - cpus_complement(mask); - cpus_and(mask, mask, cpu_online_map); + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); if (!cpus_empty(mask)) send_IPI_mask(mask, vector); } diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index 31a9717c1a8b..8170e019af8d 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h @@ -53,7 +53,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) +#define physids_complement(dst, src) bitmap_complement((dst).mask,(src).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h index a9a6f16672f2..219d40acd489 100644 --- a/include/asm-x86_64/mpspec.h +++ b/include/asm-x86_64/mpspec.h @@ -212,7 +212,7 @@ typedef struct physid_mask physid_mask_t; #define physids_and(dst, src1, src2) bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_or(dst, src1, src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS) #define physids_clear(map) bitmap_zero((map).mask, MAX_APICS) -#define physids_complement(map) bitmap_complement((map).mask, (map).mask, MAX_APICS) +#define physids_complement(dst, src) bitmap_complement((dst).mask, (src).mask, MAX_APICS) #define physids_empty(map) bitmap_empty((map).mask, MAX_APICS) #define physids_equal(map1, map2) bitmap_equal((map1).mask, (map2).mask, MAX_APICS) #define physids_weight(map) bitmap_weight((map).mask, MAX_APICS) diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index bb9a99ba2065..9310f9a1c1c5 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h @@ -20,9 +20,11 @@ extern cpumask_t node_to_cpumask[]; #define node_to_first_cpu(node) (__ffs(node_to_cpumask[node])) #define node_to_cpumask(node) (node_to_cpumask[node]) -static inline unsigned long pcibus_to_cpumask(int bus) +static inline cpumask_t pcibus_to_cpumask(int bus) { - return mp_bus_to_cpumask[bus] & cpu_online_map; + cpumask_t tmp; + cpus_and(tmp, mp_bus_to_cpumask[bus], cpu_online_map); + return tmp; } #define NODE_BALANCE_RATE 30 /* CHECKME */ diff --git a/kernel/sched.c b/kernel/sched.c index f0103ee1d66a..017b59b8de5e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -696,10 +696,9 @@ static int wake_idle(int cpu, task_t *p) return cpu; cpus_and(tmp, sd->span, cpu_online_map); - for_each_cpu_mask(i, tmp) { - if (!cpu_isset(i, p->cpus_allowed)) - continue; + cpus_and(tmp, tmp, p->cpus_allowed); + for_each_cpu_mask(i, tmp) { if (idle_cpu(i)) return i; } @@ -3335,7 +3334,7 @@ int set_cpus_allowed(task_t *p, cpumask_t new_mask) runqueue_t *rq; rq = task_rq_lock(p, &flags); - if (any_online_cpu(new_mask) == NR_CPUS) { + if (!cpus_intersects(new_mask, cpu_online_map)) { ret = -EINVAL; goto out; } @@ -3510,8 +3509,7 @@ static void migrate_all_tasks(int src_cpu) if (dest_cpu == NR_CPUS) dest_cpu = any_online_cpu(tsk->cpus_allowed); if (dest_cpu == NR_CPUS) { - cpus_clear(tsk->cpus_allowed); - cpus_complement(tsk->cpus_allowed); + cpus_setall(tsk->cpus_allowed); dest_cpu = any_online_cpu(tsk->cpus_allowed); /* Don't tell them about moving exiting tasks @@ -3827,7 +3825,7 @@ void sched_domain_debug(void) int j; char str[NR_CPUS]; struct sched_group *group = sd->groups; - cpumask_t groupmask, tmp; + cpumask_t groupmask; cpumask_scnprintf(str, NR_CPUS, sd->span); cpus_clear(groupmask); @@ -3857,8 +3855,7 @@ void sched_domain_debug(void) if (!cpus_weight(group->cpumask)) printk(" ERROR empty group:"); - cpus_and(tmp, groupmask, group->cpumask); - if (cpus_weight(tmp) > 0) + if (cpus_intersects(groupmask, group->cpumask)) printk(" ERROR repeated CPUs:"); cpus_or(groupmask, groupmask, group->cpumask); @@ -3877,8 +3874,7 @@ void sched_domain_debug(void) sd = sd->parent; if (sd) { - cpus_and(tmp, groupmask, sd->span); - if (!cpus_equal(tmp, groupmask)) + if (!cpus_subset(groupmask, sd->span)) printk(KERN_DEBUG "ERROR parent span is not a superset of domain->span\n"); } -- cgit v1.2.3 From 02d7effd5c525290aad9c0fa491dd9a3f035380e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:33 -0700 Subject: [PATCH] cpumask: comment, spacing tweaks From: Paul Jackson Tweak cpumask.h comments, spacing: - Add comments for cpu_present_map macros: num_present_cpus() and cpu_present() - Remove comments for obsolete macros: cpu_set_online(), cpu_set_offline() - Reorder a few comment lines, to match the code and confuse readers of this patch - Tabify one chunk of code Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cpumask.h | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 4d2cf59e5089..1d06e38480f7 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -47,17 +47,21 @@ * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask * + * for_each_cpu_mask(cpu, mask) for-loop cpu over mask + * * int num_online_cpus() Number of online CPUs * int num_possible_cpus() Number of all possible CPUs + * int num_present_cpus() Number of present CPUs + * * int cpu_online(cpu) Is some cpu online? * int cpu_possible(cpu) Is some cpu possible? - * void cpu_set_online(cpu) set cpu in cpu_online_map - * void cpu_set_offline(cpu) clear cpu in cpu_online_map + * int cpu_present(cpu) Is some cpu present (can schedule)? + * * int any_online_cpu(mask) First online cpu in mask * - * for_each_cpu_mask(cpu, mask) for-loop cpu over mask * for_each_cpu(cpu) for-loop cpu over cpu_possible_map * for_each_online_cpu(cpu) for-loop cpu over cpu_online_map + * for_each_present_cpu(cpu) for-loop cpu over cpu_present_map * * Subtlety: * 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway) @@ -336,19 +340,19 @@ extern cpumask_t cpu_online_map; extern cpumask_t cpu_present_map; #if NR_CPUS > 1 -#define num_online_cpus() cpus_weight(cpu_online_map) -#define num_possible_cpus() cpus_weight(cpu_possible_map) -#define num_present_cpus() cpus_weight(cpu_present_map) -#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) -#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) -#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) +#define num_online_cpus() cpus_weight(cpu_online_map) +#define num_possible_cpus() cpus_weight(cpu_possible_map) +#define num_present_cpus() cpus_weight(cpu_present_map) +#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) +#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) +#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) #else -#define num_online_cpus() 1 -#define num_possible_cpus() 1 -#define num_present_cpus() 1 -#define cpu_online(cpu) ((cpu) == 0) -#define cpu_possible(cpu) ((cpu) == 0) -#define cpu_present(cpu) ((cpu) == 0) +#define num_online_cpus() 1 +#define num_possible_cpus() 1 +#define num_present_cpus() 1 +#define cpu_online(cpu) ((cpu) == 0) +#define cpu_possible(cpu) ((cpu) == 0) +#define cpu_present(cpu) ((cpu) == 0) #endif #define any_online_cpu(mask) \ -- cgit v1.2.3 From a3dcb7f41eced06d4e43365fefd98a3b9b48e340 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:44 -0700 Subject: [PATCH] clean up cpumask_t temporaries From: Rusty Russell Paul Jackson's cpumask tour-de-force allows us to get rid of those stupid temporaries which we used to hold CPU_MASK_ALL to hand them to functions. This used to break NR_CPUS > BITS_PER_LONG. Signed-off-by: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/irq.c | 3 +-- arch/ppc64/kernel/rtasd.c | 3 +-- arch/ppc64/kernel/xics.c | 6 ++---- include/asm-i386/mach-numaq/mach_apic.h | 3 +-- include/asm-i386/mach-summit/mach_apic.h | 3 +-- kernel/kmod.c | 3 +-- kernel/kthread.c | 3 +-- kernel/sched.c | 5 ++--- 8 files changed, 10 insertions(+), 19 deletions(-) diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 7335442e4178..004c3c1a034e 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -738,7 +738,6 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer irq_desc_t *desc = get_irq_desc(irq); int ret; cpumask_t new_value, tmp; - cpumask_t allcpus = CPU_MASK_ALL; if (!desc->handler->set_affinity) return -EIO; @@ -753,7 +752,7 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer * NR_CPUS == 32 and cpumask is a long), so we mask it here to * be consistent. */ - cpus_and(new_value, new_value, allcpus); + cpus_and(new_value, new_value, CPU_MASK_ALL); /* * Grab lock here so cpu_online_map can't change, and also diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c index 243d2ee8de8a..aa649a24a947 100644 --- a/arch/ppc64/kernel/rtasd.c +++ b/arch/ppc64/kernel/rtasd.c @@ -364,7 +364,6 @@ static int rtasd(void *unused) unsigned int err_type; int cpu = 0; int event_scan = rtas_token("event-scan"); - cpumask_t all = CPU_MASK_ALL; int rc; daemonize("rtasd"); @@ -419,7 +418,7 @@ static int rtasd(void *unused) for (;;) { set_cpus_allowed(current, cpumask_of_cpu(cpu)); do_event_scan(event_scan); - set_cpus_allowed(current, all); + set_cpus_allowed(current, CPU_MASK_ALL); /* Drop hotplug lock, and sleep for a bit (at least * one second since some machines have problems if we diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 1d9cf20a2900..32adc8c22953 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -240,14 +240,13 @@ static unsigned int real_irq_to_virt(unsigned int real_irq) static int get_irq_server(unsigned int irq) { cpumask_t cpumask = irq_affinity[irq]; - cpumask_t allcpus = CPU_MASK_ALL; cpumask_t tmp = CPU_MASK_NONE; unsigned int server; #ifdef CONFIG_IRQ_ALL_CPUS /* For the moment only implement delivery to all cpus or one cpu */ if (smp_threads_ready) { - if (cpus_equal(cpumask, allcpus)) { + if (cpus_equal(cpumask, CPU_MASK_ALL)) { server = default_distrib_server; } else { cpus_and(tmp, cpu_online_map, cpumask); @@ -616,7 +615,6 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) long status; unsigned long xics_status[2]; unsigned long newmask; - cpumask_t allcpus = CPU_MASK_ALL; cpumask_t tmp = CPU_MASK_NONE; irq = virt_irq_to_real(irq_offset_down(virq)); @@ -632,7 +630,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) } /* For the moment only implement delivery to all cpus or one cpu */ - if (cpus_equal(cpumask, allcpus)) { + if (cpus_equal(cpumask, CPU_MASK_ALL)) { newmask = default_distrib_server; } else { cpus_and(tmp, cpu_online_map, cpumask); diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index e40c308b15d3..b852593a1c7b 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -8,8 +8,7 @@ static inline cpumask_t target_cpus(void) { - cpumask_t tmp = CPU_MASK_ALL; - return tmp; + return CPU_MASK_ALL; } #define TARGET_CPUS (target_cpus()) diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index 4bf36ddba96d..214263a48f71 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -19,8 +19,7 @@ static inline cpumask_t target_cpus(void) { - cpumask_t tmp = CPU_MASK_ALL; - return tmp; + return CPU_MASK_ALL; } #define TARGET_CPUS (target_cpus()) diff --git a/kernel/kmod.c b/kernel/kmod.c index ea62192b7597..579269c38a3b 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -154,7 +154,6 @@ static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; int retval; - cpumask_t mask = CPU_MASK_ALL; /* Unblock all signals. */ flush_signals(current); @@ -165,7 +164,7 @@ static int ____call_usermodehelper(void *data) spin_unlock_irq(¤t->sighand->siglock); /* We can run anywhere, unlike our parent keventd(). */ - set_cpus_allowed(current, mask); + set_cpus_allowed(current, CPU_MASK_ALL); retval = -EPERM; if (current->fs->root) diff --git a/kernel/kthread.c b/kernel/kthread.c index da0ec5b25cdf..5689ebb1a250 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -65,7 +65,6 @@ static int kthread(void *_create) void *data; sigset_t blocked; int ret = -EINTR; - cpumask_t mask = CPU_MASK_ALL; kthread_exit_files(); @@ -79,7 +78,7 @@ static int kthread(void *_create) flush_signals(current); /* By default we can run anywhere, unlike keventd. */ - set_cpus_allowed(current, mask); + set_cpus_allowed(current, CPU_MASK_ALL); /* OK, tell user we're spawned, wait for stop or wakeup */ __set_current_state(TASK_INTERRUPTIBLE); diff --git a/kernel/sched.c b/kernel/sched.c index 017b59b8de5e..95f18cf8a5b6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3913,16 +3913,15 @@ void __init sched_init(void) /* Set up an initial dummy domain for early boot */ static struct sched_domain sched_domain_init; static struct sched_group sched_group_init; - cpumask_t cpu_mask_all = CPU_MASK_ALL; memset(&sched_domain_init, 0, sizeof(struct sched_domain)); - sched_domain_init.span = cpu_mask_all; + sched_domain_init.span = CPU_MASK_ALL; sched_domain_init.groups = &sched_group_init; sched_domain_init.last_balance = jiffies; sched_domain_init.balance_interval = INT_MAX; /* Don't balance */ memset(&sched_group_init, 0, sizeof(struct sched_group)); - sched_group_init.cpumask = cpu_mask_all; + sched_group_init.cpumask = CPU_MASK_ALL; sched_group_init.next = &sched_group_init; sched_group_init.cpu_power = SCHED_LOAD_SCALE; #endif -- cgit v1.2.3 From 4320cbbd16791e039a04c390aa778a66c18220cd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:52:55 -0700 Subject: [PATCH] alpha: cpumask fixups From: William Lee Irwin III The cpumask patches broke alpha's build, even without the irqaction patch, largely centering around cpu_possible_map. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq.c | 63 ++++++++----------------------------------- arch/alpha/kernel/process.c | 4 +-- arch/alpha/kernel/setup.c | 4 +-- arch/alpha/kernel/smp.c | 39 ++++++++++++--------------- arch/alpha/kernel/sys_dp264.c | 17 ++++++------ include/asm-alpha/smp.h | 4 +-- 6 files changed, 41 insertions(+), 90 deletions(-) diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 9e8eab6dcc0a..0b2f63016044 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -227,7 +227,7 @@ static struct proc_dir_entry * irq_dir[NR_IRQS]; #ifdef CONFIG_SMP static struct proc_dir_entry * smp_affinity_entry[NR_IRQS]; static char irq_user_affinity[NR_IRQS]; -static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; static void select_smp_affinity(int irq) @@ -238,16 +238,14 @@ select_smp_affinity(int irq) if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) return; - while (((cpu_present_mask >> cpu) & 1) == 0) + while (!cpu_possible(cpu)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_affinity[irq] = 1UL << cpu; - irq_desc[irq].handler->set_affinity(irq, 1UL << cpu); + irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); } -#define HEX_DIGITS 16 - static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) @@ -259,67 +257,28 @@ irq_affinity_read_proc (char *page, char **start, off_t off, return len; } -static unsigned int -parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) -{ - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; - unsigned long i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - value = 0; - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - value = (value << 4) | c; - } -out: - *ret = value; - return 0; -} - static int irq_affinity_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value; + cpumask_t new_value; if (!irq_desc[irq].handler->set_affinity) return -EIO; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); /* The special value 0 means release control of the affinity to kernel. */ - if (new_value == 0) { + cpus_and(new_value, new_value, cpu_online_map); + if (cpus_empty(new_value)) { irq_user_affinity[irq] = 0; select_smp_affinity(irq); } /* Do not allow disabling IRQs completely - it's a too easy way to make the system unusable accidentally :-) At least one online CPU still has to be targeted. */ - else if (!(new_value & cpu_present_mask)) - return -EINVAL; else { irq_affinity[irq] = new_value; irq_user_affinity[irq] = 1; @@ -344,10 +303,10 @@ static int prof_cpu_mask_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; - unsigned long new_value; + unsigned long full_count = count, err; + cpumask_t new_value, *mask = (cpumask_t *)data; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index f5c5969b7cae..c82286424aa2 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -119,8 +119,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - clear_bit(boot_cpuid, &cpu_present_mask); - while (cpu_present_mask) + cpu_clear(boot_cpuid, cpu_possible_map); + while (cpus_weight(cpu_possible_map)) barrier(); #endif diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 4e93fe9cc6b6..c637c38d5b0e 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -1245,9 +1245,9 @@ show_cpuinfo(struct seq_file *f, void *slot) platform_string(), nr_processors); #ifdef CONFIG_SMP - seq_printf(f, "cpus active\t\t: %ld\n" + seq_printf(f, "cpus active\t\t: %d\n" "cpu active mask\t\t: %016lx\n", - num_online_cpus(), cpu_present_mask); + num_online_cpus(), cpus_addr(cpu_possible_map)[0]); #endif show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape); diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 9f4aed85950f..5e0dc627838c 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -68,7 +68,7 @@ enum ipi_message_type { static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ -unsigned long cpu_present_mask; +cpumask_t cpu_present_mask; cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -522,7 +522,7 @@ setup_smp(void) smp_num_probed = 1; hwrpb_cpu_present_mask = (1UL << boot_cpuid); } - cpu_present_mask = 1UL << boot_cpuid; + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", smp_num_probed, hwrpb_cpu_present_mask); @@ -547,7 +547,7 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_present_mask = 1UL << boot_cpuid; + cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } @@ -562,7 +562,7 @@ smp_prepare_cpus(unsigned int max_cpus) if (((hwrpb_cpu_present_mask >> i) & 1) == 0) continue; - cpu_present_mask |= 1UL << i; + cpu_set(i, cpu_possible_map); cpu_count++; } @@ -597,7 +597,7 @@ smp_cpus_done(unsigned int max_cpus) if (cpu_online(cpu)) bogosum += cpu_data[cpu].loops_per_jiffy; - printk(KERN_INFO "SMP: Total of %ld processors activated " + printk(KERN_INFO "SMP: Total of %d processors activated " "(%lu.%02lu BogoMIPS).\n", num_online_cpus(), (bogosum + 2500) / (500000/HZ), @@ -638,23 +638,17 @@ setup_profiling_timer(unsigned int multiplier) static void -send_ipi_message(unsigned long to_whom, enum ipi_message_type operation) +send_ipi_message(cpumask_t to_whom, enum ipi_message_type operation) { - unsigned long i, set, n; + int i; mb(); - for (i = to_whom; i ; i &= ~set) { - set = i & -i; - n = __ffs(set); - set_bit(operation, &ipi_data[n].bits); - } + for_each_cpu_mask(i, to_whom) + set_bit(operation, &ipi_data[i].bits); mb(); - for (i = to_whom; i ; i &= ~set) { - set = i & -i; - n = __ffs(set); - wripir(n); - } + for_each_cpu_mask(i, to_whom) + wripir(i); } /* Structure and data for smp_call_function. This is designed to @@ -784,13 +778,14 @@ smp_send_reschedule(int cpu) printk(KERN_WARNING "smp_send_reschedule: Sending IPI to self.\n"); #endif - send_ipi_message(1UL << cpu, IPI_RESCHEDULE); + send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) { - unsigned long to_whom = cpu_present_mask & ~(1UL << smp_processor_id()); + cpumask_t to_whom = cpu_possible_map; + cpu_clear(smp_processor_id(), to_whom); #ifdef DEBUG_IPI_MSG if (hard_smp_processor_id() != boot_cpu_id) printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n"); @@ -814,7 +809,7 @@ smp_send_stop(void) int smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, - int wait, unsigned long to_whom) + int wait, cpumask_t to_whom) { struct smp_call_struct data; unsigned long timeout; @@ -827,8 +822,8 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, data.info = info; data.wait = wait; - to_whom &= ~(1L << smp_processor_id()); - num_cpus_to_call = hweight64(to_whom); + cpu_clear(smp_processor_id(), to_whom); + num_cpus_to_call = cpus_weight(to_whom); atomic_set(&data.unstarted_count, num_cpus_to_call); atomic_set(&data.unfinished_count, num_cpus_to_call); diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 307ce54aca38..119501849e95 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -53,7 +53,6 @@ tsunami_update_irq_hw(unsigned long mask) register int bcpu = boot_cpuid; #ifdef CONFIG_SMP - register unsigned long cpm = cpu_present_mask; volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; @@ -72,10 +71,10 @@ tsunami_update_irq_hw(unsigned long mask) dim1 = &cchip->dim1.csr; dim2 = &cchip->dim2.csr; dim3 = &cchip->dim3.csr; - if ((cpm & 1) == 0) dim0 = &dummy; - if ((cpm & 2) == 0) dim1 = &dummy; - if ((cpm & 4) == 0) dim2 = &dummy; - if ((cpm & 8) == 0) dim3 = &dummy; + if (cpu_possible(0)) dim0 = &dummy; + if (cpu_possible(1)) dim1 = &dummy; + if (cpu_possible(2)) dim2 = &dummy; + if (cpu_possible(3)) dim3 = &dummy; *dim0 = mask0; *dim1 = mask1; @@ -164,13 +163,13 @@ clipper_end_irq(unsigned int irq) } static void -cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) +cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity) { int cpu; for (cpu = 0; cpu < 4; cpu++) { unsigned long aff = cpu_irq_affinity[cpu]; - if (affinity & (1UL << cpu)) + if (cpu_isset(cpu, affinity)) aff |= 1UL << irq; else aff &= ~(1UL << irq); @@ -179,7 +178,7 @@ cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) } static void -dp264_set_affinity(unsigned int irq, unsigned long affinity) +dp264_set_affinity(unsigned int irq, cpumask_t affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq, affinity); @@ -188,7 +187,7 @@ dp264_set_affinity(unsigned int irq, unsigned long affinity) } static void -clipper_set_affinity(unsigned int irq, unsigned long affinity) +clipper_set_affinity(unsigned int irq, cpumask_t affinity) { spin_lock(&dp264_irq_lock); cpu_set_irq_affinity(irq - 16, affinity); diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h index d342a017ceb6..cbc173ae45aa 100644 --- a/include/asm-alpha/smp.h +++ b/include/asm-alpha/smp.h @@ -50,9 +50,7 @@ extern cpumask_t cpu_online_map; extern int smp_num_cpus; #define cpu_possible_map cpu_present_mask -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - -extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu); +int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, cpumask_t cpu); #else /* CONFIG_SMP */ -- cgit v1.2.3 From 8c05319ff168610fd6e3ce043bf5217a9ff7a4f3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:08 -0700 Subject: [PATCH] make irqaction use a cpu mask From: William Lee Irwin III The following patch makes irqaction's ->mask a cpumask as it was intended to be and wraps up the rest of the sweep. Only struct irqaction is usefully greppable, so there may be some assignments to ->mask missing still. This removes more code than it adds. From: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq.c | 2 +- arch/arm/kernel/irq.c | 2 +- arch/arm/mach-clps7500/core.c | 2 +- arch/arm26/kernel/irq.c | 2 +- arch/cris/arch-v10/kernel/time.c | 2 +- arch/cris/kernel/irq.c | 2 +- arch/i386/kernel/i8259.c | 2 +- arch/i386/kernel/irq.c | 2 +- arch/i386/mach-default/setup.c | 4 +- arch/i386/mach-voyager/setup.c | 4 +- arch/ia64/kernel/irq.c | 2 +- arch/mips/baget/irq.c | 4 +- arch/mips/baget/time.c | 2 +- arch/mips/ddb5xxx/ddb5074/irq.c | 2 +- arch/mips/ddb5xxx/ddb5476/irq.c | 4 +- arch/mips/ddb5xxx/ddb5477/irq.c | 2 +- arch/mips/gt64120/common/time.c | 2 +- arch/mips/jmr3927/rbhma3100/irq.c | 8 +-- arch/mips/kernel/irq.c | 2 +- arch/mips/momentum/jaguar_atx/irq.c | 2 +- arch/mips/momentum/ocelot_c/irq.c | 4 +- arch/mips/sgi-ip32/ip32-irq.c | 4 +- arch/mips/sibyte/sb1250/irq.c | 2 +- arch/mips/tx4927/common/tx4927_irq.c | 2 +- .../tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 4 +- arch/mips/vr4181/common/irq.c | 4 +- arch/mips/vr41xx/common/giu.c | 2 +- arch/mips/vr41xx/common/icu.c | 2 +- arch/parisc/kernel/irq.c | 2 +- arch/ppc/kernel/irq.c | 2 +- arch/ppc64/kernel/irq.c | 2 +- arch/sh/cchips/hd6446x/hd64461/setup.c | 2 +- arch/sh/cchips/hd6446x/hd64465/setup.c | 2 +- arch/sh/kernel/irq.c | 2 +- arch/sh/kernel/time.c | 2 +- arch/sparc/kernel/irq.c | 4 +- arch/sparc/kernel/sun4d_irq.c | 2 +- arch/sparc64/kernel/irq.c | 68 ++++------------------ arch/sparc64/kernel/smp.c | 3 - arch/um/kernel/irq.c | 2 +- arch/v850/kernel/fpga85e2c.c | 2 +- arch/v850/kernel/irq.c | 2 +- arch/v850/kernel/time.c | 2 +- arch/x86_64/kernel/i8259.c | 2 +- arch/x86_64/kernel/irq.c | 2 +- arch/x86_64/kernel/time.c | 2 +- include/linux/interrupt.h | 3 +- 47 files changed, 68 insertions(+), 118 deletions(-) diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 0b2f63016044..b52a52b7b918 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -416,7 +416,7 @@ request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 5777a8c2faec..68636bd7c2be 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -674,7 +674,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ action->handler = handler; action->flags = irq_flags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index ee1a3192ad7b..11fa530af3ba 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -188,7 +188,7 @@ static struct irqchip clps7500_no_chip = { .unmask = cl7500_no_action, }; -static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL }; +static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; static void __init clps7500_init_irq(void) { diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c index d627cedab805..7869d1b22621 100644 --- a/arch/arm26/kernel/irq.c +++ b/arch/arm26/kernel/irq.c @@ -549,7 +549,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ action->handler = handler; action->flags = irq_flags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index c4d78d52f774..298e86a01c01 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -253,7 +253,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ static struct irqaction irq2 = { timer_interrupt, SA_SHIRQ | SA_INTERRUPT, - 0, "timer", NULL, NULL}; + CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init(void) diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index a963dda74413..94d70279058e 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -240,7 +240,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 92061fd4cc0b..fc991989284b 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -332,7 +332,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) * New motherboards sometimes make IRQ 13 be a PCI interrupt, * so allow interrupt sharing. */ -static struct irqaction fpu_irq = { math_error_irq, 0, 0, "fpu", NULL, NULL }; +static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL }; void __init init_ISA_irqs (void) { diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index cd2ed69f8367..ba2055a3959b 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -652,7 +652,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index 718f718d0d78..0aa08eaa8932 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c @@ -27,7 +27,7 @@ void __init pre_intr_init_hook(void) /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; /** * intr_init_hook - post gate setup interrupt initialisation @@ -71,7 +71,7 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; /** * time_init_hook - do any specific initialisations for the system timer. diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c index 9bbf8953f833..df123fc487bb 100644 --- a/arch/i386/mach-voyager/setup.c +++ b/arch/i386/mach-voyager/setup.c @@ -17,7 +17,7 @@ void __init pre_intr_init_hook(void) /* * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init intr_init_hook(void) { @@ -40,7 +40,7 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init_hook(void) { diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 3087c13d08d7..8355dda0188c 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -607,7 +607,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c index fe158acf8921..d2067c037c35 100644 --- a/arch/mips/baget/irq.c +++ b/arch/mips/baget/irq.c @@ -325,7 +325,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; @@ -389,7 +389,7 @@ static void write_err_interrupt(int irq, void *dev_id, struct pt_regs * regs) } static struct irqaction irq0 = -{ write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL}; +{ write_err_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "bus write error", NULL, NULL}; void __init init_IRQ(void) { diff --git a/arch/mips/baget/time.c b/arch/mips/baget/time.c index 205bde31215e..ed82c62df3d6 100644 --- a/arch/mips/baget/time.c +++ b/arch/mips/baget/time.c @@ -67,7 +67,7 @@ static void __init timer_enable(void) } static struct irqaction timer_irq = -{ timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +{ timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init(void) { diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c index dc4e643496b2..547386de484a 100644 --- a/arch/mips/ddb5xxx/ddb5074/irq.c +++ b/arch/mips/ddb5xxx/ddb5074/irq.c @@ -24,7 +24,7 @@ extern asmlinkage void ddbIRQ(void); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ #define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c index 58e794f01ed5..6a1202aec98f 100644 --- a/arch/mips/ddb5xxx/ddb5476/irq.c +++ b/arch/mips/ddb5xxx/ddb5476/irq.c @@ -107,8 +107,8 @@ static void nile4_irq_setup(void) /* memory resource acquire in ddb_setup */ } -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; -static struct irqaction irq_error = { no_action, 0, 0, "error", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; +static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; extern asmlinkage void ddb5476_handle_int(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c index 0ae83365fe75..dfc2559aaace 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/arch/mips/ddb5xxx/ddb5477/irq.c @@ -77,7 +77,7 @@ extern void vrc5477_irq_init(u32 base); extern void mips_cpu_irq_init(u32 base); extern asmlinkage void ddb5477_handle_int(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; void ddb5477_irq_setup(void) diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c index 86a2100db00d..44f33caf298e 100644 --- a/arch/mips/gt64120/common/time.c +++ b/arch/mips/gt64120/common/time.c @@ -80,7 +80,7 @@ void gt64120_time_init(void) timer.name = "timer"; timer.dev_id = NULL; timer.next = NULL; - timer.mask = 0; + timer.mask = CPU_MASK_NONE; irq_desc[GT_TIMER].action = &timer; enable_irq(GT_TIMER); diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 442dc6df4b6b..4ab85b5b2b4d 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -301,7 +301,7 @@ static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static struct irqaction ioc_action = { - jmr3927_ioc_interrupt, 0, 0, "IOC", NULL, NULL, + jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL, }; static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -318,7 +318,7 @@ static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static struct irqaction isac_action = { - jmr3927_isac_interrupt, 0, 0, "ISAC", NULL, NULL, + jmr3927_isac_interrupt, 0, CPU_MASK_NONE, "ISAC", NULL, NULL, }; @@ -327,7 +327,7 @@ static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * re printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); } static struct irqaction isaerr_action = { - jmr3927_isaerr_interrupt, 0, 0, "ISA error", NULL, NULL, + jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL, }; static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) @@ -337,7 +337,7 @@ static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * re tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); } static struct irqaction pcierr_action = { - jmr3927_pcierr_interrupt, 0, 0, "PCI error", NULL, NULL, + jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL, }; int jmr3927_ether1_irq = 0; diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 845e0914ffe5..13acf876b46f 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -487,7 +487,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c index f13f856067e7..cc25cbcb4bb2 100644 --- a/arch/mips/momentum/jaguar_atx/irq.c +++ b/arch/mips/momentum/jaguar_atx/irq.c @@ -42,7 +42,7 @@ extern asmlinkage void jaguar_handle_int(void); static struct irqaction cascade_mv64340 = { - no_action, SA_INTERRUPT, 0, "MV64340-Cascade", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL }; void __init init_IRQ(void) diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index d12f5befdf6f..37ad81291d82 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c @@ -53,11 +53,11 @@ extern void uart_irq_init(void); extern void cpci_irq_init(void); static struct irqaction cascade_fpga = { - no_action, SA_INTERRUPT, 0, "cascade via FPGA", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL }; static struct irqaction cascade_mv64340 = { - no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL + no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL }; void __init init_IRQ(void) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 5091454ca197..75846d6e8154 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -123,9 +123,9 @@ extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id, struct pt_regs *regs); struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, - 0, "CRIME memory error", NULL, NULL }; + CPU_MASK_NONE, "CRIME memory error", NULL, NULL }; struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, - 0, "CRIME CPU error", NULL, NULL }; + CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; extern void ip32_handle_int(void); diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index e2216ee9ba49..ddbe64b2d371 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -279,7 +279,7 @@ static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id, static struct irqaction sb1250_dummy_action = { .handler = sb1250_dummy_handler, .flags = 0, - .mask = 0, + .mask = CPU_MASK_NONE, .name = "sb1250-private", .next = NULL, .dev_id = 0 diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 14591d16e41a..bf59409eea36 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -172,7 +172,7 @@ static struct hw_interrupt_type tx4927_irq_pic_type = { .set_affinity = NULL }; -#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction tx4927_irq_pic_action = TX4927_PIC_ACTION(TX4927_PIC_NAME); diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index f4fe81eb7a28..930304585443 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -337,8 +337,8 @@ int toshiba_rbtx4927_irq_nested(int sw_irq) return (sw_irq); } -//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } -#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, 0, s, NULL, NULL } +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction toshiba_rbtx4927_irq_ioc_action = TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); #ifdef CONFIG_TOSHIBA_FPCIB0 diff --git a/arch/mips/vr4181/common/irq.c b/arch/mips/vr4181/common/irq.c index 7b5a1a4f313c..4a2458f8bc8b 100644 --- a/arch/mips/vr4181/common/irq.c +++ b/arch/mips/vr4181/common/irq.c @@ -180,9 +180,9 @@ extern int setup_irq(unsigned int irq, struct irqaction *irqaction); extern void mips_cpu_irq_init(u32 irq_base); static struct irqaction cascade = - { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; + { no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL }; static struct irqaction reserved = - { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; + { no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL }; void __init init_IRQ(void) { diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c index 6fe6a73ff99b..6ee189968e8b 100644 --- a/arch/mips/vr41xx/common/giu.c +++ b/arch/mips/vr41xx/common/giu.c @@ -209,7 +209,7 @@ struct vr41xx_giuint_cascade { }; static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS]; -static struct irqaction giu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction giu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; static int no_irq_number(int irq) { diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index bd67058e4743..1f223d70e4e6 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -288,7 +288,7 @@ static struct hw_interrupt_type giuint_irq_type = { /*=======================================================================*/ -static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction icu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; static void __init vr41xx_icu_init(void) { diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 72f748905f18..ca1acad13e09 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -644,7 +644,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index f3c0d2cc2205..6da092941c73 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -241,7 +241,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = dev_id; action->next = NULL; diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 004c3c1a034e..6971f8a0cba0 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -206,7 +206,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = dev_id; action->next = NULL; diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c index 5e03ea93838e..f014b9bf6922 100644 --- a/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -134,7 +134,7 @@ int hd64461_irq_demux(int irq) return __irq_demux(irq); } -static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL }; +static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64461", NULL, NULL }; int __init setup_hd64461(void) { diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c index 73a44a7701bb..68e4c4e4283d 100644 --- a/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -154,7 +154,7 @@ int hd64465_irq_demux(int irq) return irq; } -static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, 0, "HD64465", NULL, NULL}; +static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64465", NULL, NULL}; static int __init setup_hd64465(void) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index a37e2d1cffce..18f056b15b74 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -436,7 +436,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index cd91a59a9fff..37d66714edba 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -391,7 +391,7 @@ static int __init sh_pclk_setup(char *str) } __setup("sh_pclk=", sh_pclk_setup); -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc) { diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index 6b1698b5ad6f..237764bb69fd 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -449,7 +449,7 @@ int request_fast_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->dev_id = NULL; action->next = NULL; @@ -529,7 +529,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 5e9a705c1093..93e385611b95 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -336,7 +336,7 @@ int sun4d_request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 35243558bfc0..10c0c4ed6e89 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -118,10 +118,6 @@ static void register_irq_proc (unsigned int irq); action->flags |= __irq_ino(irq) << 48; #define get_ino_in_irqaction(action) (action->flags >> 48) -#if NR_CPUS > 64 -#error irqaction embedded smp affinity does not work with > 64 cpus, FIXME -#endif - #define put_smpaff_in_irqaction(action, smpaff) (action)->mask = (smpaff) #define get_smpaff_in_irqaction(action) ((action)->mask) @@ -458,7 +454,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ action->next = NULL; action->dev_id = dev_id; put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, 0); + put_smpaff_in_irqaction(action, CPU_MASK_NONE); if (tmp) tmp->next = action; @@ -694,7 +690,7 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp) cpumask_t cpu_mask; unsigned int buddy, ticks; - cpus_addr(cpu_mask)[0] = get_smpaff_in_irqaction(ap); + cpu_mask = get_smpaff_in_irqaction(ap); cpus_and(cpu_mask, cpu_mask, cpu_online_map); if (cpus_empty(cpu_mask)) cpu_mask = cpu_online_map; @@ -715,7 +711,7 @@ static inline void redirect_intr(int cpu, struct ino_bucket *bp) if (++buddy >= NR_CPUS) buddy = 0; if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, 0); + put_smpaff_in_irqaction(ap, CPU_MASK_NONE); goto out; } } @@ -949,7 +945,7 @@ int request_fast_irq(unsigned int irq, action->name = name; action->next = NULL; put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, 0); + put_smpaff_in_irqaction(action, CPU_MASK_NONE); *(bucket->pil + irq_action) = action; enable_irq(irq); @@ -1167,45 +1163,6 @@ static struct proc_dir_entry * irq_dir [NUM_IVECS]; #ifdef CONFIG_SMP -#define HEX_DIGITS 16 - -static unsigned int parse_hex_value (const char __user *buffer, - unsigned long count, unsigned long *ret) -{ - unsigned char hexnum [HEX_DIGITS]; - unsigned long value; - int i; - - if (!count) - return -EINVAL; - if (count > HEX_DIGITS) - count = HEX_DIGITS; - if (copy_from_user(hexnum, buffer, count)) - return -EFAULT; - - /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. - */ - value = 0; - - for (i = 0; i < count; i++) { - unsigned int c = hexnum[i]; - - switch (c) { - case '0' ... '9': c -= '0'; break; - case 'a' ... 'f': c -= 'a'-10; break; - case 'A' ... 'F': c -= 'A'-10; break; - default: - goto out; - } - value = (value << 4) | c; - } -out: - *ret = value; - return 0; -} - static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1214,7 +1171,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, cpumask_t mask; int len; - cpus_addr(mask)[0] = get_smpaff_in_irqaction(ap); + mask = get_smpaff_in_irqaction(ap); if (cpus_empty(mask)) mask = cpu_online_map; @@ -1225,7 +1182,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, return len; } -static inline void set_intr_affinity(int irq, unsigned long hw_aff) +static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; @@ -1243,22 +1200,17 @@ static int irq_affinity_write_proc (struct file *file, const char __user *buffer unsigned long count, void *data) { int irq = (long) data, full_count = count, err; - unsigned long new_value, i; + cpumask_t new_value; - err = parse_hex_value(buffer, count, &new_value); + err = cpumask_parse(buffer, count, new_value); /* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least * one online CPU still has to be targeted. */ - for (i = 0; i < NR_CPUS; i++) { - if ((new_value & (1UL << i)) != 0 && - !cpu_online(i)) - new_value &= ~(1UL << i); - } - - if (!new_value) + cpus_and(new_value, new_value, cpu_online_map); + if (cpus_empty(new_value)) return -EINVAL; set_intr_affinity(irq, new_value); diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 58c3792b4af1..c0f729f9167f 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -414,9 +414,6 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c * packet, but we have no use for that. However we do take advantage of * the new pipelining feature (ie. dispatch to multiple cpus simultaneously). */ -#if NR_CPUS > 32 -#error Fixup cheetah_xcall_deliver Dave... -#endif static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { u64 pstate, ver; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 5f6c8502a248..0e968bb11a45 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -419,7 +419,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c index 72dda796fac6..17e3dbafc371 100644 --- a/arch/v850/kernel/fpga85e2c.c +++ b/arch/v850/kernel/fpga85e2c.c @@ -168,5 +168,5 @@ static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs) static int reg_snap_dev_id; static struct irqaction reg_snap_action = { - make_reg_snap, 0, 0, "reg_snap", ®_snap_dev_id, 0 + make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", ®_snap_dev_id, 0 }; diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c index a5d918e71be9..d97864021730 100644 --- a/arch/v850/kernel/irq.c +++ b/arch/v850/kernel/irq.c @@ -392,7 +392,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c index fee3e957da5c..74067adea388 100644 --- a/arch/v850/kernel/time.c +++ b/arch/v850/kernel/time.c @@ -203,7 +203,7 @@ static int timer_dev_id; static struct irqaction timer_irqaction = { timer_interrupt, SA_INTERRUPT, - 0, + CPU_MASK_NONE, "timer", &timer_dev_id, NULL diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 304b6a37f58b..8b1e2dffec67 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -365,7 +365,7 @@ void __init init_8259A(int auto_eoi) * IRQ2 is cascade interrupt to second interrupt controller */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; void __init init_ISA_irqs (void) { diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index bfdb95e8bf95..fcaaa8c17262 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -488,7 +488,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; - action->mask = 0; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index d47d3f8de44e..10c511f50d1d 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -689,7 +689,7 @@ int __init time_setup(char *str) } static struct irqaction irq0 = { - timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL + timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL }; extern void __init config_acpi_tables(void); diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 220f2a8602b4..565321b05213 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,7 @@ typedef int irqreturn_t; struct irqaction { irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; - unsigned long mask; + cpumask_t mask; const char *name; void *dev_id; struct irqaction *next; -- cgit v1.2.3 From 0342e1625c4fdcae2df9817d73225478eeb384a6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:18 -0700 Subject: [PATCH] Fix and Reenable MSI Support on x86_64 From: long MSI support for x86_64 is currently disabled in the kernel 2.6.x. Below is the patch, which provides a fix and reenable it. In addition, the patch provides a info message during kernel boot if configuring vector-base indexing. Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 7 ++++++- arch/x86_64/kernel/i8259.c | 24 ++++++++++++++++++++++++ arch/x86_64/kernel/io_apic.c | 26 ++++++++++++++++++-------- drivers/pci/Kconfig | 2 +- include/asm-x86_64/hw_irq.h | 1 + include/asm-x86_64/msi.h | 7 +------ 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 28b4d7c4e3c6..8a3af5697f64 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1411,12 +1411,17 @@ void __init print_IO_APIC(void) ); } } + if (use_pci_vector()) + printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - printk(KERN_DEBUG "IRQ%d ", i); + if (use_pci_vector() && !platform_legacy_irq(i)) + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); + else + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 8b1e2dffec67..94e77bd96ff8 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -47,6 +47,12 @@ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ BI(x,c) BI(x,d) BI(x,e) BI(x,f) +#define BUILD_14_IRQS(x) \ + BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ + BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ + BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ + BI(x,c) BI(x,d) + /* * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: * (these are usually mapped to vectors 0x20-0x2f) @@ -68,9 +74,15 @@ BUILD_16_IRQS(0x0) BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) + +#ifdef CONFIG_PCI_USE_VECTOR + BUILD_14_IRQS(0xe) +#endif + #endif #undef BUILD_16_IRQS +#undef BUILD_14_IRQS #undef BI @@ -83,6 +95,12 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) +#define IRQLIST_14(x) \ + IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ + IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ + IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ + IRQ(x,c), IRQ(x,d) + void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), @@ -91,11 +109,17 @@ void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), IRQLIST_16(0xc), IRQLIST_16(0xd) + +#ifdef CONFIG_PCI_USE_VECTOR + , IRQLIST_14(0xe) +#endif + #endif }; #undef IRQ #undef IRQLIST_16 +#undef IRQLIST_14 /* * This is the 'legacy' 8259A Programmable Interrupt Controller, diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 3c3a310be3e1..3869af670b28 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -67,8 +67,8 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; #ifdef CONFIG_PCI_USE_VECTOR -int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; #define vector_to_irq(vector) \ (platform_legacy_irq(vector) ? vector : vector_irq[vector]) #else @@ -656,10 +656,14 @@ static inline int IO_APIC_irq_trigger(int irq) /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -#ifndef CONFIG_PCI_USE_VECTOR +#ifdef CONFIG_PCI_USE_VECTOR +int assign_irq_vector(int irq) +#else int __init assign_irq_vector(int irq) +#endif { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; + BUG_ON(irq >= NR_IRQ_VECTORS); if (IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); @@ -668,18 +672,19 @@ next: if (current_vector == IA32_SYSCALL_VECTOR) goto next; - if (current_vector > FIRST_SYSTEM_VECTOR) { + if (current_vector >= FIRST_SYSTEM_VECTOR) { offset++; + if (!(offset%8)) + return -ENOSPC; current_vector = FIRST_DEVICE_VECTOR + offset; } - if (current_vector == FIRST_SYSTEM_VECTOR) - panic("ran out of interrupt sources!"); + vector_irq[current_vector] = irq; + if (irq != AUTO_ASSIGN) + IO_APIC_VECTOR(irq) = current_vector; - IO_APIC_VECTOR(irq) = current_vector; return current_vector; } -#endif extern void (*interrupt[NR_IRQS])(void); static struct hw_interrupt_type ioapic_level_type; @@ -925,12 +930,17 @@ void __init print_IO_APIC(void) ); } } + if (use_pci_vector()) + printk(KERN_INFO "Using vector-based indexing\n"); printk(KERN_DEBUG "IRQ to pin mappings:\n"); for (i = 0; i < NR_IRQS; i++) { struct irq_pin_list *entry = irq_2_pin + i; if (entry->pin < 0) continue; - printk(KERN_DEBUG "IRQ%d ", i); + if (use_pci_vector() && !platform_legacy_irq(i)) + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); + else + printk(KERN_DEBUG "IRQ%d ", i); for (;;) { printk("-> %d:%d", entry->apic, entry->pin); if (!entry->next) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b8f764fd210f..03681b915a56 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -3,7 +3,7 @@ # config PCI_USE_VECTOR bool "Vector-based interrupt indexing (MSI)" - depends on (X86_LOCAL_APIC && X86_IO_APIC && !X86_64) || IA64 + depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 default n help This replaces the current existing IRQ-based index interrupt scheme diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index 161edad6afdf..2df689dd6d77 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h @@ -78,6 +78,7 @@ struct hw_interrupt_type; #ifndef __ASSEMBLY__ extern u8 irq_vector[NR_IRQ_VECTORS]; #define IO_APIC_VECTOR(irq) (irq_vector[irq]) +#define AUTO_ASSIGN -1 /* * Various low-level irq details needed by irq.c, process.c, diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h index 727b911f29ca..e0e1e9b3bd87 100644 --- a/include/asm-x86_64/msi.h +++ b/include/asm-x86_64/msi.h @@ -11,11 +11,6 @@ #define LAST_DEVICE_VECTOR 232 #define MSI_DEST_MODE MSI_LOGICAL_MODE #define MSI_TARGET_CPU_SHIFT 12 - -#ifdef CONFIG_SMP -#define MSI_TARGET_CPU logical_smp_processor_id() -#else -#define MSI_TARGET_CPU TARGET_CPUS -#endif +#define MSI_TARGET_CPU TARGET_CPUS #endif /* ASM_MSI_H */ -- cgit v1.2.3 From acba6041ff3f5dd7b4c88e012530db7474e3cdb8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:29 -0700 Subject: [PATCH] vmscan.c: shuffle things around Move all the data structure declarations, macros and variable definitions to less surprising places. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 92 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index bd852ece0d5b..5d856f4244bf 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -38,11 +38,49 @@ #include +/* possible outcome of pageout() */ +typedef enum { + /* failed to write page out, page is locked */ + PAGE_KEEP, + /* move page to the active list, page is locked */ + PAGE_ACTIVATE, + /* page has been sent to the disk successfully, page is unlocked */ + PAGE_SUCCESS, + /* page is clean and locked */ + PAGE_CLEAN, +} pageout_t; + +struct scan_control { + /* Ask refill_inactive_zone, or shrink_cache to scan this many pages */ + unsigned long nr_to_scan; + + /* Incremented by the number of inactive pages that were scanned */ + unsigned long nr_scanned; + + /* Incremented by the number of pages reclaimed */ + unsigned long nr_reclaimed; + + unsigned long nr_mapped; /* From page_state */ + + /* Ask shrink_caches, or shrink_zone to scan at this priority */ + unsigned int priority; + + /* This context's GFP mask */ + unsigned int gfp_mask; + + int may_writepage; +}; + /* - * From 0 .. 100. Higher means more swappy. + * The list of shrinker callbacks used by to apply pressure to + * ageable caches. */ -int vm_swappiness = 60; -static long total_memory; +struct shrinker { + shrinker_t shrinker; + struct list_head list; + int seeks; /* seeks to recreate an obj */ + long nr; /* objs pending delete */ +}; #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) @@ -66,7 +104,7 @@ static long total_memory; if ((_page)->lru.prev != _base) { \ struct page *prev; \ \ - prev = lru_to_page(&(_page->lru)); \ + prev = lru_to_page(&(_page->lru)); \ prefetchw(&prev->_field); \ } \ } while (0) @@ -75,15 +113,10 @@ static long total_memory; #endif /* - * The list of shrinker callbacks used by to apply pressure to - * ageable caches. + * From 0 .. 100. Higher means more swappy. */ -struct shrinker { - shrinker_t shrinker; - struct list_head list; - int seeks; /* seeks to recreate an obj */ - long nr; /* objs pending delete */ -}; +int vm_swappiness = 60; +static long total_memory; static LIST_HEAD(shrinker_list); static DECLARE_MUTEX(shrinker_sem); @@ -106,7 +139,6 @@ struct shrinker *set_shrinker(int seeks, shrinker_t theshrinker) } return shrinker; } - EXPORT_SYMBOL(set_shrinker); /* @@ -119,7 +151,6 @@ void remove_shrinker(struct shrinker *shrinker) up(&shrinker_sem); kfree(shrinker); } - EXPORT_SYMBOL(remove_shrinker); #define SHRINK_BATCH 128 @@ -239,18 +270,6 @@ static void handle_write_error(struct address_space *mapping, unlock_page(page); } -/* possible outcome of pageout() */ -typedef enum { - /* failed to write page out, page is locked */ - PAGE_KEEP, - /* move page to the active list, page is locked */ - PAGE_ACTIVATE, - /* page has been sent to the disk successfully, page is unlocked */ - PAGE_SUCCESS, - /* page is clean and locked */ - PAGE_CLEAN, -} pageout_t; - /* * pageout is called by shrink_list() for each dirty page. Calls ->writepage(). */ @@ -310,27 +329,6 @@ static pageout_t pageout(struct page *page, struct address_space *mapping) return PAGE_CLEAN; } -struct scan_control { - /* Ask refill_inactive_zone, or shrink_cache to scan this many pages */ - unsigned long nr_to_scan; - - /* Incremented by the number of inactive pages that were scanned */ - unsigned long nr_scanned; - - /* Incremented by the number of pages reclaimed */ - unsigned long nr_reclaimed; - - unsigned long nr_mapped; /* From page_state */ - - /* Ask shrink_caches, or shrink_zone to scan at this priority */ - unsigned int priority; - - /* This context's GFP mask */ - unsigned int gfp_mask; - - int may_writepage; -}; - /* * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed */ -- cgit v1.2.3 From 2332dc7870b6f40eff03df88cbb03f4ffddbd086 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:40 -0700 Subject: [PATCH] vmscan.c scan rate fixes We've been futzing with the scan rates of the inactive and active lists far too much, and it's still not right (Anton reports interrupt-off times of over a second). - We have this logic in there from 2.4.early (at least) which tries to keep the inactive list 1/3rd the size of the active list. Or something. I really cannot see any logic behind this, so toss it out and change the arithmetic in there so that all pages on both lists have equal scan rates. - Chunk the work up so we never hold interrupts off for more that 32 pages worth of scanning. - Make the per-zone scan-count accumulators unsigned long rather than atomic_t. Mainly because atomic_t's could conceivably overflow, but also because access to these counters is racy-by-design anyway. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 4 +-- mm/page_alloc.c | 4 +-- mm/vmscan.c | 70 ++++++++++++++++++++++---------------------------- 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 373a13ba6f3f..2f41b635580b 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -118,8 +118,8 @@ struct zone { spinlock_t lru_lock; struct list_head active_list; struct list_head inactive_list; - atomic_t nr_scan_active; - atomic_t nr_scan_inactive; + unsigned long nr_scan_active; + unsigned long nr_scan_inactive; unsigned long nr_active; unsigned long nr_inactive; int all_unreclaimable; /* All pages pinned */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 16d5c2af94ee..b30e78c2a939 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1482,8 +1482,8 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone_names[j], realsize, batch); INIT_LIST_HEAD(&zone->active_list); INIT_LIST_HEAD(&zone->inactive_list); - atomic_set(&zone->nr_scan_active, 0); - atomic_set(&zone->nr_scan_inactive, 0); + zone->nr_scan_active = 0; + zone->nr_scan_inactive = 0; zone->nr_active = 0; zone->nr_inactive = 0; if (!size) diff --git a/mm/vmscan.c b/mm/vmscan.c index 5d856f4244bf..3fe27c1d2381 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -789,54 +789,46 @@ refill_inactive_zone(struct zone *zone, struct scan_control *sc) } /* - * Scan `nr_pages' from this zone. Returns the number of reclaimed pages. * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. */ static void shrink_zone(struct zone *zone, struct scan_control *sc) { - unsigned long scan_active, scan_inactive; - int count; - - scan_inactive = (zone->nr_active + zone->nr_inactive) >> sc->priority; + unsigned long nr_active; + unsigned long nr_inactive; /* - * Try to keep the active list 2/3 of the size of the cache. And - * make sure that refill_inactive is given a decent number of pages. - * - * The "scan_active + 1" here is important. With pagecache-intensive - * workloads the inactive list is huge, and `ratio' evaluates to zero - * all the time. Which pins the active list memory. So we add one to - * `scan_active' just to make sure that the kernel will slowly sift - * through the active list. + * Add one to `nr_to_scan' just to make sure that the kernel will + * slowly sift through the active list. */ - if (zone->nr_active >= 4*(zone->nr_inactive*2 + 1)) { - /* Don't scan more than 4 times the inactive list scan size */ - scan_active = 4*scan_inactive; - } else { - unsigned long long tmp; - - /* Cast to long long so the multiply doesn't overflow */ - - tmp = (unsigned long long)scan_inactive * zone->nr_active; - do_div(tmp, zone->nr_inactive*2 + 1); - scan_active = (unsigned long)tmp; - } - - atomic_add(scan_active + 1, &zone->nr_scan_active); - count = atomic_read(&zone->nr_scan_active); - if (count >= SWAP_CLUSTER_MAX) { - atomic_set(&zone->nr_scan_active, 0); - sc->nr_to_scan = count; - refill_inactive_zone(zone, sc); - } + zone->nr_scan_active += (zone->nr_active >> sc->priority) + 1; + nr_active = zone->nr_scan_active; + if (nr_active >= SWAP_CLUSTER_MAX) + zone->nr_scan_active = 0; + else + nr_active = 0; + + zone->nr_scan_inactive += (zone->nr_inactive >> sc->priority) + 1; + nr_inactive = zone->nr_scan_inactive; + if (nr_inactive >= SWAP_CLUSTER_MAX) + zone->nr_scan_inactive = 0; + else + nr_inactive = 0; + + while (nr_active || nr_inactive) { + if (nr_active) { + sc->nr_to_scan = min(nr_active, + (unsigned long)SWAP_CLUSTER_MAX); + nr_active -= sc->nr_to_scan; + refill_inactive_zone(zone, sc); + } - atomic_add(scan_inactive, &zone->nr_scan_inactive); - count = atomic_read(&zone->nr_scan_inactive); - if (count >= SWAP_CLUSTER_MAX) { - atomic_set(&zone->nr_scan_inactive, 0); - sc->nr_to_scan = count; - shrink_cache(zone, sc); + if (nr_inactive) { + sc->nr_to_scan = min(nr_inactive, + (unsigned long)SWAP_CLUSTER_MAX); + nr_inactive -= sc->nr_to_scan; + shrink_cache(zone, sc); + } } } -- cgit v1.2.3 From 42b8d9947462d751f1a4cd6c7e842d95c3249f35 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:53:52 -0700 Subject: [PATCH] vmscan.c: dont reclaim too many pages The shrink_zone() logic can, under some circumstances, cause far too many pages to be reclaimed. Say, we're scanning at high priority and suddenly hit a large number of reclaimable pages on the LRU. Change things so we bale out when SWAP_CLUSTER_MAX pages have been reclaimed. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index 3fe27c1d2381..a744497f0d49 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -62,6 +62,9 @@ struct scan_control { unsigned long nr_mapped; /* From page_state */ + /* How many pages shrink_cache() should reclaim */ + int nr_to_reclaim; + /* Ask shrink_caches, or shrink_zone to scan at this priority */ unsigned int priority; @@ -586,6 +589,7 @@ static void shrink_cache(struct zone *zone, struct scan_control *sc) if (current_is_kswapd()) mod_page_state(kswapd_steal, nr_freed); mod_page_state_zone(zone, pgsteal, nr_freed); + sc->nr_to_reclaim -= nr_freed; spin_lock_irq(&zone->lru_lock); /* @@ -815,6 +819,8 @@ shrink_zone(struct zone *zone, struct scan_control *sc) else nr_inactive = 0; + sc->nr_to_reclaim = SWAP_CLUSTER_MAX; + while (nr_active || nr_inactive) { if (nr_active) { sc->nr_to_scan = min(nr_active, @@ -828,6 +834,8 @@ shrink_zone(struct zone *zone, struct scan_control *sc) (unsigned long)SWAP_CLUSTER_MAX); nr_inactive -= sc->nr_to_scan; shrink_cache(zone, sc); + if (sc->nr_to_reclaim <= 0) + break; } } } -- cgit v1.2.3 From a44115192f55f8b7a22d511cc194d7880a2ba553 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:04 -0700 Subject: [PATCH] vm: vfs shrinkage tuning Some people want the dentry and inode caches shrink harder, others want them shrunk more reluctantly. The patch adds /proc/sys/vm/vfs_cache_pressure, which tunes the vfs cache versus pagecache scanning pressure. - at vfs_cache_pressure=0 we don't shrink dcache and icache at all. - at vfs_cache_pressure=100 there is no change in behaviour. - at vfs_cache_pressure > 100 we reclaim dentries and inodes harder. The number of megabytes of slab left after a slocate.cron on my 256MB test box: vfs_cache_pressure=100000 33480 vfs_cache_pressure=10000 61996 vfs_cache_pressure=1000 104056 vfs_cache_pressure=200 166340 vfs_cache_pressure=100 190200 vfs_cache_pressure=50 206168 Of course, this just left more directory and inode pagecache behind instead of vfs cache. Interestingly, on this machine the entire slocate run fits into pagecache, but not into VFS caches. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 12 ++++++++++++ Documentation/sysctl/vm.txt | 2 +- fs/dcache.c | 5 +++-- fs/inode.c | 2 +- include/linux/dcache.h | 2 ++ include/linux/sysctl.h | 1 + kernel/sysctl.c | 12 ++++++++++++ 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 995da97a2633..b84b7a7cc723 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -1115,6 +1115,18 @@ program to load modules on demand. The files in this directory can be used to tune the operation of the virtual memory (VM) subsystem of the Linux kernel. +vfs_cache_pressure +------------------ + +Controls the tendency of the kernel to reclaim the memory which is used for +caching of directory and inode objects. + +At the default value of vfs_cache_pressure=100 the kernel will attempt to +reclaim dentries and inodes at a "fair" rate with respect to pagecache and +swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer +to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 +causes the kernel to prefer to reclaim dentries and inodes. + dirty_background_ratio ---------------------- diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index fc3e413c3721..c873ef92fbfa 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -28,7 +28,7 @@ Currently, these files are in /proc/sys/vm: ============================================================== dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, -dirty_writeback_centisecs: +dirty_writeback_centisecs, vfs_cache_pressure: See Documentation/filesystems/proc.txt diff --git a/fs/dcache.c b/fs/dcache.c index 02df5d45b82e..ac36b5c5fdf2 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -32,9 +32,10 @@ #include #include -#define DCACHE_PARANOIA 1 /* #define DCACHE_DEBUG 1 */ +int sysctl_vfs_cache_pressure = 100; + spinlock_t dcache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; @@ -664,7 +665,7 @@ static int shrink_dcache_memory(int nr, unsigned int gfp_mask) return -1; prune_dcache(nr); } - return dentry_stat.nr_unused; + return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; } /** diff --git a/fs/inode.c b/fs/inode.c index e802a3c35fd2..ad1dd009acbc 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -488,7 +488,7 @@ static int shrink_icache_memory(int nr, unsigned int gfp_mask) if (gfp_mask & __GFP_FS) prune_icache(nr); } - return inodes_stat.nr_unused; + return (inodes_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; } static void __wait_on_freeing_inode(struct inode *inode); diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 72f48658a7d7..66e27328434b 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -313,6 +313,8 @@ static inline int d_mountpoint(struct dentry *dentry) extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *); extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); +extern int sysctl_vfs_cache_pressure; + #endif /* __KERNEL__ */ #endif /* __LINUX_DCACHE_H */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index f70f7fc14498..38acd5d4b691 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -164,6 +164,7 @@ enum VM_LAPTOP_MODE=23, /* vm laptop mode */ VM_BLOCK_DUMP=24, /* block dump mode */ VM_HUGETLB_GROUP=25, /* permitted hugetlb group */ + VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */ }; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 7dca63a88ea2..641727bab22f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -39,6 +39,8 @@ #include #include #include +#include + #include #ifdef CONFIG_ROOT_NFS @@ -777,6 +779,16 @@ static ctl_table vm_table[] = { .strategy = &sysctl_intvec, .extra1 = &zero, }, + { + .ctl_name = VM_VFS_CACHE_PRESSURE, + .procname = "vfs_cache_pressure", + .data = &sysctl_vfs_cache_pressure, + .maxlen = sizeof(sysctl_vfs_cache_pressure), + .mode = 0644, + .proc_handler = &proc_dointvec, + .strategy = &sysctl_intvec, + .extra1 = &zero, + }, { .ctl_name = 0 } }; -- cgit v1.2.3 From 0ac04ac1d635bc16d7336171c01899bf97b04953 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:15 -0700 Subject: [PATCH] dnotify.c: use inode->i_lock in place of dn_lock From: "Adam J. Richter" Replace the use of a global spinlock with the per-inode ->i_lock. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/dnotify.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/dnotify.c b/fs/dnotify.c index daee2edb17cc..2801eb4fdf10 100644 --- a/fs/dnotify.c +++ b/fs/dnotify.c @@ -23,7 +23,6 @@ int dir_notify_enable = 1; -static rwlock_t dn_lock = RW_LOCK_UNLOCKED; static kmem_cache_t *dn_cache; static void redo_inode_mask(struct inode *inode) @@ -46,7 +45,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) inode = filp->f_dentry->d_inode; if (!S_ISDIR(inode->i_mode)) return; - write_lock(&dn_lock); + spin_lock(&inode->i_lock); prev = &inode->i_dnotify; while ((dn = *prev) != NULL) { if ((dn->dn_owner == id) && (dn->dn_filp == filp)) { @@ -57,7 +56,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) } prev = &dn->dn_next; } - write_unlock(&dn_lock); + spin_unlock(&inode->i_lock); } int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) @@ -81,7 +80,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL); if (dn == NULL) return -ENOMEM; - write_lock(&dn_lock); + spin_lock(&inode->i_lock); prev = &inode->i_dnotify; while ((odn = *prev) != NULL) { if ((odn->dn_owner == id) && (odn->dn_filp == filp)) { @@ -104,12 +103,13 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) inode->i_dnotify_mask |= arg & ~DN_MULTISHOT; dn->dn_next = inode->i_dnotify; inode->i_dnotify = dn; -out: - write_unlock(&dn_lock); - return error; + spin_unlock(&inode->i_lock); + return 0; + out_free: + spin_unlock(&inode->i_lock); kmem_cache_free(dn_cache, dn); - goto out; + return error; } void __inode_dir_notify(struct inode *inode, unsigned long event) @@ -119,7 +119,7 @@ void __inode_dir_notify(struct inode *inode, unsigned long event) struct fown_struct * fown; int changed = 0; - write_lock(&dn_lock); + spin_lock(&inode->i_lock); prev = &inode->i_dnotify; while ((dn = *prev) != NULL) { if ((dn->dn_mask & event) == 0) { @@ -138,7 +138,7 @@ void __inode_dir_notify(struct inode *inode, unsigned long event) } if (changed) redo_inode_mask(inode); - write_unlock(&dn_lock); + spin_unlock(&inode->i_lock); } EXPORT_SYMBOL(__inode_dir_notify); -- cgit v1.2.3 From 758e48e4186f474b3258b9c4b4480511df1e6808 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:26 -0700 Subject: [PATCH] Use fancy wakeups in wait.h Use the more SMP-friendly prepare_to_wait()/finish_wait() in wait_event() and friends. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/wait.h | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/include/linux/wait.h b/include/linux/wait.h index 4a9f996bb6cc..e0f2b2ffc16f 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -120,18 +120,15 @@ extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int #define __wait_event(wq, condition) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_UNINTERRUPTIBLE); \ + prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ if (condition) \ break; \ schedule(); \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event(wq, condition) \ @@ -143,12 +140,10 @@ do { \ #define __wait_event_interruptible(wq, condition, ret) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ if (condition) \ break; \ if (!signal_pending(current)) { \ @@ -158,8 +153,7 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible(wq, condition) \ @@ -172,12 +166,10 @@ do { \ #define __wait_event_interruptible_timeout(wq, condition, ret) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ if (condition) \ break; \ if (!signal_pending(current)) { \ @@ -189,8 +181,7 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible_timeout(wq, condition, timeout) \ @@ -203,12 +194,11 @@ do { \ #define __wait_event_interruptible_exclusive(wq, condition, ret) \ do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ + DEFINE_WAIT(__wait); \ \ - add_wait_queue_exclusive(&wq, &__wait); \ for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ + prepare_to_wait_exclusive(&wq, &__wait, \ + TASK_INTERRUPTIBLE); \ if (condition) \ break; \ if (!signal_pending(current)) { \ @@ -218,8 +208,7 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ + finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible_exclusive(wq, condition) \ -- cgit v1.2.3 From c75b81a5da09be94099cf7b46bdb32fedc8ce71a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:38 -0700 Subject: [PATCH] tweak the buddy allocator for better I/O merging From: William Lee Irwin III Based on Arjan van de Ven's idea, with guidance and testing from James Bottomley. The physical ordering of pages delivered to the IO subsystem is strongly related to the order in which fragments are subdivided from larger blocks of memory tracked by the page allocator. Consider a single MAX_ORDER block of memory in isolation acted on by a sequence of order 0 allocations in an otherwise empty buddy system. Subdividing the block beginning at the highest addresses will yield all the pages of the block in reverse, and subdividing the block begining at the lowest addresses will yield all the pages of the block in physical address order. Empirical tests demonstrate this ordering is preserved, and that changing the order of subdivision so that the lowest page is split off first resolves the sglist merging difficulties encountered by driver authors at Adaptec and others in James Bottomley's testing. James found that before this patch, there were 40 merges out of about 32K segments. Afterward, there were 24007 merges out of 19513 segments, for a merge rate of about 55%. Merges of 128 segments, the maximum allowed, were observed afterward, where beforehand they never occurred. It also improves dbench on my workstation and works fine there. Signed-off-by: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b30e78c2a939..f8dbd8be97b5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -293,6 +293,20 @@ void __free_pages_ok(struct page *page, unsigned int order) #define MARK_USED(index, order, area) \ __change_bit((index) >> (1+(order)), (area)->map) +/* + * The order of subdivision here is critical for the IO subsystem. + * Please do not alter this order without good reasons and regression + * testing. Specifically, as large blocks of memory are subdivided, + * the order in which smaller blocks are delivered depends on the order + * they're subdivided in this function. This is the primary factor + * influencing the order in which pages are delivered to the IO + * subsystem according to empirical testing, and this is also justified + * by considering the behavior of a buddy system containing a single + * large block of memory acted on by a series of small allocations. + * This behavior is a critical factor in sglist merging's success. + * + * -- wli + */ static inline struct page * expand(struct zone *zone, struct page *page, unsigned long index, int low, int high, struct free_area *area) @@ -300,14 +314,12 @@ expand(struct zone *zone, struct page *page, unsigned long size = 1 << high; while (high > low) { - BUG_ON(bad_range(zone, page)); area--; high--; size >>= 1; - list_add(&page->lru, &area->free_list); - MARK_USED(index, high, area); - index += size; - page += size; + BUG_ON(bad_range(zone, &page[size])); + list_add(&page[size].lru, &area->free_list); + MARK_USED(index + size, high, area); } return page; } -- cgit v1.2.3 From b167eef8224b01dec3f15bb95936595013a6066f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:54:49 -0700 Subject: [PATCH] hwcache align kmalloc caches From: Manfred Spraul Reversing the patches that made all caches hw cacheline aligned had an unintended side effect on the kmalloc caches: Before they had the SLAB_HWCACHE_ALIGN flag set, now it's clear. This breaks one sgi driver - it expects aligned caches. Additionally I think it's the right thing to do: It costs virtually nothing (the caches are power-of-two sized) and could reduce false sharing. Additionally, the patch adds back the documentation for the SLAB_HWCACHE_ALIGN flag. Signed-Off: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 45c5c0549230..d99f1eb10dbf 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -129,6 +129,10 @@ #define ARCH_KMALLOC_MINALIGN 0 #endif +#ifndef ARCH_KMALLOC_FLAGS +#define ARCH_KMALLOC_FLAGS SLAB_HWCACHE_ALIGN +#endif + /* Legal flag mask for kmem_cache_create(). */ #if DEBUG # define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \ @@ -758,7 +762,7 @@ void __init kmem_cache_init(void) * allow tighter packing of the smaller caches. */ sizes->cs_cachep = kmem_cache_create(names->name, sizes->cs_size, ARCH_KMALLOC_MINALIGN, - SLAB_PANIC, NULL, NULL); + (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL); /* Inc off-slab bufctl limit until the ceiling is hit. */ if (!(OFF_SLAB(sizes->cs_cachep))) { @@ -768,7 +772,8 @@ void __init kmem_cache_init(void) sizes->cs_dmacachep = kmem_cache_create(names->name_dma, sizes->cs_size, ARCH_KMALLOC_MINALIGN, - (SLAB_CACHE_DMA | SLAB_PANIC), NULL, NULL); + (ARCH_KMALLOC_FLAGS | SLAB_CACHE_DMA | SLAB_PANIC), + NULL, NULL); sizes++; names++; @@ -1116,8 +1121,9 @@ static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp) * %SLAB_NO_REAP - Don't automatically reap this cache when we're under * memory pressure. * - * %SLAB_HWCACHE_ALIGN - This flag has no effect and will be removed soon. - * + * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware + * cacheline. This can be beneficial if you're counting cycles as closely + * as davem. */ kmem_cache_t * kmem_cache_create (const char *name, size_t size, size_t align, -- cgit v1.2.3 From f875aa02c8594625486193f4226747c1079a6a05 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:00 -0700 Subject: [PATCH] reduce function inlining in slab.c From: Manfred Spraul slab.c contains too many inline functions: - some functions that are not performance critical were inlined. Waste of text size. - The debug code relies on __builtin_return_address(0) to keep track of the callers. According to rmk, gcc didn't inline some functions as expected and that resulted in useless debug output. This was probably caused by the large debug-only inline functions. The attached patche removes most inline functions: - the empty on release/huge on debug inline functions were replaced with empty macros on release/normal functions on debug. - spurious inline statements were removed. The code is down to 6 inline functions: three one-liners for struct abstractions, one for a might_sleep_if test and two for the performance critical __cache_alloc / __cache_free functions. Note: If an embedded arch wants to save a few bytes by uninlining __cache_{free,alloc}: The right way to do that is to fold the functions into kmem_cache_xy and then replace kmalloc with kmem_cache_alloc(kmem_find_general_cachep(),). Signed-Off: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 84 ++++++++++++++++++++++++++++----------------------------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index d99f1eb10dbf..741f6461031f 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -384,12 +384,12 @@ struct kmem_cache_s { * cachep->objsize - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long] * cachep->objsize - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long] */ -static inline int obj_dbghead(kmem_cache_t *cachep) +static int obj_dbghead(kmem_cache_t *cachep) { return cachep->dbghead; } -static inline int obj_reallen(kmem_cache_t *cachep) +static int obj_reallen(kmem_cache_t *cachep) { return cachep->reallen; } @@ -413,30 +413,15 @@ static void **dbg_userword(kmem_cache_t *cachep, void *objp) BUG_ON(!(cachep->flags & SLAB_STORE_USER)); return (void**)(objp+cachep->objsize-BYTES_PER_WORD); } + #else -static inline int obj_dbghead(kmem_cache_t *cachep) -{ - return 0; -} -static inline int obj_reallen(kmem_cache_t *cachep) -{ - return cachep->objsize; -} -static inline unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp) -{ - BUG(); - return 0; -} -static inline unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp) -{ - BUG(); - return 0; -} -static inline void **dbg_userword(kmem_cache_t *cachep, void *objp) -{ - BUG(); - return 0; -} + +#define obj_dbghead(x) 0 +#define obj_reallen(cachep) (cachep->objsize) +#define dbg_redzone1(cachep, objp) ({BUG(); (unsigned long *)NULL;}) +#define dbg_redzone2(cachep, objp) ({BUG(); (unsigned long *)NULL;}) +#define dbg_userword(cachep, objp) ({BUG(); (void **)NULL;}) + #endif /* @@ -879,7 +864,7 @@ static void *kmem_getpages(kmem_cache_t *cachep, int flags, int nodeid) /* * Interface to system's page release. */ -static inline void kmem_freepages(kmem_cache_t *cachep, void *addr) +static void kmem_freepages(kmem_cache_t *cachep, void *addr) { unsigned long i = (1<gfporder); struct page *page = virt_to_page(addr); @@ -1413,27 +1398,29 @@ opps: } EXPORT_SYMBOL(kmem_cache_create); -static inline void check_irq_off(void) -{ #if DEBUG +static void check_irq_off(void) +{ BUG_ON(!irqs_disabled()); -#endif } -static inline void check_irq_on(void) +static void check_irq_on(void) { -#if DEBUG BUG_ON(irqs_disabled()); -#endif } -static inline void check_spinlock_acquired(kmem_cache_t *cachep) +static void check_spinlock_acquired(kmem_cache_t *cachep) { #ifdef CONFIG_SMP check_irq_off(); BUG_ON(spin_trylock(&cachep->spinlock)); #endif } +#else +#define check_irq_off() do { } while(0) +#define check_irq_on() do { } while(0) +#define check_spinlock_acquired(x) do { } while(0) +#endif /* * Waits for all CPUs to execute func(). @@ -1596,7 +1583,7 @@ int kmem_cache_destroy (kmem_cache_t * cachep) EXPORT_SYMBOL(kmem_cache_destroy); /* Get the memory for a slab management obj. */ -static inline struct slab* alloc_slabmgmt (kmem_cache_t *cachep, +static struct slab* alloc_slabmgmt (kmem_cache_t *cachep, void *objp, int colour_off, int local_flags) { struct slab *slabp; @@ -1779,15 +1766,16 @@ failed: return 0; } +#if DEBUG + /* * Perform extra freeing checks: * - detect bad pointers. * - POISON/RED_ZONE checking * - destructor calls, for caches with POISON+dtor */ -static inline void kfree_debugcheck(const void *objp) +static void kfree_debugcheck(const void *objp) { -#if DEBUG struct page *page; if (!virt_addr_valid(objp)) { @@ -1800,12 +1788,10 @@ static inline void kfree_debugcheck(const void *objp) printk(KERN_ERR "kfree_debugcheck: bad ptr %lxh.\n", (unsigned long)objp); BUG(); } -#endif } -static inline void *cache_free_debugcheck (kmem_cache_t * cachep, void * objp, void *caller) +static void *cache_free_debugcheck (kmem_cache_t * cachep, void * objp, void *caller) { -#if DEBUG struct page *page; unsigned int objnr; struct slab *slabp; @@ -1867,13 +1853,11 @@ static inline void *cache_free_debugcheck (kmem_cache_t * cachep, void * objp, v poison_obj(cachep, objp, POISON_FREE); #endif } -#endif return objp; } -static inline void check_slabp(kmem_cache_t *cachep, struct slab *slabp) +static void check_slabp(kmem_cache_t *cachep, struct slab *slabp) { -#if DEBUG int i; int entries = 0; @@ -1897,8 +1881,12 @@ bad: printk("\n"); BUG(); } -#endif } +#else +#define kfree_debugcheck(x) do { } while(0) +#define cache_free_debugcheck(x,objp,z) (objp) +#define check_slabp(x,y) do { } while(0) +#endif static void* cache_alloc_refill(kmem_cache_t* cachep, int flags) { @@ -2005,11 +1993,11 @@ cache_alloc_debugcheck_before(kmem_cache_t *cachep, int flags) #endif } -static inline void * +#if DEBUG +static void * cache_alloc_debugcheck_after(kmem_cache_t *cachep, unsigned long flags, void *objp, void *caller) { -#if DEBUG if (!objp) return objp; if (cachep->flags & SLAB_POISON) { @@ -2045,9 +2033,11 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep, cachep->ctor(objp, cachep, ctor_flags); } -#endif return objp; } +#else +#define cache_alloc_debugcheck_after(a,b,objp,d) (objp) +#endif static inline void * __cache_alloc (kmem_cache_t *cachep, int flags) @@ -2693,7 +2683,7 @@ static void drain_array_locked(kmem_cache_t *cachep, * If we cannot acquire the cache chain semaphore then just give up - we'll * try again next timer interrupt. */ -static inline void cache_reap (void) +static void cache_reap (void) { struct list_head *walk; -- cgit v1.2.3 From 8dac324845379809bea5d35ece79521094f3e6f4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:11 -0700 Subject: [PATCH] abs() fixes OK, the pending abs() disaster has hit: drivers/usb/class/audio.c:404: warning: static declaration of 'abs' follows non-static declaration This is due to the declaration in kernel.h. AFAIK there's not even a matching definition for that. The patch implements abs() as a macro in kernel.h and kills off various private implementations. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/ppc_ksyms.c | 4 ---- drivers/usb/class/audio.c | 14 -------------- include/asm-ppc64/system.h | 2 -- include/linux/kernel.h | 11 ++++++++++- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c index 1a8e1bf630c6..836cf2a43eab 100644 --- a/arch/ppc64/kernel/ppc_ksyms.c +++ b/arch/ppc64/kernel/ppc_ksyms.c @@ -47,8 +47,6 @@ extern int do_signal(sigset_t *, struct pt_regs *); -int abs(int); - EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(isa_io_base); @@ -157,8 +155,6 @@ EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL_NOVERS(memchr); -EXPORT_SYMBOL(abs); - EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(get_wchan); diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 96a1c025ddf0..648bbb033bb2 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c @@ -212,9 +212,6 @@ #define dprintk(x) -#undef abs -extern int abs(int __x) __attribute_const__; /* Shut up warning */ - /* --------------------------------------------------------------------- */ /* @@ -398,17 +395,6 @@ struct usb_audio_state { /* --------------------------------------------------------------------- */ -/* prevent picking up a bogus abs macro */ -#undef abs -static inline int abs(int x) -{ - if (x < 0) - return -x; - return x; -} - -/* --------------------------------------------------------------------- */ - static inline unsigned ld2(unsigned int x) { unsigned r = 0; diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 06ecd1bb285d..47c78eef463c 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h @@ -128,8 +128,6 @@ static inline void flush_altivec_to_thread(struct task_struct *t) } #endif -extern int abs(int); - extern struct task_struct *__switch_to(struct task_struct *, struct task_struct *); #define switch_to(prev, next, last) ((last) = __switch_to((prev), (next))) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 9eb023020b44..d6ed9b926c6f 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -54,6 +54,16 @@ void __might_sleep(char *file, int line); #define might_sleep_if(cond) do {} while (0) #endif +#define abs(x) ({ \ + int __x = (x); \ + (__x < 0) ? -__x : __x; \ + }) + +#define labs(x) ({ \ + long __x = (x); \ + (__x < 0) ? -__x : __x; \ + }) + extern struct notifier_block *panic_notifier_list; NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))); @@ -61,7 +71,6 @@ asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET; NORET_TYPE void complete_and_exit(struct completion *, long) ATTRIB_NORET; -extern int abs(int); extern unsigned long simple_strtoul(const char *,char **,unsigned int); extern long simple_strtol(const char *,char **,unsigned int); extern unsigned long long simple_strtoull(const char *,char **,unsigned int); -- cgit v1.2.3 From 296d3c783b83b8a80cd16301ea6d0dabe2b77637 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:22 -0700 Subject: [PATCH] Support NetMOS based PCI cards providing serial and parallel ports From: Christoph Lameter Attached a patch to support a variety of PCI based serial and parallel port I/O ports (typically labeled 222N-2 or 9835). I think this should go into 2.6.0 since it has been out there for a long time and is just some additional driver support that somehow fell through the cracks in 2.4.X. Tim Waugh submitted it in the 2.4.X series. See also http://winterwolf.co.uk/pciio Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/ChangeLog | 4 ++++ drivers/parport/parport_pc.c | 17 +++++++++++++++++ drivers/parport/parport_serial.c | 10 ++++++++++ include/linux/pci_ids.h | 4 ++++ 4 files changed, 35 insertions(+) diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog index 692415edb153..db717c1d62a5 100644 --- a/drivers/parport/ChangeLog +++ b/drivers/parport/ChangeLog @@ -1,3 +1,7 @@ +2001-10-11 Tim Waugh + * parport_pc.c, parport_serial.c: Support for NetMos cards. + + Patch originally from Michael Reinelt . + 2002-04-25 Tim Waugh * parport_serial.c, parport_pc.c: Move some SIIG cards around. diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 218eb4fd785e..fe4cc866de08 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2632,6 +2632,10 @@ enum parport_pc_pci_cards { oxsemi_840, aks_0100, mobility_pp, + netmos_9705, + netmos_9805, + netmos_9815, + netmos_9855, }; @@ -2701,6 +2705,10 @@ static struct parport_pc_pci { /* oxsemi_840 */ { 1, { { 0, -1 }, } }, /* aks_0100 */ { 1, { { 0, -1 }, } }, /* mobility_pp */ { 1, { { 0, 1 }, } }, + /* netmos_9705 */ { 1, { { 0, -1 }, } }, /* untested */ + /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ + /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ + /* netmos_9855 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ }; static struct pci_device_id parport_pc_pci_tbl[] = { @@ -2769,6 +2777,15 @@ static struct pci_device_id parport_pc_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 }, { PCI_VENDOR_ID_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 }, + /* NetMos communication controllers */ + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9805, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index c29e8ded5fbc..1f17d0124cc7 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -33,6 +33,8 @@ enum parport_pc_pci_cards { titan_110l = 0, titan_210l, + netmos_9735, + netmos_9835, avlab_1s1p, avlab_1s1p_650, avlab_1s1p_850, @@ -71,6 +73,8 @@ static struct parport_pc_pci { } cards[] __devinitdata = { /* titan_110l */ { 1, { { 3, -1 }, } }, /* titan_210l */ { 1, { { 3, -1 }, } }, + /* netmos_9735 (not tested) */ { 1, { { 2, -1 }, } }, + /* netmos_9835 */ { 1, { { 2, -1 }, } }, /* avlab_1s1p */ { 1, { { 1, 2}, } }, /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, @@ -93,6 +97,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L, PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9735 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9835 }, /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, @@ -172,6 +180,8 @@ static struct pci_board_no_ids pci_boards[] __devinitdata = { /* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, /* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, +/* netmos_9735 (n/t)*/ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, +/* netmos_9835 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 45d805ddeb9e..ba2d0b357306 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2252,8 +2252,12 @@ #define PCI_DEVICE_ID_HOLTEK_6565 0x6565 #define PCI_VENDOR_ID_NETMOS 0x9710 +#define PCI_DEVICE_ID_NETMOS_9705 0x9705 #define PCI_DEVICE_ID_NETMOS_9735 0x9735 +#define PCI_DEVICE_ID_NETMOS_9805 0x9805 +#define PCI_DEVICE_ID_NETMOS_9815 0x9815 #define PCI_DEVICE_ID_NETMOS_9835 0x9835 +#define PCI_DEVICE_ID_NETMOS_9855 0x9855 #define PCI_SUBVENDOR_ID_EXSYS 0xd84d #define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014 -- cgit v1.2.3 From 26b193e6bf56a27bc9ffe759f1c3b384c309a0a6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:33 -0700 Subject: [PATCH] help text for FB_RIVA_I2C From: "Antonino A. Daplas" Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7c551a2c26ce..b8ea9ab1e6a9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -436,6 +436,13 @@ config FB_RIVA_I2C bool "Enable DDC Support" depends on FB_RIVA && I2C help + This enables I2C support for nVidia Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. config FB_I810 tristate "Intel 810/815 support (EXPERIMENTAL)" -- cgit v1.2.3 From 6a948bc8ac0d7b3c4bf1a46838fb3786ecffbd93 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:44 -0700 Subject: [PATCH] nr_pagecache can go negative We use per-cpu counters for the system-wide pagecache accounting. The counters spill into the global nr_pagecache atomic_t when they underflow or overflow. Hence it is possible, under weird circumstances, for nr_pagecache to go negative. Anton says he has hit this. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 427b696f484b..4da205f3cb26 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -136,7 +137,10 @@ static inline void pagecache_acct(int count) static inline unsigned long get_page_cache_size(void) { - return atomic_read(&nr_pagecache); + int ret = atomic_read(&nr_pagecache); + if (unlikely(ret < 0)) + ret = 0; + return ret; } static inline pgoff_t linear_page_index(struct vm_area_struct *vma, -- cgit v1.2.3 From a5b5323bfe43d8a284119248d54008fc7b483608 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:55:56 -0700 Subject: [PATCH] Make nr_swap_pages a long From: Anton Blanchard ../include/linux/swap.h:extern int nr_swap_pages; /* XXX: shouldn't this be ulong? --hch */ Sounds like it should be too me. Some of the code checks for nr_swap_pages < 0 so I made it a long instead. I had to fix up the ppc64 show_mem() (Im guessing there will be other trivial changes required in other 64bit archs, I can find and fix those if you want). I also noticed that the ppc64 show_mem() used ints to store page counts. We can overflow that, so make them unsigned long. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/mm/init.c | 2 +- arch/alpha/mm/numa.c | 2 +- arch/arm/mm/init.c | 2 +- arch/arm26/mm/init.c | 2 +- arch/cris/mm/init.c | 2 +- arch/i386/mm/pgtable.c | 2 +- arch/ia64/mm/contig.c | 2 +- arch/ia64/mm/discontig.c | 2 +- arch/m68k/atari/stram.c | 4 ++-- arch/m68k/mm/init.c | 2 +- arch/mips/mm/pgtable.c | 2 +- arch/parisc/mm/init.c | 3 ++- arch/ppc/mm/init.c | 2 +- arch/ppc64/mm/init.c | 14 +++++++------- arch/s390/mm/init.c | 2 +- arch/sh/mm/init.c | 2 +- arch/sparc/mm/init.c | 2 +- arch/sparc64/mm/init.c | 2 +- arch/um/kernel/mem.c | 2 +- arch/x86_64/mm/init.c | 2 +- include/linux/swap.h | 2 +- mm/page_alloc.c | 2 +- 22 files changed, 30 insertions(+), 29 deletions(-) diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 0a5873f7e3fb..3ea81ca1c6d9 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -106,7 +106,7 @@ show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index 91f5f373f811..31a3f63433f3 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -371,7 +371,7 @@ show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for (nid = 0; nid < numnodes; nid++) { struct page * lmem_map = node_mem_map(nid); i = node_spanned_pages(nid); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 07ddce79808c..c183e6537114 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -58,7 +58,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for (node = 0; node < numnodes; node++) { struct page *page, *end; diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c index a4f56b2b493b..ad41cebe207a 100644 --- a/arch/arm26/mm/init.c +++ b/arch/arm26/mm/init.c @@ -67,7 +67,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); page = NODE_MEM_MAP(0); diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index d0bd0c957d28..31a0018b525a 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -138,7 +138,7 @@ show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 49561339cbcc..137d18db72ff 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -33,7 +33,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { page = pgdat->node_mem_map + i; diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 183533a62dbd..c0f8f4a3e019 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -43,7 +43,7 @@ show_mem (void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { if (!pfn_valid(i)) diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index b8472d960191..788aa84e3420 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -498,7 +498,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { printk("Node ID: %d\n", pgdat->node_id); for(i = 0; i < pgdat->node_spanned_pages; i++) { diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index b03d03163496..f7cfaa6db534 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c @@ -743,7 +743,7 @@ static int unswap_by_read(unsigned short *map, unsigned long max, if (map[i]) { entry = swp_entry(stram_swap_type, i); - DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n", + DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n", i, map[i], nr_swap_pages); swap_device_lock(stram_swap_info); @@ -772,7 +772,7 @@ static int unswap_by_read(unsigned short *map, unsigned long max, #endif } - DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n", + DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n", i, map[i], nr_swap_pages ); swap_list_lock(); swap_device_lock(stram_swap_info); diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index d79dbfae6b21..c45beb955943 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -47,7 +47,7 @@ void show_mem(void) printk("\nMem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c index b1722b8f6e5e..8c30f32a66e8 100644 --- a/arch/mips/mm/pgtable.c +++ b/arch/mips/mm/pgtable.c @@ -12,7 +12,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); pfn = max_mapnr; while (pfn-- > 0) { page = pfn_to_page(pfn); diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index e7a8b1bc9ae4..94f5d4e60920 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -484,7 +484,8 @@ void show_mem(void) printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk(KERN_INFO "Free swap: %6ldkB\n", + nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index b53c0f0f3347..448e80c11518 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -118,7 +118,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index 5043702a470f..857e8915ee89 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -89,15 +89,15 @@ unsigned long top_of_ram; void show_mem(void) { - int total = 0, reserved = 0; - int shared = 0, cached = 0; + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; struct page *page; pg_data_t *pgdat; unsigned long i; printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; i++) { page = pgdat->node_mem_map + i; @@ -110,10 +110,10 @@ void show_mem(void) shared += page_count(page) - 1; } } - printk("%d pages of RAM\n",total); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); + printk("%ld pages of RAM\n", total); + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); } #ifdef CONFIG_PPC_ISERIES diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 177a3d26e261..1541b8699c17 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -60,7 +60,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 95b5368c0670..7b2bcad145ca 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -66,7 +66,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 1d61ed4130b3..4bc6aff2c8c3 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -76,7 +76,7 @@ void show_mem(void) { printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", totalram_pages); printk("%d free pages\n", nr_free_pages()); diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 043861f313c2..72a2164bdf67 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -348,7 +348,7 @@ void show_mem(void) { printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", num_physpages); printk("%d free pages\n", nr_free_pages()); diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index ec2be14beedf..84a895c2a365 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -380,7 +380,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); pfn = max_mapnr; while(pfn-- > 0) { page = pfn_to_page(pfn); diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index fa8cc36487d7..f393e3355b99 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -60,7 +60,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { diff --git a/include/linux/swap.h b/include/linux/swap.h index a748538f3a31..62a841cc18b2 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -156,7 +156,7 @@ extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct * /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; extern unsigned long totalhigh_pages; -extern int nr_swap_pages; /* XXX: shouldn't this be ulong? --hch */ +extern long nr_swap_pages; extern unsigned int nr_free_pages(void); extern unsigned int nr_free_pages_pgdat(pg_data_t *pgdat); extern unsigned int nr_free_buffer_pages(void); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f8dbd8be97b5..fe55c14bd4dc 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -38,7 +38,7 @@ DECLARE_BITMAP(node_online_map, MAX_NUMNODES); struct pglist_data *pgdat_list; unsigned long totalram_pages; unsigned long totalhigh_pages; -int nr_swap_pages; +long nr_swap_pages; int numnodes = 1; int sysctl_lower_zone_protection = 0; -- cgit v1.2.3 From e62d1b673e80773490a0b2362e85ea4e64c50709 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:56:08 -0700 Subject: [PATCH] make total_swap_pages a long Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 2 +- mm/swapfile.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 62a841cc18b2..b9edc335a563 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -206,7 +206,7 @@ extern struct page * read_swap_cache_async(swp_entry_t, struct vm_area_struct *v unsigned long addr); /* linux/mm/swapfile.c */ -extern int total_swap_pages; +extern long total_swap_pages; extern unsigned int nr_swapfiles; extern struct swap_info_struct swap_info[]; extern void si_swapinfo(struct sysinfo *); diff --git a/mm/swapfile.c b/mm/swapfile.c index 6422f1b8d810..714c8339c5f2 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -32,7 +32,7 @@ spinlock_t swaplock = SPIN_LOCK_UNLOCKED; unsigned int nr_swapfiles; -int total_swap_pages; +long total_swap_pages; static int swap_overflow; EXPORT_SYMBOL(total_swap_pages); -- cgit v1.2.3 From adaa6aad36dd8d00d5239ea820633e83ce19171c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:56:19 -0700 Subject: [PATCH] mips: SGI A2 audio rewrite and 2.6 fixes From: Ralf Baechle Fix HAL2 audio driver for the SGI A2 audio subsystem and rewrite large parts of it to finally work. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/oss/Kconfig | 5 +- sound/oss/hal2.c | 1157 ++++++++++++++++++++++++++++------------------------- sound/oss/hal2.h | 156 ++------ 3 files changed, 652 insertions(+), 666 deletions(-) diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 648bccd40806..05f6bc8ecee8 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -186,7 +186,10 @@ config SOUND_VWSND config SOUND_HAL2 tristate "SGI HAL2 sound (EXPERIMENTAL)" - depends on SGI_IP22 && SOUND && EXPERIMENTAL + depends on SOUND_PRIME!=n && SOUND && SGI_IP22 && EXPERIMENTAL + help + Say Y or M if you have an SGI Indy system and want to be able to + use it's on-board A2 audio system. config SOUND_VRC5477 tristate "NEC Vrc5477 AC97 sound" diff --git a/sound/oss/hal2.c b/sound/oss/hal2.c index 6ad89aa8b262..1f49d04242f3 100644 --- a/sound/oss/hal2.c +++ b/sound/oss/hal2.c @@ -1,6 +1,6 @@ /* - * Driver for HAL2 sound processors - * Copyright (c) 2001, 2002 Ladislav Michl + * Driver for A2 audio system used in SGI machines + * Copyright (c) 2001, 2002, 2003 Ladislav Michl * * Based on Ulf Carlsson's code. * @@ -21,22 +21,21 @@ * /dev/dsp standard dsp device, (mostly) OSS compatible * /dev/mixer standard mixer device, (mostly) OSS compatible * - * BUGS: - * + Driver currently supports indigo mode only. - * + Recording doesn't work. I guess that it is caused by PBUS channel - * misconfiguration, but until I get relevant info I'm unable to fix it. */ - +#include #include #include #include #include #include +#include +#include #include #include + #include -#include -#include +#include +#include #include "hal2.h" @@ -52,61 +51,131 @@ #define DEBUG_MIX(args...) #endif +/* + * Before touching these look how it works. It is a bit unusual I know, + * but it helps to keep things simple. This driver is considered complete + * and I won't add any new features although hardware has many cool + * capabilities. + * (Historical note: HAL2 driver was first written by Ulf Carlsson - ALSA + * 0.3 running with 2.2.x kernel. Then ALSA changed completely and it + * seemed easier to me to write OSS driver from scratch - this one. Now + * when ALSA is official part of 2.6 kernel it's time to write ALSA driver + * using (hopefully) final version of ALSA interface) + */ +#define H2_BLOCK_SIZE 1024 +#define H2_ADC_BUFSIZE 8192 +#define H2_DAC_BUFSIZE 16834 + +struct hal2_pbus { + struct hpc3_pbus_dmacregs *pbus; + int pbusnr; + unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */ +}; + +struct hal2_desc { + struct hpc_dma_desc desc; + u32 cnt; /* don't touch, it is also padding */ +}; + +struct hal2_codec { + unsigned char *buffer; + struct hal2_desc *desc; + int desc_count; + int tail, head; /* tail index, head index */ + struct hal2_pbus pbus; + unsigned int format; /* Audio data format */ + int voices; /* mono/stereo */ + unsigned int sample_rate; + unsigned int master; /* Master frequency */ + unsigned short mod; /* MOD value */ + unsigned short inc; /* INC value */ + + wait_queue_head_t dma_wait; + spinlock_t lock; + struct semaphore sem; + + int usecount; /* recording and playback are + * independent */ +}; + +#define H2_MIX_OUTPUT_ATT 0 +#define H2_MIX_INPUT_GAIN 1 +#define H2_MIXERS 2 +struct hal2_mixer { + int modcnt; + unsigned int master; + unsigned int volume[H2_MIXERS]; +}; + +struct hal2_card { + int dev_dsp; /* audio device */ + int dev_mixer; /* mixer device */ + int dev_midi; /* midi device */ + + struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */ + struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */ + struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */ + struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */ + + struct hal2_codec dac; + struct hal2_codec adc; + struct hal2_mixer mixer; +}; + #define H2_INDIRECT_WAIT(regs) while (regs->isr & H2_ISR_TSTATUS); #define H2_READ_ADDR(addr) (addr | (1<<7)) #define H2_WRITE_ADDR(addr) (addr) -static char *hal2str = "HAL2 audio"; -static int ibuffers = 32; -static int obuffers = 32; +static char *hal2str = "HAL2"; -/* I doubt anyone has a machine with two HAL2 cards. It's possible to +/* + * I doubt anyone has a machine with two HAL2 cards. It's possible to * have two HPC's, so it is probably possible to have two HAL2 cards. * Try to deal with it, but note that it is not tested. */ #define MAXCARDS 2 -static hal2_card_t* hal2_card[MAXCARDS]; +static struct hal2_card* hal2_card[MAXCARDS]; static const struct { unsigned char idx:4, avail:1; } mixtable[SOUND_MIXER_NRDEVICES] = { - [SOUND_MIXER_PCM] = { H2_MIX_OUTPUT_ATT, 1 }, /* voice */ - [SOUND_MIXER_MIC] = { H2_MIX_INPUT_GAIN, 1 }, /* mic */ + [SOUND_MIXER_PCM] = { H2_MIX_OUTPUT_ATT, 1 }, /* voice */ + [SOUND_MIXER_MIC] = { H2_MIX_INPUT_GAIN, 1 }, /* mic */ }; #define H2_SUPPORTED_FORMATS (AFMT_S16_LE | AFMT_S16_BE) -static inline void hal2_isr_write(hal2_card_t *hal2, u32 val) +static inline void hal2_isr_write(struct hal2_card *hal2, u16 val) { hal2->ctl_regs->isr = val; } -static inline u32 hal2_isr_look(hal2_card_t *hal2) +static inline u16 hal2_isr_look(struct hal2_card *hal2) { return hal2->ctl_regs->isr; } -static inline u32 hal2_rev_look(hal2_card_t *hal2) +static inline u16 hal2_rev_look(struct hal2_card *hal2) { return hal2->ctl_regs->rev; } -#if 0 -static u16 hal2_i_look16(hal2_card_t *hal2, u32 addr) +#ifdef HAL2_DUMP_REGS +static u16 hal2_i_look16(struct hal2_card *hal2, u16 addr) { - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - return (regs->idr0 & 0xffff); + return regs->idr0; } #endif -static u32 hal2_i_look32(hal2_card_t *hal2, u32 addr) +static u32 hal2_i_look32(struct hal2_card *hal2, u16 addr) { u32 ret; - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); @@ -117,9 +186,9 @@ static u32 hal2_i_look32(hal2_card_t *hal2, u32 addr) return ret; } -static void hal2_i_write16(hal2_card_t *hal2, u32 addr, u16 val) +static void hal2_i_write16(struct hal2_card *hal2, u16 addr, u16 val) { - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->idr0 = val; regs->idr1 = 0; @@ -129,9 +198,9 @@ static void hal2_i_write16(hal2_card_t *hal2, u32 addr, u16 val) H2_INDIRECT_WAIT(regs); } -static void hal2_i_write32(hal2_card_t *hal2, u32 addr, u32 val) +static void hal2_i_write32(struct hal2_card *hal2, u16 addr, u32 val) { - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->idr0 = val & 0xffff; regs->idr1 = val >> 16; @@ -141,13 +210,13 @@ static void hal2_i_write32(hal2_card_t *hal2, u32 addr, u32 val) H2_INDIRECT_WAIT(regs); } -static void hal2_i_setbit16(hal2_card_t *hal2, u32 addr, u16 bit) +static void hal2_i_setbit16(struct hal2_card *hal2, u16 addr, u16 bit) { - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - regs->idr0 = regs->idr0 | bit; + regs->idr0 = (regs->idr0 & 0xffff) | bit; regs->idr1 = 0; regs->idr2 = 0; regs->idr3 = 0; @@ -155,14 +224,14 @@ static void hal2_i_setbit16(hal2_card_t *hal2, u32 addr, u16 bit) H2_INDIRECT_WAIT(regs); } -static void hal2_i_setbit32(hal2_card_t *hal2, u32 addr, u32 bit) +static void hal2_i_setbit32(struct hal2_card *hal2, u16 addr, u32 bit) { u32 tmp; - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - tmp = regs->idr0 | (regs->idr1 << 16) | bit; + tmp = (regs->idr0 & 0xffff) | (regs->idr1 << 16) | bit; regs->idr0 = tmp & 0xffff; regs->idr1 = tmp >> 16; regs->idr2 = 0; @@ -171,13 +240,13 @@ static void hal2_i_setbit32(hal2_card_t *hal2, u32 addr, u32 bit) H2_INDIRECT_WAIT(regs); } -static void hal2_i_clearbit16(hal2_card_t *hal2, u32 addr, u16 bit) +static void hal2_i_clearbit16(struct hal2_card *hal2, u16 addr, u16 bit) { - hal2_ctl_regs_t *regs = hal2->ctl_regs; + struct hal2_ctl_regs *regs = hal2->ctl_regs; regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - regs->idr0 = regs->idr0 & ~bit; + regs->idr0 = (regs->idr0 & 0xffff) & ~bit; regs->idr1 = 0; regs->idr2 = 0; regs->idr3 = 0; @@ -186,14 +255,14 @@ static void hal2_i_clearbit16(hal2_card_t *hal2, u32 addr, u16 bit) } #if 0 -static void hal2_i_clearbit32(hal2_card_t *hal2, u32 addr, u32 bit) +static void hal2_i_clearbit32(struct hal2_card *hal2, u16 addr, u32 bit) { u32 tmp; hal2_ctl_regs_t *regs = hal2->ctl_regs; regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - tmp = (regs->idr0 | (regs->idr1 << 16)) & ~bit; + tmp = ((regs->idr0 & 0xffff) | (regs->idr1 << 16)) & ~bit; regs->idr0 = tmp & 0xffff; regs->idr1 = tmp >> 16; regs->idr2 = 0; @@ -203,33 +272,33 @@ static void hal2_i_clearbit32(hal2_card_t *hal2, u32 addr, u32 bit) } #endif -#ifdef HAL2_DEBUG -static void hal2_dump_regs(hal2_card_t *hal2) +#ifdef HAL2_DUMP_REGS +static void hal2_dump_regs(struct hal2_card *hal2) { - printk("isr: %08hx ", hal2_isr_look(hal2)); - printk("rev: %08hx\n", hal2_rev_look(hal2)); - printk("relay: %04hx\n", hal2_i_look16(hal2, H2I_RELAY_C)); - printk("port en: %04hx ", hal2_i_look16(hal2, H2I_DMA_PORT_EN)); - printk("dma end: %04hx ", hal2_i_look16(hal2, H2I_DMA_END)); - printk("dma drv: %04hx\n", hal2_i_look16(hal2, H2I_DMA_DRV)); - printk("syn ctl: %04hx ", hal2_i_look16(hal2, H2I_SYNTH_C)); - printk("aesrx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESRX_C)); - printk("aestx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESTX_C)); - printk("dac ctl1: %04hx ", hal2_i_look16(hal2, H2I_ADC_C1)); - printk("dac ctl2: %08lx ", hal2_i_look32(hal2, H2I_ADC_C2)); - printk("adc ctl1: %04hx ", hal2_i_look16(hal2, H2I_DAC_C1)); - printk("adc ctl2: %08lx ", hal2_i_look32(hal2, H2I_DAC_C2)); - printk("syn map: %04hx\n", hal2_i_look16(hal2, H2I_SYNTH_MAP_C)); - printk("bres1 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES1_C1)); - printk("bres1 ctl2: %04lx ", hal2_i_look32(hal2, H2I_BRES1_C2)); - printk("bres2 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES2_C1)); - printk("bres2 ctl2: %04lx ", hal2_i_look32(hal2, H2I_BRES2_C2)); - printk("bres3 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES3_C1)); - printk("bres3 ctl2: %04lx\n", hal2_i_look32(hal2, H2I_BRES3_C2)); + DEBUG("isr: %08hx ", hal2_isr_look(hal2)); + DEBUG("rev: %08hx\n", hal2_rev_look(hal2)); + DEBUG("relay: %04hx\n", hal2_i_look16(hal2, H2I_RELAY_C)); + DEBUG("port en: %04hx ", hal2_i_look16(hal2, H2I_DMA_PORT_EN)); + DEBUG("dma end: %04hx ", hal2_i_look16(hal2, H2I_DMA_END)); + DEBUG("dma drv: %04hx\n", hal2_i_look16(hal2, H2I_DMA_DRV)); + DEBUG("syn ctl: %04hx ", hal2_i_look16(hal2, H2I_SYNTH_C)); + DEBUG("aesrx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESRX_C)); + DEBUG("aestx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESTX_C)); + DEBUG("dac ctl1: %04hx ", hal2_i_look16(hal2, H2I_ADC_C1)); + DEBUG("dac ctl2: %08x ", hal2_i_look32(hal2, H2I_ADC_C2)); + DEBUG("adc ctl1: %04hx ", hal2_i_look16(hal2, H2I_DAC_C1)); + DEBUG("adc ctl2: %08x ", hal2_i_look32(hal2, H2I_DAC_C2)); + DEBUG("syn map: %04hx\n", hal2_i_look16(hal2, H2I_SYNTH_MAP_C)); + DEBUG("bres1 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES1_C1)); + DEBUG("bres1 ctl2: %04x ", hal2_i_look32(hal2, H2I_BRES1_C2)); + DEBUG("bres2 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES2_C1)); + DEBUG("bres2 ctl2: %04x ", hal2_i_look32(hal2, H2I_BRES2_C2)); + DEBUG("bres3 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES3_C1)); + DEBUG("bres3 ctl2: %04x\n", hal2_i_look32(hal2, H2I_BRES3_C2)); } #endif -static hal2_card_t* hal2_dsp_find_card(int minor) +static struct hal2_card* hal2_dsp_find_card(int minor) { int i; @@ -239,7 +308,7 @@ static hal2_card_t* hal2_dsp_find_card(int minor) return NULL; } -static hal2_card_t* hal2_mixer_find_card(int minor) +static struct hal2_card* hal2_mixer_find_card(int minor) { int i; @@ -249,48 +318,51 @@ static hal2_card_t* hal2_mixer_find_card(int minor) return NULL; } +static void hal2_inc_head(struct hal2_codec *codec) +{ + codec->head++; + if (codec->head == codec->desc_count) + codec->head = 0; +} -static void hal2_dac_interrupt(hal2_codec_t *dac) +static void hal2_inc_tail(struct hal2_codec *codec) +{ + codec->tail++; + if (codec->tail == codec->desc_count) + codec->tail = 0; +} + +static void hal2_dac_interrupt(struct hal2_codec *dac) { int running; spin_lock(&dac->lock); - /* if tail buffer contains zero samples DMA stream was already * stopped */ - running = dac->tail->info.cnt; - dac->tail->info.cnt = 0; - dac->tail->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX; - dma_cache_wback_inv((unsigned long) dac->tail, - sizeof(struct hpc_dma_desc)); + running = dac->desc[dac->tail].cnt; + dac->desc[dac->tail].cnt = 0; + dac->desc[dac->tail].desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX; /* we just proccessed empty buffer, don't update tail pointer */ if (running) - dac->tail = dac->tail->info.next; - + hal2_inc_tail(dac); spin_unlock(&dac->lock); wake_up(&dac->dma_wait); } -static void hal2_adc_interrupt(hal2_codec_t *adc) +static void hal2_adc_interrupt(struct hal2_codec *adc) { int running; - - spin_lock(&adc->lock); + spin_lock(&adc->lock); /* if head buffer contains nonzero samples DMA stream was already * stopped */ - running = !adc->head->info.cnt; - adc->head->info.cnt = H2_BUFFER_SIZE; - adc->head->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX; - dma_cache_wback_inv((unsigned long) adc->head, - sizeof(struct hpc_dma_desc)); + running = !adc->desc[adc->head].cnt; + adc->desc[adc->head].cnt = H2_BLOCK_SIZE; + adc->desc[adc->head].desc.cntinfo = HPCDMA_XIE | HPCDMA_EOR; /* we just proccessed empty buffer, don't update head pointer */ - if (running) { - dma_cache_inv((unsigned long) adc->head->data, H2_BUFFER_SIZE); - adc->head = adc->head->info.next; - } - + if (running) + hal2_inc_head(adc); spin_unlock(&adc->lock); wake_up(&adc->dma_wait); @@ -298,60 +370,48 @@ static void hal2_adc_interrupt(hal2_codec_t *adc) static irqreturn_t hal2_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - hal2_card_t *hal2 = (hal2_card_t*)dev_id; + struct hal2_card *hal2 = (struct hal2_card*)dev_id; + irqreturn_t ret = IRQ_NONE; /* decide what caused this interrupt */ - if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) + if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) { hal2_dac_interrupt(&hal2->dac); - if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) + ret = IRQ_HANDLED; + } + if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) { hal2_adc_interrupt(&hal2->adc); - return IRQ_HANDLED; + ret = IRQ_HANDLED; + } + return ret; } -static int hal2_compute_rate(hal2_codec_t *codec, unsigned int rate) +static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate) { - unsigned short inc; + unsigned short mod; - /* We default to 44.1 kHz and if it isn't possible to fall back to - * 48.0 kHz with the needed adjustments of real_rate. - */ - DEBUG("rate: %d\n", rate); - /* Refer to CS4216 data sheet */ - if (rate < 4000) - rate = 4000; - if (rate > 50000) - rate = 50000; - - /* Note: This is NOT the way they set up the bresenham clock generators - * in the specification. I've tried to implement that method but it - * doesn't work. It's probably another silly bug in the spec. - * - * I accidently discovered this method while I was testing and it seems - * to work very well with all frequencies, and thee shall follow rule #1 - * of programming :-) - */ - - if (44100 % rate == 0) { - inc = 44100 / rate; - if (inc < 1) inc = 1; + if (rate < 4000) rate = 4000; + else if (rate > 48000) rate = 48000; + + if (44100 % rate < 48000 % rate) { + mod = 4 * 44100 / rate; codec->master = 44100; } else { - inc = 48000 / rate; - if (inc < 1) inc = 1; - rate = 48000 / inc; + mod = 4 * 48000 / rate; codec->master = 48000; } - codec->inc = inc; - codec->mod = 1; - + + codec->inc = 4; + codec->mod = mod; + rate = 4 * codec->master / mod; + DEBUG("real_rate: %d\n", rate); return rate; } -static void hal2_set_dac_rate(hal2_card_t *hal2) +static void hal2_set_dac_rate(struct hal2_card *hal2) { unsigned int master = hal2->dac.master; int inc = hal2->dac.inc; @@ -360,10 +420,10 @@ static void hal2_set_dac_rate(hal2_card_t *hal2) DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod); hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0); - hal2_i_write32(hal2, H2I_BRES1_C2, ((0xffff & (mod - inc - 1)) << 16) | 1); + hal2_i_write32(hal2, H2I_BRES1_C2, ((0xffff & (inc - mod - 1)) << 16) | inc); } -static void hal2_set_adc_rate(hal2_card_t *hal2) +static void hal2_set_adc_rate(struct hal2_card *hal2) { unsigned int master = hal2->adc.master; int inc = hal2->adc.inc; @@ -372,13 +432,13 @@ static void hal2_set_adc_rate(hal2_card_t *hal2) DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod); hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0); - hal2_i_write32(hal2, H2I_BRES2_C2, ((0xffff & (mod - inc - 1)) << 16) | 1); + hal2_i_write32(hal2, H2I_BRES2_C2, ((0xffff & (inc - mod - 1)) << 16) | inc); } -static void hal2_setup_dac(hal2_card_t *hal2) +static void hal2_setup_dac(struct hal2_card *hal2) { unsigned int fifobeg, fifoend, highwater, sample_size; - hal2_pbus_t *pbus = &hal2->dac.pbus; + struct hal2_pbus *pbus = &hal2->dac.pbus; DEBUG("hal2_setup_dac\n"); @@ -388,230 +448,215 @@ static void hal2_setup_dac(hal2_card_t *hal2) * endian. The information is written later, on the start call. */ sample_size = 2 * hal2->dac.voices; - /* Fifo should be set to hold exactly four samples. Highwater mark * should be set to two samples. */ highwater = (sample_size * 2) >> 1; /* halfwords */ fifobeg = 0; /* playback is first */ fifoend = (sample_size * 4) >> 3; /* doublewords */ pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD | - (highwater << 8) | (fifobeg << 16) | (fifoend << 24); + (highwater << 8) | (fifobeg << 16) | (fifoend << 24) | + (hal2->dac.format & AFMT_S16_LE ? HPC3_PDMACTRL_SEL : 0); /* We disable everything before we do anything at all */ pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); - hal2_i_clearbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); /* Setup the HAL2 for playback */ hal2_set_dac_rate(hal2); + /* Set endianess */ + if (hal2->dac.format & AFMT_S16_LE) + hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX); + else + hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX); + /* Set DMA bus */ + hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); /* We are using 1st Bresenham clock generator for playback */ hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT) | (1 << H2I_C1_CLKID_SHIFT) | (hal2->dac.voices << H2I_C1_DATAT_SHIFT)); } -static void hal2_setup_adc(hal2_card_t *hal2) +static void hal2_setup_adc(struct hal2_card *hal2) { unsigned int fifobeg, fifoend, highwater, sample_size; - hal2_pbus_t *pbus = &hal2->adc.pbus; + struct hal2_pbus *pbus = &hal2->adc.pbus; DEBUG("hal2_setup_adc\n"); - - sample_size = 2 * hal2->adc.voices; + sample_size = 2 * hal2->adc.voices; highwater = (sample_size * 2) >> 1; /* halfwords */ fifobeg = (4 * 4) >> 3; /* record is second */ fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */ pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD | - (highwater << 8) | (fifobeg << 16) | (fifoend << 24); + (highwater << 8) | (fifobeg << 16) | (fifoend << 24) | + (hal2->adc.format & AFMT_S16_LE ? HPC3_PDMACTRL_SEL : 0); pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); - hal2_i_clearbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); /* Setup the HAL2 for record */ hal2_set_adc_rate(hal2); + /* Set endianess */ + if (hal2->adc.format & AFMT_S16_LE) + hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR); + else + hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR); + /* Set DMA bus */ + hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); /* We are using 2nd Bresenham clock generator for record */ hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT) | (2 << H2I_C1_CLKID_SHIFT) | (hal2->adc.voices << H2I_C1_DATAT_SHIFT)); } -static void hal2_start_dac(hal2_card_t *hal2) +static dma_addr_t hal2_desc_addr(struct hal2_codec *codec, int i) { - hal2_pbus_t *pbus = &hal2->dac.pbus; + if (--i < 0) + i = codec->desc_count - 1; + return codec->desc[i].desc.pnext; +} - DEBUG("hal2_start_dac\n"); - - pbus->pbus->pbdma_dptr = PHYSADDR(hal2->dac.tail); - pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; +static void hal2_start_dac(struct hal2_card *hal2) +{ + struct hal2_codec *dac = &hal2->dac; + struct hal2_pbus *pbus = &dac->pbus; - /* set endianess */ - if (hal2->dac.format & AFMT_S16_LE) - hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX); - else - hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX); - /* set DMA bus */ - hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); + pbus->pbus->pbdma_dptr = hal2_desc_addr(dac, dac->tail); + pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; /* enable DAC */ hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); } -static void hal2_start_adc(hal2_card_t *hal2) +static void hal2_start_adc(struct hal2_card *hal2) { - hal2_pbus_t *pbus = &hal2->adc.pbus; + struct hal2_codec *adc = &hal2->adc; + struct hal2_pbus *pbus = &adc->pbus; - DEBUG("hal2_start_adc\n"); - - pbus->pbus->pbdma_dptr = PHYSADDR(hal2->adc.head); + pbus->pbus->pbdma_dptr = hal2_desc_addr(adc, adc->head); pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; - - /* set endianess */ - if (hal2->adc.format & AFMT_S16_LE) - hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR); - else - hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR); - /* set DMA bus */ - hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); /* enable ADC */ hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); } -static inline void hal2_stop_dac(hal2_card_t *hal2) +static inline void hal2_stop_dac(struct hal2_card *hal2) { - DEBUG("hal2_stop_dac\n"); - hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; /* The HAL2 itself may remain enabled safely */ } -static inline void hal2_stop_adc(hal2_card_t *hal2) +static inline void hal2_stop_adc(struct hal2_card *hal2) { - DEBUG("hal2_stop_adc\n"); - hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; } -#define hal2_alloc_dac_dmabuf(hal2) hal2_alloc_dmabuf(hal2, 1) -#define hal2_alloc_adc_dmabuf(hal2) hal2_alloc_dmabuf(hal2, 0) -static int hal2_alloc_dmabuf(hal2_card_t *hal2, int is_dac) +static int hal2_alloc_dmabuf(struct hal2_codec *codec, int size, + int count, int cntinfo, int dir) { - int buffers, cntinfo; - hal2_buf_t *buf, *prev; - hal2_codec_t *codec; - - if (is_dac) { - codec = &hal2->dac; - buffers = obuffers; - cntinfo = HPCDMA_XIE | HPCDMA_EOX; - } else { - codec = &hal2->adc; - buffers = ibuffers; - cntinfo = HPCDMA_XIE | H2_BUFFER_SIZE; - } - - DEBUG("allocating %d DMA buffers.\n", buffers); - - buf = (hal2_buf_t*) get_zeroed_page(GFP_KERNEL); - if (!buf) + struct hal2_desc *desc, *dma_addr; + int i; + + DEBUG("allocating %dk DMA buffer.\n", size / 1024); + + codec->buffer = (unsigned char *)__get_free_pages(GFP_KERNEL | GFP_DMA, + get_order(size)); + if (!codec->buffer) + return -ENOMEM; + desc = dma_alloc_coherent(NULL, count * sizeof(struct hal2_desc), + (dma_addr_t *)&dma_addr, GFP_KERNEL); + if (!desc) { + free_pages((unsigned long)codec->buffer, get_order(size)); return -ENOMEM; - codec->head = buf; - codec->tail = buf; - - while (--buffers) { - buf->info.desc.pbuf = PHYSADDR(&buf->data); - buf->info.desc.cntinfo = cntinfo; - buf->info.cnt = 0; - prev = buf; - buf = (hal2_buf_t*) get_zeroed_page(GFP_KERNEL); - if (!buf) { - printk("HAL2: Not enough memory for DMA buffer.\n"); - buf = codec->head; - while (buf) { - prev = buf; - free_page((unsigned long) buf); - buf = prev->info.next; - } - return -ENOMEM; - } - prev->info.next = buf; - prev->info.desc.pnext = PHYSADDR(buf); - /* The PBUS can prolly not read this stuff when it's in - * the cache so we have to flush it back to main memory - */ - dma_cache_wback_inv((unsigned long) prev, PAGE_SIZE); } - buf->info.desc.pbuf = PHYSADDR(&buf->data); - buf->info.desc.cntinfo = cntinfo; - buf->info.cnt = 0; - buf->info.next = codec->head; - buf->info.desc.pnext = PHYSADDR(codec->head); - dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); - + codec->desc = desc; + for (i = 0; i < count; i++) { + desc->desc.pbuf = dma_map_single(NULL, + (void *)(codec->buffer + i * H2_BLOCK_SIZE), + H2_BLOCK_SIZE, dir); + desc->desc.cntinfo = cntinfo; + desc->desc.pnext = (i == count - 1) ? + (u32)dma_addr : (u32)(dma_addr + i + 1); + desc->cnt = 0; + desc++; + } + codec->desc_count = count; + codec->head = codec->tail = 0; return 0; } -#define hal2_free_dac_dmabuf(hal2) hal2_free_dmabuf(hal2, 1) -#define hal2_free_adc_dmabuf(hal2) hal2_free_dmabuf(hal2, 0) -static void hal2_free_dmabuf(hal2_card_t *hal2, int is_dac) +static int hal2_alloc_dac_dmabuf(struct hal2_codec *codec) { - hal2_buf_t *buf, *next; - hal2_codec_t *codec = (is_dac) ? &hal2->dac : &hal2->adc; + return hal2_alloc_dmabuf(codec, H2_DAC_BUFSIZE, + H2_DAC_BUFSIZE / H2_BLOCK_SIZE, + HPCDMA_XIE | HPCDMA_EOX, + DMA_TO_DEVICE); +} - if (!codec->head) - return; - - buf = codec->head->info.next; - codec->head->info.next = NULL; - while (buf) { - next = buf->info.next; - free_page((unsigned long) buf); - buf = next; - } - codec->head = codec->tail = NULL; +static int hal2_alloc_adc_dmabuf(struct hal2_codec *codec) +{ + return hal2_alloc_dmabuf(codec, H2_ADC_BUFSIZE, + H2_ADC_BUFSIZE / H2_BLOCK_SIZE, + HPCDMA_XIE | H2_BLOCK_SIZE, + DMA_TO_DEVICE); +} + +static void hal2_free_dmabuf(struct hal2_codec *codec, int size, int dir) +{ + dma_addr_t dma_addr; + int i; + + dma_addr = codec->desc[codec->desc_count - 1].desc.pnext; + for (i = 0; i < codec->desc_count; i++) + dma_unmap_single(NULL, codec->desc[i].desc.pbuf, + H2_BLOCK_SIZE, dir); + dma_free_coherent(NULL, codec->desc_count * sizeof(struct hal2_desc), + (void *)codec->desc, dma_addr); + free_pages((unsigned long)codec->buffer, get_order(size)); +} + +static void hal2_free_dac_dmabuf(struct hal2_codec *codec) +{ + return hal2_free_dmabuf(codec, H2_DAC_BUFSIZE, DMA_TO_DEVICE); +} + +static void hal2_free_adc_dmabuf(struct hal2_codec *codec) +{ + return hal2_free_dmabuf(codec, H2_ADC_BUFSIZE, DMA_FROM_DEVICE); } /* * Add 'count' bytes to 'buffer' from DMA ring buffers. Return number of * bytes added or -EFAULT if copy_from_user failed. */ -static int hal2_get_buffer(hal2_card_t *hal2, char *buffer, int count) +static int hal2_get_buffer(struct hal2_card *hal2, char *buffer, int count) { unsigned long flags; int size, ret = 0; - hal2_codec_t *adc = &hal2->adc; - - spin_lock_irqsave(&adc->lock, flags); - + unsigned char *buf; + struct hal2_desc *tail; + struct hal2_codec *adc = &hal2->adc; + DEBUG("getting %d bytes ", count); + spin_lock_irqsave(&adc->lock, flags); + tail = &adc->desc[adc->tail]; /* enable DMA stream if there are no data */ - if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && - adc->tail->info.cnt == 0) + if (!tail->cnt && !(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT)) hal2_start_adc(hal2); - - DEBUG("... "); - - while (adc->tail->info.cnt > 0 && count > 0) { - size = min(adc->tail->info.cnt, count); + while (tail->cnt > 0 && count > 0) { + size = min((int)tail->cnt, count); + buf = &adc->buffer[(adc->tail + 1) * H2_BLOCK_SIZE - tail->cnt]; spin_unlock_irqrestore(&adc->lock, flags); - - if (copy_to_user(buffer, &adc->tail->data[H2_BUFFER_SIZE-size], - size)) { + dma_sync_single(NULL, tail->desc.pbuf, size, DMA_FROM_DEVICE); + if (copy_to_user(buffer, buf, size)) { ret = -EFAULT; goto out; } - spin_lock_irqsave(&adc->lock, flags); - - adc->tail->info.cnt -= size; + tail->cnt -= size; /* buffer is empty, update tail pointer */ - if (adc->tail->info.cnt == 0) { - adc->tail->info.desc.cntinfo = HPCDMA_XIE | - H2_BUFFER_SIZE; - dma_cache_wback_inv((unsigned long) adc->tail, - sizeof(struct hpc_dma_desc)); - adc->tail = adc->tail->info.next; + if (tail->cnt == 0) { + tail->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE; + hal2_inc_tail(adc); + tail = &adc->desc[adc->tail]; /* enable DMA stream again if needed */ if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT)) hal2_start_adc(hal2); - } buffer += size; ret += size; @@ -620,9 +665,9 @@ static int hal2_get_buffer(hal2_card_t *hal2, char *buffer, int count) DEBUG("(%d) ", size); } spin_unlock_irqrestore(&adc->lock, flags); -out: +out: DEBUG("\n"); - + return ret; } @@ -630,86 +675,81 @@ out: * Add 'count' bytes from 'buffer' to DMA ring buffers. Return number of * bytes added or -EFAULT if copy_from_user failed. */ -static int hal2_add_buffer(hal2_card_t *hal2, char *buffer, int count) +static int hal2_add_buffer(struct hal2_card *hal2, char *buffer, int count) { unsigned long flags; + unsigned char *buf; int size, ret = 0; - hal2_codec_t *dac = &hal2->dac; - - spin_lock_irqsave(&dac->lock, flags); - + struct hal2_desc *head; + struct hal2_codec *dac = &hal2->dac; + DEBUG("adding %d bytes ", count); - while (dac->head->info.cnt == 0 && count > 0) { - size = min((int)H2_BUFFER_SIZE, count); + spin_lock_irqsave(&dac->lock, flags); + head = &dac->desc[dac->head]; + while (head->cnt == 0 && count > 0) { + size = min((int)H2_BLOCK_SIZE, count); + buf = &dac->buffer[dac->head * H2_BLOCK_SIZE]; spin_unlock_irqrestore(&dac->lock, flags); - - if (copy_from_user(dac->head->data, buffer, size)) { + if (copy_from_user(buf, buffer, size)) { ret = -EFAULT; goto out; } + dma_sync_single(NULL, head->desc.pbuf, size, DMA_TO_DEVICE); spin_lock_irqsave(&dac->lock, flags); - - dac->head->info.desc.cntinfo = size | HPCDMA_XIE; - dac->head->info.cnt = size; - dma_cache_wback_inv((unsigned long) dac->head, - size + PAGE_SIZE - H2_BUFFER_SIZE); + head->desc.cntinfo = size | HPCDMA_XIE; + head->cnt = size; buffer += size; ret += size; count -= size; - dac->head = dac->head->info.next; + hal2_inc_head(dac); + head = &dac->desc[dac->head]; DEBUG("(%d) ", size); } if (!(dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && ret > 0) hal2_start_dac(hal2); - spin_unlock_irqrestore(&dac->lock, flags); -out: +out: DEBUG("\n"); - + return ret; } #define hal2_reset_dac_pointer(hal2) hal2_reset_pointer(hal2, 1) #define hal2_reset_adc_pointer(hal2) hal2_reset_pointer(hal2, 0) -static void hal2_reset_pointer(hal2_card_t *hal2, int is_dac) +static void hal2_reset_pointer(struct hal2_card *hal2, int is_dac) { - hal2_codec_t *codec = (is_dac) ? &hal2->dac : &hal2->adc; - + int i; + struct hal2_codec *codec = (is_dac) ? &hal2->dac : &hal2->adc; + DEBUG("hal2_reset_pointer\n"); - codec->tail = codec->head; - do { - codec->tail->info.desc.cntinfo = HPCDMA_XIE | (is_dac) ? - HPCDMA_EOX : H2_BUFFER_SIZE; - codec->tail->info.cnt = 0; - dma_cache_wback_inv((unsigned long) codec->tail, - sizeof(struct hpc_dma_desc)); - codec->tail = codec->tail->info.next; - } while (codec->tail != codec->head); + for (i = 0; i < codec->desc_count; i++) { + codec->desc[i].cnt = 0; + codec->desc[i].desc.cntinfo = HPCDMA_XIE | (is_dac) ? + HPCDMA_EOX : H2_BLOCK_SIZE; + } + codec->head = codec->tail = 0; } -static int hal2_sync_dac(hal2_card_t *hal2) +static int hal2_sync_dac(struct hal2_card *hal2) { DECLARE_WAITQUEUE(wait, current); - hal2_codec_t *dac = &hal2->dac; + struct hal2_codec *dac = &hal2->dac; int ret = 0; - signed long timeout = 1000 * H2_BUFFER_SIZE * 2 * dac->voices * + unsigned long flags; + signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * dac->voices * HZ / dac->sample_rate / 900; - down(&dac->sem); - while (dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) { add_wait_queue(&dac->dma_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (!schedule_timeout(timeout)) - /* We may get bogus timeout when system is - * heavily loaded */ - if (dac->tail->info.cnt) { - printk("HAL2: timeout...\n"); - ret = -ETIME; - } + schedule_timeout(timeout); + spin_lock_irqsave(&dac->lock, flags); + if (dac->desc[dac->tail].cnt) + ret = -ETIME; + spin_unlock_irqrestore(&dac->lock, flags); if (signal_pending(current)) ret = -ERESTARTSYS; if (ret) { @@ -719,17 +759,15 @@ static int hal2_sync_dac(hal2_card_t *hal2) remove_wait_queue(&dac->dma_wait, &wait); } - up(&dac->sem); - return ret; } -static int hal2_write_mixer(hal2_card_t *hal2, int index, int vol) +static int hal2_write_mixer(struct hal2_card *hal2, int index, int vol) { - unsigned int l, r; + unsigned int l, r, tmp; DEBUG_MIX("mixer %d write\n", index); - + if (index >= SOUND_MIXER_NRDEVICES || !mixtable[index].avail) return -EINVAL; @@ -739,23 +777,22 @@ static int hal2_write_mixer(hal2_card_t *hal2, int index, int vol) l = vol & 0xff; if (l > 100) l = 100; - + hal2->mixer.volume[mixtable[index].idx] = l | (r << 8); switch (mixtable[index].idx) { - case H2_MIX_OUTPUT_ATT: { + case H2_MIX_OUTPUT_ATT: DEBUG_MIX("output attenuator %d,%d\n", l, r); if (r | l) { - unsigned int tmp = hal2_i_look32(hal2, H2I_DAC_C2); - + tmp = hal2_i_look32(hal2, H2I_DAC_C2); tmp &= ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE); /* Attenuator has five bits */ - l = (31 * (100 - l) / 99); - r = (31 * (100 - r) / 99); - + l = 31 * (100 - l) / 99; + r = 31 * (100 - r) / 99; + DEBUG_MIX("left: %d, right %d\n", l, r); tmp |= (l << H2I_C2_L_ATT_SHIFT) & H2I_C2_L_ATT_M; @@ -763,30 +800,80 @@ static int hal2_write_mixer(hal2_card_t *hal2, int index, int vol) hal2_i_write32(hal2, H2I_DAC_C2, tmp); } else hal2_i_setbit32(hal2, H2I_DAC_C2, H2I_C2_MUTE); + break; + case H2_MIX_INPUT_GAIN: + + DEBUG_MIX("input gain %d,%d\n", l, r); + + tmp = hal2_i_look32(hal2, H2I_ADC_C2); + tmp &= ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M); + + /* Gain control has four bits */ + l = 16 * l / 100; + r = 16 * r / 100; + + DEBUG_MIX("left: %d, right %d\n", l, r); + + tmp |= (l << H2I_C2_L_GAIN_SHIFT) & H2I_C2_L_GAIN_M; + tmp |= (r << H2I_C2_R_GAIN_SHIFT) & H2I_C2_R_GAIN_M; + hal2_i_write32(hal2, H2I_ADC_C2, tmp); + + break; } - case H2_MIX_INPUT_GAIN: { - /* TODO */ - } - } + return 0; } -static void hal2_init_mixer(hal2_card_t *hal2) +static void hal2_init_mixer(struct hal2_card *hal2) { int i; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) - hal2_write_mixer(hal2, i, 100 | (100 << 8)); - + if (mixtable[i].avail) + hal2->mixer.volume[mixtable[i].idx] = 100 | (100 << 8); + + /* disable attenuator */ + hal2_i_write32(hal2, H2I_DAC_C2, 0); + /* set max input gain */ + hal2_i_write32(hal2, H2I_ADC_C2, H2I_C2_MUTE | + (H2I_C2_L_GAIN_M << H2I_C2_L_GAIN_SHIFT) | + (H2I_C2_R_GAIN_M << H2I_C2_R_GAIN_SHIFT)); + /* set max volume */ + hal2->mixer.master = 0xff; + hal2->vol_regs->left = 0xff; + hal2->vol_regs->right = 0xff; } -static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, +/* + * XXX: later i'll implement mixer for main volume which will be disabled + * by default. enabling it users will be allowed to have master volume level + * control on panel in their favourite X desktop + */ +static void hal2_volume_control(int direction) +{ + unsigned int master = hal2_card[0]->mixer.master; + struct hal2_vol_regs *vol = hal2_card[0]->vol_regs; + + /* volume up */ + if (direction > 0 && master < 0xff) + master++; + /* volume down */ + else if (direction < 0 && master > 0) + master--; + /* TODO: mute/unmute */ + vol->left = master; + vol->right = master; + hal2_card[0]->mixer.master = master; +} + +static int hal2_mixer_ioctl(struct hal2_card *hal2, unsigned int cmd, unsigned long arg) { int val; if (cmd == SOUND_MIXER_INFO) { mixer_info info; + memset(&info, 0, sizeof(info)); strlcpy(info.id, hal2str, sizeof(info.id)); strlcpy(info.name, hal2str, sizeof(info.name)); @@ -797,6 +884,7 @@ static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, } if (cmd == SOUND_OLD_MIXER_INFO) { _old_mixer_info info; + memset(&info, 0, sizeof(info)); strlcpy(info.id, hal2str, sizeof(info.id)); strlcpy(info.name, hal2str, sizeof(info.name)); @@ -820,7 +908,7 @@ static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, case SOUND_MIXER_DEVMASK: case SOUND_MIXER_STEREODEVS: { int i; - + for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) if (mixtable[i].avail) val |= 1 << i; @@ -836,7 +924,7 @@ static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, /* Read a specific mixer */ default: { int i = _IOC_NR(cmd); - + if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail) return -EINVAL; val = hal2->mixer.volume[mixtable[i].idx]; @@ -845,10 +933,10 @@ static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, } return put_user(val, (int *)arg); } - + if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ)) return -EINVAL; - + hal2->mixer.modcnt++; if (get_user(val, (int *)arg)) @@ -867,7 +955,7 @@ static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, static int hal2_open_mixdev(struct inode *inode, struct file *file) { - hal2_card_t *hal2 = hal2_mixer_find_card(iminor(inode)); + struct hal2_card *hal2 = hal2_mixer_find_card(iminor(inode)); if (hal2) { file->private_data = hal2; @@ -884,31 +972,30 @@ static int hal2_release_mixdev(struct inode *inode, struct file *file) static int hal2_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - return hal2_mixer_ioctl((hal2_card_t *)file->private_data, cmd, arg); + return hal2_mixer_ioctl((struct hal2_card *)file->private_data, cmd, arg); } - static int hal2_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int val; - hal2_card_t *hal2 = (hal2_card_t *) file->private_data; + struct hal2_card *hal2 = (struct hal2_card *) file->private_data; switch (cmd) { case OSS_GETVERSION: return put_user(SOUND_VERSION, (int *)arg); - + case SNDCTL_DSP_SYNC: if (file->f_mode & FMODE_WRITE) return hal2_sync_dac(hal2); return 0; - + case SNDCTL_DSP_SETDUPLEX: return 0; case SNDCTL_DSP_GETCAPS: return put_user(DSP_CAP_DUPLEX | DSP_CAP_MULTI, (int *)arg); - + case SNDCTL_DSP_RESET: if (file->f_mode & FMODE_READ) { hal2_stop_adc(hal2); @@ -936,7 +1023,7 @@ static int hal2_ioctl(struct inode *inode, struct file *file, hal2_set_dac_rate(hal2); } return put_user(val, (int *)arg); - + case SNDCTL_DSP_STEREO: if (get_user(val, (int *)arg)) return -EFAULT; @@ -973,10 +1060,10 @@ static int hal2_ioctl(struct inode *inode, struct file *file, if (file->f_mode & FMODE_WRITE) val = hal2->dac.voices; return put_user(val, (int *)arg); - + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ return put_user(H2_SUPPORTED_FORMATS, (int *)arg); - + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ if (get_user(val, (int *)arg)) return -EFAULT; @@ -1001,68 +1088,61 @@ static int hal2_ioctl(struct inode *inode, struct file *file, val = hal2->dac.format; } return put_user(val, (int *)arg); - + case SNDCTL_DSP_POST: return 0; case SNDCTL_DSP_GETOSPACE: { - unsigned long flags; audio_buf_info info; - hal2_buf_t *buf; - hal2_codec_t *dac = &hal2->dac; - + int i; + unsigned long flags; + struct hal2_codec *dac = &hal2->dac; + if (!(file->f_mode & FMODE_WRITE)) return -EINVAL; - - spin_lock_irqsave(&dac->lock, flags); info.fragments = 0; - buf = dac->head; - while (buf->info.cnt == 0 && buf != dac->tail) { - info.fragments++; - buf = buf->info.next; - } + spin_lock_irqsave(&dac->lock, flags); + for (i = 0; i < dac->desc_count; i++) + if (dac->desc[i].cnt == 0) + info.fragments++; spin_unlock_irqrestore(&dac->lock, flags); - - info.fragstotal = obuffers; - info.fragsize = H2_BUFFER_SIZE; + info.fragstotal = dac->desc_count; + info.fragsize = H2_BLOCK_SIZE; info.bytes = info.fragsize * info.fragments; return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0; } - + case SNDCTL_DSP_GETISPACE: { - unsigned long flags; audio_buf_info info; - hal2_buf_t *buf; - hal2_codec_t *adc = &hal2->adc; - + int i; + unsigned long flags; + struct hal2_codec *adc = &hal2->adc; + if (!(file->f_mode & FMODE_READ)) return -EINVAL; - - spin_lock_irqsave(&adc->lock, flags); info.fragments = 0; info.bytes = 0; - buf = adc->tail; - while (buf->info.cnt > 0 && buf != adc->head) { - info.fragments++; - info.bytes += buf->info.cnt; - buf = buf->info.next; - } + spin_lock_irqsave(&adc->lock, flags); + for (i = 0; i < adc->desc_count; i++) + if (adc->desc[i].cnt > 0) { + info.fragments++; + info.bytes += adc->desc[i].cnt; + } spin_unlock_irqrestore(&adc->lock, flags); + info.fragstotal = adc->desc_count; + info.fragsize = H2_BLOCK_SIZE; - info.fragstotal = ibuffers; - info.fragsize = H2_BUFFER_SIZE; - return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0; } case SNDCTL_DSP_NONBLOCK: file->f_flags |= O_NONBLOCK; return 0; - + case SNDCTL_DSP_GETBLKSIZE: - return put_user(H2_BUFFER_SIZE, (int *)arg); - + return put_user(H2_BLOCK_SIZE, (int *)arg); + case SNDCTL_DSP_SETFRAGMENT: return 0; @@ -1083,10 +1163,9 @@ static int hal2_ioctl(struct inode *inode, struct file *file, return put_user(val, (int *)arg); case SOUND_PCM_READ_BITS: - val = 16; - return put_user(val, (int *)arg); + return put_user(16, (int *)arg); } - + return hal2_mixer_ioctl(hal2, cmd, arg); } @@ -1094,27 +1173,27 @@ static ssize_t hal2_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { ssize_t err; - hal2_card_t *hal2 = (hal2_card_t *) file->private_data; - hal2_codec_t *adc = &hal2->adc; + struct hal2_card *hal2 = (struct hal2_card *) file->private_data; + struct hal2_codec *adc = &hal2->adc; - if (count == 0) + if (!count) return 0; if (ppos != &file->f_pos) return -ESPIPE; - - down(&adc->sem); - + if (down_interruptible(&adc->sem)) + return -EINTR; if (file->f_flags & O_NONBLOCK) { err = hal2_get_buffer(hal2, buffer, count); err = err == 0 ? -EAGAIN : err; } else { do { /* ~10% longer */ - signed long timeout = 1000 * H2_BUFFER_SIZE * + signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * adc->voices * HZ / adc->sample_rate / 900; + unsigned long flags; DECLARE_WAITQUEUE(wait, current); ssize_t cnt = 0; - + err = hal2_get_buffer(hal2, buffer, count); if (err > 0) { count -= err; @@ -1125,28 +1204,23 @@ static ssize_t hal2_read(struct file *file, char *buffer, if (count > 0 && err >= 0) { add_wait_queue(&adc->dma_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - /* Well, it is possible, that interrupt already - * arrived. Hmm, shit happens, we have one more - * buffer filled ;) */ - if (!schedule_timeout(timeout)) - /* We may get bogus timeout when system - * is heavily loaded */ - if (!adc->tail->info.cnt) { - printk("HAL2: timeout...\n"); - hal2_stop_adc(hal2); - hal2_reset_adc_pointer(hal2); - err = -EAGAIN; - } + schedule_timeout(timeout); + spin_lock_irqsave(&adc->lock, flags); + if (!adc->desc[adc->tail].cnt) + err = -EAGAIN; + spin_unlock_irqrestore(&adc->lock, flags); if (signal_pending(current)) err = -ERESTARTSYS; remove_wait_queue(&adc->dma_wait, &wait); + if (err < 0) { + hal2_stop_adc(hal2); + hal2_reset_adc_pointer(hal2); + } } } while (count > 0 && err >= 0); - } - up(&adc->sem); - + return err; } @@ -1155,27 +1229,27 @@ static ssize_t hal2_write(struct file *file, const char *buffer, { ssize_t err; char *buf = (char*) buffer; - hal2_card_t *hal2 = (hal2_card_t *) file->private_data; - hal2_codec_t *dac = &hal2->dac; + struct hal2_card *hal2 = (struct hal2_card *) file->private_data; + struct hal2_codec *dac = &hal2->dac; - if (count == 0) + if (!count) return 0; if (ppos != &file->f_pos) return -ESPIPE; - - down(&dac->sem); - + if (down_interruptible(&dac->sem)) + return -EINTR; if (file->f_flags & O_NONBLOCK) { err = hal2_add_buffer(hal2, buf, count); err = err == 0 ? -EAGAIN : err; } else { do { /* ~10% longer */ - signed long timeout = 1000 * H2_BUFFER_SIZE * + signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * dac->voices * HZ / dac->sample_rate / 900; + unsigned long flags; DECLARE_WAITQUEUE(wait, current); ssize_t cnt = 0; - + err = hal2_add_buffer(hal2, buf, count); if (err > 0) { count -= err; @@ -1186,25 +1260,21 @@ static ssize_t hal2_write(struct file *file, const char *buffer, if (count > 0 && err >= 0) { add_wait_queue(&dac->dma_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - /* Well, it is possible, that interrupt already - * arrived. Hmm, shit happens, we have one more - * buffer free ;) */ - if (!schedule_timeout(timeout)) - /* We may get bogus timeout when system - * is heavily loaded */ - if (dac->head->info.cnt) { - printk("HAL2: timeout...\n"); - hal2_stop_dac(hal2); - hal2_reset_dac_pointer(hal2); - err = -EAGAIN; - } + schedule_timeout(timeout); + spin_lock_irqsave(&dac->lock, flags); + if (dac->desc[dac->head].cnt) + err = -EAGAIN; + spin_unlock_irqrestore(&dac->lock, flags); if (signal_pending(current)) err = -ERESTARTSYS; remove_wait_queue(&dac->dma_wait, &wait); + if (err < 0) { + hal2_stop_dac(hal2); + hal2_reset_dac_pointer(hal2); + } } } while (count > 0 && err >= 0); } - up(&dac->sem); return err; @@ -1214,99 +1284,96 @@ static unsigned int hal2_poll(struct file *file, struct poll_table_struct *wait) { unsigned long flags; unsigned int mask = 0; - hal2_card_t *hal2 = (hal2_card_t *) file->private_data; + struct hal2_card *hal2 = (struct hal2_card *) file->private_data; if (file->f_mode & FMODE_READ) { - hal2_codec_t *adc = &hal2->adc; - - poll_wait(file, &hal2->adc.dma_wait, wait); + struct hal2_codec *adc = &hal2->adc; + + poll_wait(file, &adc->dma_wait, wait); spin_lock_irqsave(&adc->lock, flags); - if (adc->tail->info.cnt > 0) + if (adc->desc[adc->tail].cnt > 0) mask |= POLLIN; spin_unlock_irqrestore(&adc->lock, flags); } - + if (file->f_mode & FMODE_WRITE) { - hal2_codec_t *dac = &hal2->dac; - + struct hal2_codec *dac = &hal2->dac; + poll_wait(file, &dac->dma_wait, wait); spin_lock_irqsave(&dac->lock, flags); - if (dac->head->info.cnt == 0) + if (dac->desc[dac->head].cnt == 0) mask |= POLLOUT; spin_unlock_irqrestore(&dac->lock, flags); } - + return mask; } static int hal2_open(struct inode *inode, struct file *file) { int err; - hal2_card_t *hal2 = hal2_dsp_find_card(iminor(inode)); + struct hal2_card *hal2 = hal2_dsp_find_card(iminor(inode)); - DEBUG("opening audio device.\n"); - - if (!hal2) { - printk("HAL2: Whee?! Open door and go away!\n"); + if (!hal2) return -ENODEV; - } file->private_data = hal2; - if (file->f_mode & FMODE_READ) { - if (hal2->adc.usecount) + struct hal2_codec *adc = &hal2->adc; + + if (adc->usecount) return -EBUSY; - /* OSS spec wanted us to use 8 bit, 8 kHz mono by default, * but HAL2 can't do 8bit audio */ - hal2->adc.format = AFMT_S16_BE; - hal2->adc.voices = 1; - hal2->adc.sample_rate = hal2_compute_rate(&hal2->adc, 8000); + adc->format = AFMT_S16_BE; + adc->voices = 1; + adc->sample_rate = hal2_compute_rate(adc, 8000); hal2_set_adc_rate(hal2); - - /* alloc DMA buffers */ - err = hal2_alloc_adc_dmabuf(hal2); + err = hal2_alloc_adc_dmabuf(adc); if (err) return err; hal2_setup_adc(hal2); - - hal2->adc.usecount++; + adc->usecount++; } - if (file->f_mode & FMODE_WRITE) { - if (hal2->dac.usecount) - return -EBUSY; + struct hal2_codec *dac = &hal2->dac; - hal2->dac.format = AFMT_S16_BE; - hal2->dac.voices = 1; - hal2->dac.sample_rate = hal2_compute_rate(&hal2->dac, 8000); + if (dac->usecount) + return -EBUSY; + dac->format = AFMT_S16_BE; + dac->voices = 1; + dac->sample_rate = hal2_compute_rate(dac, 8000); hal2_set_dac_rate(hal2); - - /* alloc DMA buffers */ - err = hal2_alloc_dac_dmabuf(hal2); + err = hal2_alloc_dac_dmabuf(dac); if (err) return err; hal2_setup_dac(hal2); - - hal2->dac.usecount++; + dac->usecount++; } - + return 0; } static int hal2_release(struct inode *inode, struct file *file) { - hal2_card_t *hal2 = (hal2_card_t *) file->private_data; + struct hal2_card *hal2 = (struct hal2_card *) file->private_data; if (file->f_mode & FMODE_READ) { + struct hal2_codec *adc = &hal2->adc; + + down(&adc->sem); hal2_stop_adc(hal2); - hal2_free_adc_dmabuf(hal2); - hal2->adc.usecount--; + hal2_free_adc_dmabuf(adc); + adc->usecount--; + up(&adc->sem); } - if (file->f_mode & FMODE_WRITE) { + struct hal2_codec *dac = &hal2->dac; + + down(&dac->sem); hal2_sync_dac(hal2); - hal2_free_dac_dmabuf(hal2); - hal2->dac.usecount--; + hal2_free_dac_dmabuf(dac); + dac->usecount--; + up(&dac->sem); } return 0; @@ -1331,159 +1398,155 @@ static struct file_operations hal2_mixer_fops = { .release = hal2_release_mixdev, }; -static int hal2_request_irq(hal2_card_t *hal2, int irq) -{ - unsigned long flags; - int ret = 0; - - save_and_cli(flags); - if (request_irq(irq, hal2_interrupt, SA_SHIRQ, hal2str, hal2)) { - printk(KERN_ERR "HAL2: Can't get irq %d\n", irq); - ret = -EAGAIN; - } - restore_flags(flags); - return ret; -} - -static int hal2_alloc_resources(hal2_card_t *hal2, struct hpc3_regs *hpc3) -{ - hal2_pbus_t *pbus; - - pbus = &hal2->dac.pbus; - pbus->pbusnr = 0; - pbus->pbus = &hpc3->pbdma[pbus->pbusnr]; - /* The spec says that we should write 0x08248844 but that's WRONG. HAL2 - * does 8 bit DMA, not 16 bit even if it generates 16 bit audio. */ - hpc3->pbus_dmacfgs[pbus->pbusnr][0] = 0x08208844; /* Magic :-) */ - - pbus = &hal2->adc.pbus; - pbus->pbusnr = 1; - pbus->pbus = &hpc3->pbdma[pbus->pbusnr]; - hpc3->pbus_dmacfgs[pbus->pbusnr][0] = 0x08208844; /* Magic :-) */ - - return hal2_request_irq(hal2, SGI_HPCDMA_IRQ); -} - -static void hal2_init_codec(hal2_codec_t *codec) +static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3, + int index) { + codec->pbus.pbusnr = index; + codec->pbus.pbus = &hpc3->pbdma[index]; init_waitqueue_head(&codec->dma_wait); init_MUTEX(&codec->sem); spin_lock_init(&codec->lock); } -static void hal2_free_resources(hal2_card_t *hal2) -{ - free_irq(SGI_HPCDMA_IRQ, hal2); -} - -static int hal2_detect(hal2_card_t *hal2) +static int hal2_detect(struct hal2_card *hal2) { unsigned short board, major, minor; unsigned short rev; /* reset HAL2 */ hal2_isr_write(hal2, 0); - /* release reset */ hal2_isr_write(hal2, H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N); hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE); - - if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT) { - DEBUG("HAL2: no device detected, rev: 0x%04hx\n", rev); + if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT) return -ENODEV; - } board = (rev & H2_REV_BOARD_M) >> 12; major = (rev & H2_REV_MAJOR_CHIP_M) >> 4; minor = (rev & H2_REV_MINOR_CHIP_M); - printk("SGI HAL2 Processor revision %i.%i.%i detected\n", + printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n", board, major, minor); - if (board != 4 || major != 1 || minor != 0) - printk( "Other revision than 4.1.0 detected. " - "Your card is probably unsupported\n"); - return 0; } -static int hal2_init_card(hal2_card_t **phal2, struct hpc3_regs *hpc3, - unsigned long hpc3_base) +static int hal2_init_card(struct hal2_card **phal2, struct hpc3_regs *hpc3) { int ret = 0; - hal2_card_t *hal2; - - hal2 = (hal2_card_t *) kmalloc(sizeof(hal2_card_t), GFP_KERNEL); + struct hal2_card *hal2; + + hal2 = (struct hal2_card *) kmalloc(sizeof(struct hal2_card), GFP_KERNEL); if (!hal2) return -ENOMEM; - memset(hal2, 0, sizeof(hal2_card_t)); + memset(hal2, 0, sizeof(struct hal2_card)); - hal2->ctl_regs = (hal2_ctl_regs_t *) KSEG1ADDR(hpc3_base + H2_CTL_PIO); - hal2->aes_regs = (hal2_aes_regs_t *) KSEG1ADDR(hpc3_base + H2_AES_PIO); - hal2->vol_regs = (hal2_vol_regs_t *) KSEG1ADDR(hpc3_base + H2_VOL_PIO); - hal2->syn_regs = (hal2_syn_regs_t *) KSEG1ADDR(hpc3_base + H2_SYN_PIO); + hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0]; + hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1]; + hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2]; + hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3]; if (hal2_detect(hal2) < 0) { - printk("HAL2 audio processor not found\n"); ret = -ENODEV; - goto fail1; + goto free_card; } - hal2_init_codec(&hal2->dac); - hal2_init_codec(&hal2->adc); + hal2_init_codec(&hal2->dac, hpc3, 0); + hal2_init_codec(&hal2->adc, hpc3, 1); - ret = hal2_alloc_resources(hal2, hpc3); - if (ret) - goto fail1; - - hal2_init_mixer(hal2); + /* + * All DMA channel interfaces in HAL2 are designed to operate with + * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles + * in D5. HAL2 is a 16-bit device which can accept both big and little + * endian format. It assumes that even address bytes are on high + * portion of PBUS (15:8) and assumes that HPC3 is programmed to + * accept a live (unsynchronized) version of P_DREQ_N from HAL2. + */ +#define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \ + (2 << HPC3_DMACFG_D4R_SHIFT) | \ + (2 << HPC3_DMACFG_D5R_SHIFT) | \ + (0 << HPC3_DMACFG_D3W_SHIFT) | \ + (2 << HPC3_DMACFG_D4W_SHIFT) | \ + (2 << HPC3_DMACFG_D5W_SHIFT) | \ + HPC3_DMACFG_DS16 | \ + HPC3_DMACFG_EVENHI | \ + HPC3_DMACFG_RTIME | \ + (8 << HPC3_DMACFG_BURST_SHIFT) | \ + HPC3_DMACFG_DRQLIVE) + /* + * Ignore what's mentioned in the specification and write value which + * works in The Real World (TM) + */ + hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844; + hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844; + + if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, SA_SHIRQ, + hal2str, hal2)) { + printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ); + ret = -EAGAIN; + goto free_card; + } hal2->dev_dsp = register_sound_dsp(&hal2_audio_fops, -1); if (hal2->dev_dsp < 0) { ret = hal2->dev_dsp; - goto fail2; + goto free_irq; } hal2->dev_mixer = register_sound_mixer(&hal2_mixer_fops, -1); if (hal2->dev_mixer < 0) { ret = hal2->dev_mixer; - goto fail3; + goto unregister_dsp; } - + + hal2_init_mixer(hal2); + *phal2 = hal2; return 0; -fail3: +unregister_dsp: unregister_sound_dsp(hal2->dev_dsp); -fail2: - hal2_free_resources(hal2); -fail1: +free_irq: + free_irq(SGI_HPCDMA_IRQ, hal2); +free_card: kfree(hal2); - + return ret; } +extern void (*indy_volume_button)(int); + /* - * We are assuming only one HAL2 card. If you ever meet machine with more than - * one, tell immediately about it to someone. Preferably to me. --ladis + * Assuming only one HAL2 card. Mail me if you ever meet machine with + * more than one. */ static int __init init_hal2(void) { - int i; + int i, error; for (i = 0; i < MAXCARDS; i++) hal2_card[i] = NULL; - return hal2_init_card(&hal2_card[0], hpc3c0, HPC3_CHIP0_PBASE); + error = hal2_init_card(&hal2_card[0], hpc3c0); + + /* let Indy's volume buttons work */ + if (!error && !ip22_is_fullhouse()) + indy_volume_button = hal2_volume_control; + + return error; + } static void __exit exit_hal2(void) { int i; + + /* unregister volume butons callback function */ + indy_volume_button = NULL; for (i = 0; i < MAXCARDS; i++) if (hal2_card[i]) { - hal2_free_resources(hal2_card[i]); + free_irq(SGI_HPCDMA_IRQ, hal2_card[i]); unregister_sound_dsp(hal2_card[i]->dev_dsp); unregister_sound_mixer(hal2_card[i]->dev_mixer); kfree(hal2_card[i]); diff --git a/sound/oss/hal2.h b/sound/oss/hal2.h index 256be453d39b..2bd3b52d8a37 100644 --- a/sound/oss/hal2.h +++ b/sound/oss/hal2.h @@ -4,7 +4,7 @@ /* * Driver for HAL2 sound processors * Copyright (c) 1999 Ulf Carlsson - * Copyright (c) 2001 Ladislav Michl + * Copyright (c) 2001, 2002, 2003 Ladislav Michl * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,16 +22,10 @@ */ #include -#include +#include #include #include -#define H2_HAL2_BASE 0x58000 -#define H2_CTL_PIO (H2_HAL2_BASE + 0 * 0x400) -#define H2_AES_PIO (H2_HAL2_BASE + 1 * 0x400) -#define H2_VOL_PIO (H2_HAL2_BASE + 2 * 0x400) -#define H2_SYN_PIO (H2_HAL2_BASE + 3 * 0x400) - /* Indirect status register */ #define H2_ISR_TSTATUS 0x01 /* RO: transaction status 1=busy */ @@ -207,122 +201,48 @@ #define H2I_UTIME_2_LD 0xffff /* seconds, LSB's */ #define H2I_UTIME_3_LD 0xffff /* seconds, MSB's */ -typedef volatile u32 hal2_reg_t; - -typedef struct stru_hal2_ctl_regs hal2_ctl_regs_t; -struct stru_hal2_ctl_regs { - hal2_reg_t _unused0[4]; - hal2_reg_t isr; /* 0x10 Status Register */ - hal2_reg_t _unused1[3]; - hal2_reg_t rev; /* 0x20 Revision Register */ - hal2_reg_t _unused2[3]; - hal2_reg_t iar; /* 0x30 Indirect Address Register */ - hal2_reg_t _unused3[3]; - hal2_reg_t idr0; /* 0x40 Indirect Data Register 0 */ - hal2_reg_t _unused4[3]; - hal2_reg_t idr1; /* 0x50 Indirect Data Register 1 */ - hal2_reg_t _unused5[3]; - hal2_reg_t idr2; /* 0x60 Indirect Data Register 2 */ - hal2_reg_t _unused6[3]; - hal2_reg_t idr3; /* 0x70 Indirect Data Register 3 */ +struct hal2_ctl_regs { + u32 _unused0[4]; + volatile u32 isr; /* 0x10 Status Register */ + u32 _unused1[3]; + volatile u32 rev; /* 0x20 Revision Register */ + u32 _unused2[3]; + volatile u32 iar; /* 0x30 Indirect Address Register */ + u32 _unused3[3]; + volatile u32 idr0; /* 0x40 Indirect Data Register 0 */ + u32 _unused4[3]; + volatile u32 idr1; /* 0x50 Indirect Data Register 1 */ + u32 _unused5[3]; + volatile u32 idr2; /* 0x60 Indirect Data Register 2 */ + u32 _unused6[3]; + volatile u32 idr3; /* 0x70 Indirect Data Register 3 */ }; -typedef struct stru_hal2_aes_regs hal2_aes_regs_t; -struct stru_hal2_aes_regs { - hal2_reg_t rx_stat[2]; /* Status registers */ - hal2_reg_t rx_cr[2]; /* Control registers */ - hal2_reg_t rx_ud[4]; /* User data window */ - hal2_reg_t rx_st[24]; /* Channel status data */ +struct hal2_aes_regs { + volatile u32 rx_stat[2]; /* Status registers */ + volatile u32 rx_cr[2]; /* Control registers */ + volatile u32 rx_ud[4]; /* User data window */ + volatile u32 rx_st[24]; /* Channel status data */ - hal2_reg_t tx_stat[1]; /* Status register */ - hal2_reg_t tx_cr[3]; /* Control registers */ - hal2_reg_t tx_ud[4]; /* User data window */ - hal2_reg_t tx_st[24]; /* Channel status data */ -}; - -typedef struct stru_hal2_vol_regs hal2_vol_regs_t; -struct stru_hal2_vol_regs { - hal2_reg_t right; /* 0x00 Right volume */ - hal2_reg_t left; /* 0x04 Left volume */ -}; - -typedef struct stru_hal2_syn_regs hal2_syn_regs_t; -struct stru_hal2_syn_regs { - hal2_reg_t _unused0[2]; - hal2_reg_t page; /* DOC Page register */ - hal2_reg_t regsel; /* DOC Register selection */ - hal2_reg_t dlow; /* DOC Data low */ - hal2_reg_t dhigh; /* DOC Data high */ - hal2_reg_t irq; /* IRQ Status */ - hal2_reg_t dram; /* DRAM Access */ -}; - -/* HAL2 specific structures */ - -typedef struct stru_hal2_pbus hal2_pbus_t; -struct stru_hal2_pbus { - struct hpc3_pbus_dmacregs *pbus; - int pbusnr; - unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */ -}; - -typedef struct stru_hal2_binfo hal2_binfo_t; -typedef struct stru_hal2_buffer hal2_buf_t; -struct stru_hal2_binfo { - volatile struct hpc_dma_desc desc; - hal2_buf_t *next; /* pointer to next buffer */ - int cnt; /* bytes in buffer */ -}; -#define H2_BUFFER_SIZE (PAGE_SIZE - \ - ((sizeof(hal2_binfo_t) - 1) / 8 + 1) * 8) -struct stru_hal2_buffer { - hal2_binfo_t info; - char data[H2_BUFFER_SIZE] __attribute__((aligned(8))); + volatile u32 tx_stat[1]; /* Status register */ + volatile u32 tx_cr[3]; /* Control registers */ + volatile u32 tx_ud[4]; /* User data window */ + volatile u32 tx_st[24]; /* Channel status data */ }; -typedef struct stru_hal2_codec hal2_codec_t; -struct stru_hal2_codec { - hal2_buf_t *head; - hal2_buf_t *tail; - hal2_pbus_t pbus; - unsigned int format; /* Audio data format */ - int voices; /* mono/stereo */ - unsigned int sample_rate; - unsigned int master; /* Master frequency */ - unsigned short mod; /* MOD value */ - unsigned short inc; /* INC value */ - - wait_queue_head_t dma_wait; - spinlock_t lock; - struct semaphore sem; - - int usecount; /* recording and playback are - * independent */ +struct hal2_vol_regs { + volatile u32 right; /* Right volume */ + volatile u32 left; /* Left volume */ }; -#define H2_MIX_OUTPUT_ATT 0 -#define H2_MIX_INPUT_GAIN 1 -#define H2_MIXERS 2 -typedef struct stru_hal2_mixer hal2_mixer_t; -struct stru_hal2_mixer { - int modcnt; - unsigned int volume[H2_MIXERS]; -}; - -typedef struct stru_hal2_card hal2_card_t; -struct stru_hal2_card { - int dev_dsp; /* audio device */ - int dev_mixer; /* mixer device */ - int dev_midi; /* midi device */ - - hal2_ctl_regs_t *ctl_regs; /* HAL2 ctl registers */ - hal2_aes_regs_t *aes_regs; /* HAL2 vol registers */ - hal2_vol_regs_t *vol_regs; /* HAL2 aes registers */ - hal2_syn_regs_t *syn_regs; /* HAL2 syn registers */ - - hal2_codec_t dac; - hal2_codec_t adc; - hal2_mixer_t mixer; +struct hal2_syn_regs { + u32 _unused0[2]; + volatile u32 page; /* DOC Page register */ + volatile u32 regsel; /* DOC Register selection */ + volatile u32 dlow; /* DOC Data low */ + volatile u32 dhigh; /* DOC Data high */ + volatile u32 irq; /* IRQ Status */ + volatile u32 dram; /* DRAM Access */ }; -#endif /* __HAL2_H */ +#endif /* __HAL2_H */ -- cgit v1.2.3 From d07cdd16e934e88f737ca2322c8ce8f1733c8e07 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 18:56:30 -0700 Subject: [PATCH] Dell laptop lockup fix for ALSA From: Alan Cox OSS avoids the Dell lockup by not hitting the problem register (which apparently breaks resume on a Sony laptop). ALSA keeps a flag and uses pci subvendor info to clear it for problem Dell laptops. Unfortunately there is at least one other Dell laptop which is affected. This adds its sub id's [Patch from Dan Williams @ Red Hat slightly reformatted by me] Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/pci/nm256/nm256.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index ee3b246bbef0..57b7584a7d3b 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -1509,6 +1509,10 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, /* this workaround will cause lock-up after suspend/resume on Sony PCG-F305 */ chip->latitude_workaround = 0; } + if (subsystem_vendor == 0x1028 && subsystem_device == 0x0080) { + /* this workaround will cause lock-up after suspend/resume on a Dell laptop */ + chip->latitude_workaround = 0; + } snd_nm256_init_chip(chip); -- cgit v1.2.3 From fb9c90ba9f4166c3b9a51b5728db69968852b231 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:19:53 -0700 Subject: [PATCH] MIPS Update From: Ralf Baechle MIPS update: - Further conversion of MIPS kernel configuration to reverse dependencies. - Support for the PMC-Sierra Yosemite evaluation board. - Merge arch/mips/mm-32 and arch/mips/mm-32 into arch/mips/mm. - Partial support for the R8000 now that I finally have clearance for the documentation previously covered by NDA. - Make distclean fixes. - Regenerate default configuration files against latest Kconfig files. - Fix handling of data bus errors in modules. - Make R4000 bug probing more bullet proof. - Rewrite semaphore code folloing the PPC implementation to no longer manipulate 2 32-bit quantities atomically using 64-bit instructions. Occasionally this did cause problems due to struct semaphore not having sufficient alignment. - Make sys_pipe() code bullet proof against gcc 3.5 over-optimization. - Fix possibly exploitable bug in IRIX compatibility statvfs(2). - Make sched_clock() an outline function. - Support for the MIPS 24K and 25K processors. - Make functions static that aren't needed anywhere else. - Factor out some more generic MIPS SMP code. - Factor out common part of the GT-64240 code. - Ocelot C now uses the generic MV-64340 interrupt handler code. - Factor out common board support code - More cleanup and bug fixes for the NEC VR41xx code. - Start cleanup of hazard handling as required for MIPS32/64 V2 processors. - Enforce minimal kmalloc alignment of 8 byte so 64-bit registers can be stored into fields without exceptions. - Speeling and warning fixes. Signed-off-by: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/Kconfig | 78 +- arch/mips/Makefile | 9 +- arch/mips/boot/Makefile | 2 +- arch/mips/configs/atlas_defconfig | 9 +- arch/mips/configs/bosporus_defconfig | 7 +- arch/mips/configs/capcella_defconfig | 12 +- arch/mips/configs/cobalt_defconfig | 8 +- arch/mips/configs/db1000_defconfig | 8 +- arch/mips/configs/db1100_defconfig | 7 +- arch/mips/configs/db1500_defconfig | 10 +- arch/mips/configs/ddb5476_defconfig | 9 +- arch/mips/configs/ddb5477_defconfig | 7 +- arch/mips/configs/decstation_defconfig | 4 +- arch/mips/configs/e55_defconfig | 6 +- arch/mips/configs/eagle_defconfig | 11 +- arch/mips/configs/ev64120_defconfig | 6 +- arch/mips/configs/ev96100_defconfig | 4 +- arch/mips/configs/ip22_defconfig | 5 +- arch/mips/configs/ip27_defconfig | 9 +- arch/mips/configs/ip32_defconfig | 8 +- arch/mips/configs/it8172_defconfig | 6 +- arch/mips/configs/ivr_defconfig | 8 +- arch/mips/configs/jaguar-atx_defconfig | 4 +- arch/mips/configs/jmr3927_defconfig | 7 +- arch/mips/configs/lasat200_defconfig | 8 +- arch/mips/configs/malta_defconfig | 6 +- arch/mips/configs/mirage_defconfig | 7 +- arch/mips/configs/mpc30x_defconfig | 9 +- arch/mips/configs/mtx1_defconfig | 7 +- arch/mips/configs/ocelot_c_defconfig | 50 +- arch/mips/configs/ocelot_defconfig | 4 +- arch/mips/configs/ocelot_g_defconfig | 587 +++++++++ arch/mips/configs/osprey_defconfig | 4 +- arch/mips/configs/pb1000_defconfig | 7 +- arch/mips/configs/pb1100_defconfig | 7 +- arch/mips/configs/pb1500_defconfig | 12 +- arch/mips/configs/pb1550_defconfig | 12 +- arch/mips/configs/rm200_defconfig | 17 +- arch/mips/configs/sb1250-swarm_defconfig | 34 +- arch/mips/configs/sead_defconfig | 3 +- arch/mips/configs/tb0226_defconfig | 8 +- arch/mips/configs/tb0229_defconfig | 10 +- arch/mips/configs/workpad_defconfig | 5 +- arch/mips/configs/xxs1500_defconfig | 7 +- arch/mips/configs/yosemite_defconfig | 181 ++- arch/mips/defconfig | 5 +- arch/mips/kernel/Makefile | 3 +- arch/mips/kernel/cpu-bugs64.c | 40 +- arch/mips/kernel/cpu-probe.c | 46 +- arch/mips/kernel/module-elf32.c | 11 - arch/mips/kernel/module-elf64.c | 11 - arch/mips/kernel/module.c | 53 + arch/mips/kernel/scall32-o32.S | 1 + arch/mips/kernel/scall64-64.S | 1 + arch/mips/kernel/scall64-n32.S | 1 + arch/mips/kernel/scall64-o32.S | 1 + arch/mips/kernel/semaphore.c | 328 ++--- arch/mips/kernel/setup.c | 14 +- arch/mips/kernel/syscall.c | 2 +- arch/mips/kernel/sysirix.c | 2 +- arch/mips/kernel/time.c | 5 + arch/mips/kernel/traps.c | 59 +- arch/mips/lib-32/Makefile | 22 +- arch/mips/lib-64/Makefile | 22 +- arch/mips/mips-boards/generic/cmdline.c | 6 +- arch/mips/mips-boards/generic/printf.c | 34 +- arch/mips/mm-32/Makefile | 19 - arch/mips/mm-32/tlbex-r4k.S | 524 -------- arch/mips/mm-64/Makefile | 25 - arch/mips/mm-64/tlb-dbg-r4k.c | 71 -- arch/mips/mm-64/tlb-glue-r4k.S | 41 - arch/mips/mm-64/tlb-glue-sb1.S | 66 - arch/mips/mm-64/tlbex-r4k.S | 203 ---- arch/mips/mm/Makefile | 39 +- arch/mips/mm/tlb-r8k.c | 253 ++++ arch/mips/mm/tlb-sb1.c | 2 +- arch/mips/mm/tlb64-glue-r4k.S | 41 + arch/mips/mm/tlb64-glue-sb1.S | 66 + arch/mips/mm/tlbex-r3k.S | 224 ---- arch/mips/mm/tlbex32-r3k.S | 224 ++++ arch/mips/mm/tlbex32-r4k.S | 524 ++++++++ arch/mips/mm/tlbex64-r4k.S | 203 ++++ arch/mips/momentum/jaguar_atx/prom.c | 14 - arch/mips/momentum/jaguar_atx/setup.c | 2 +- arch/mips/momentum/ocelot_c/Makefile | 4 +- arch/mips/momentum/ocelot_c/irq.c | 3 +- arch/mips/momentum/ocelot_c/pci-irq.c | 72 -- arch/mips/momentum/ocelot_c/prom.c | 3 +- arch/mips/momentum/ocelot_c/setup.c | 2 +- arch/mips/momentum/ocelot_g/Makefile | 3 +- arch/mips/momentum/ocelot_g/gt-irq.c | 96 +- arch/mips/momentum/ocelot_g/gt64240.h | 1238 ------------------- arch/mips/momentum/ocelot_g/gt64240_dep.h | 57 - arch/mips/momentum/ocelot_g/pci-irq.c | 73 -- arch/mips/momentum/ocelot_g/prom.c | 8 +- arch/mips/momentum/ocelot_g/setup.c | 116 +- arch/mips/pci/Makefile | 17 +- arch/mips/pci/fixup-capcella.c | 28 +- arch/mips/pci/fixup-jaguar.c | 42 + arch/mips/pci/fixup-mpc30x.c | 48 + arch/mips/pci/fixup-mv64340.c | 42 - arch/mips/pci/fixup-ocelot-c.c | 39 + arch/mips/pci/fixup-ocelot-g.c | 35 + arch/mips/pci/fixup-tb0219.c | 64 + arch/mips/pci/fixup-tb0226.c | 117 +- arch/mips/pci/fixup-tb0229.c | 64 - arch/mips/pci/fixup-victor-mpc30x.c | 48 - arch/mips/pci/fixup-yosemite.c | 17 +- arch/mips/pci/ops-gt64240.c | 149 +++ arch/mips/pci/ops-msc.c | 6 +- arch/mips/pci/ops-titan-ht.c | 125 ++ arch/mips/pci/ops-titan.c | 32 +- arch/mips/pci/ops-vr41xx.c | 126 ++ arch/mips/pci/pci-ocelot-c.c | 161 ++- arch/mips/pci/pci-ocelot-g.c | 496 +------- arch/mips/pci/pci-vr41xx.c | 398 +++--- arch/mips/pci/pci-vr41xx.h | 283 +++-- arch/mips/pci/pci-yosemite.c | 37 + arch/mips/pci/pci.c | 2 +- arch/mips/pmc-sierra/yosemite/Makefile | 7 +- arch/mips/pmc-sierra/yosemite/dbg_io.c | 184 +++ arch/mips/pmc-sierra/yosemite/i2c-yosemite.c | 188 +++ arch/mips/pmc-sierra/yosemite/i2c-yosemite.h | 52 +- arch/mips/pmc-sierra/yosemite/irq-handler.S | 87 +- arch/mips/pmc-sierra/yosemite/irq.c | 247 ++-- arch/mips/pmc-sierra/yosemite/prom.c | 144 +-- arch/mips/pmc-sierra/yosemite/py-console.c | 130 ++ arch/mips/pmc-sierra/yosemite/setup.c | 175 ++- arch/mips/pmc-sierra/yosemite/setup.h | 18 +- arch/mips/ramdisk/Makefile | 2 +- arch/mips/sgi-ip22/ip22-setup.c | 3 + arch/mips/vr41xx/common/bcu.c | 54 +- arch/mips/vr41xx/common/cmu.c | 6 +- arch/mips/vr41xx/common/giu.c | 242 +++- arch/mips/vr41xx/common/icu.c | 499 +++++--- arch/mips/vr41xx/common/init.c | 15 - arch/mips/vr41xx/common/ksyms.c | 2 - arch/mips/vr41xx/common/pmu.c | 8 +- arch/mips/vr41xx/common/rtc.c | 8 +- arch/mips/vr41xx/common/serial.c | 2 +- arch/mips/vr41xx/common/vrc4173.c | 404 +++++-- arch/mips/vr41xx/tanbac-tb0226/setup.c | 61 +- arch/mips/vr41xx/tanbac-tb0229/Makefile | 2 +- arch/mips/vr41xx/tanbac-tb0229/reboot.c | 27 - arch/mips/vr41xx/tanbac-tb0229/setup.c | 66 +- arch/mips/vr41xx/tanbac-tb0229/tb0219.c | 44 + arch/mips/vr41xx/victor-mpc30x/setup.c | 61 +- arch/mips/vr41xx/zao-capcella/setup.c | 61 +- include/asm-mips/asmmacro.h | 4 +- include/asm-mips/atomic.h | 130 +- include/asm-mips/cache.h | 2 + include/asm-mips/gt64240.h | 1264 ++++++++++++++++++++ include/asm-mips/hazards.h | 117 +- .../asm-mips/mach-yosemite/cpu-feature-overrides.h | 38 + include/asm-mips/mipsregs.h | 2 +- include/asm-mips/mmu_context.h | 12 +- include/asm-mips/module.h | 19 +- include/asm-mips/page.h | 6 +- include/asm-mips/pci.h | 3 + include/asm-mips/pgtable-32.h | 72 +- include/asm-mips/pgtable-64.h | 33 +- include/asm-mips/pgtable-bits.h | 18 +- include/asm-mips/pgtable.h | 2 - include/asm-mips/pmon.h | 3 + include/asm-mips/processor.h | 9 - include/asm-mips/semaphore.h | 265 +--- include/asm-mips/serial.h | 19 - include/asm-mips/smp.h | 8 - include/asm-mips/stackframe.h | 3 + include/asm-mips/system.h | 21 +- include/asm-mips/thread_info.h | 3 + include/asm-mips/titan_dep.h | 181 ++- include/asm-mips/unistd.h | 15 +- include/asm-mips/vr41xx/capcella.h | 54 +- include/asm-mips/vr41xx/mpc30x.h | 54 +- include/asm-mips/vr41xx/tb0219.h | 42 + include/asm-mips/vr41xx/tb0226.h | 54 +- include/asm-mips/vr41xx/tb0229.h | 73 -- include/asm-mips/vr41xx/vr41xx.h | 144 ++- include/asm-mips/vr41xx/vrc4173.h | 78 +- 180 files changed, 7917 insertions(+), 6118 deletions(-) create mode 100644 arch/mips/configs/ocelot_g_defconfig create mode 100644 arch/mips/kernel/module.c delete mode 100644 arch/mips/mm-32/Makefile delete mode 100644 arch/mips/mm-32/tlbex-r4k.S delete mode 100644 arch/mips/mm-64/Makefile delete mode 100644 arch/mips/mm-64/tlb-dbg-r4k.c delete mode 100644 arch/mips/mm-64/tlb-glue-r4k.S delete mode 100644 arch/mips/mm-64/tlb-glue-sb1.S delete mode 100644 arch/mips/mm-64/tlbex-r4k.S create mode 100644 arch/mips/mm/tlb-r8k.c create mode 100644 arch/mips/mm/tlb64-glue-r4k.S create mode 100644 arch/mips/mm/tlb64-glue-sb1.S delete mode 100644 arch/mips/mm/tlbex-r3k.S create mode 100644 arch/mips/mm/tlbex32-r3k.S create mode 100644 arch/mips/mm/tlbex32-r4k.S create mode 100644 arch/mips/mm/tlbex64-r4k.S delete mode 100644 arch/mips/momentum/ocelot_c/pci-irq.c delete mode 100644 arch/mips/momentum/ocelot_g/gt64240.h delete mode 100644 arch/mips/momentum/ocelot_g/gt64240_dep.h delete mode 100644 arch/mips/momentum/ocelot_g/pci-irq.c create mode 100644 arch/mips/pci/fixup-jaguar.c create mode 100644 arch/mips/pci/fixup-mpc30x.c delete mode 100644 arch/mips/pci/fixup-mv64340.c create mode 100644 arch/mips/pci/fixup-ocelot-c.c create mode 100644 arch/mips/pci/fixup-ocelot-g.c create mode 100644 arch/mips/pci/fixup-tb0219.c delete mode 100644 arch/mips/pci/fixup-tb0229.c delete mode 100644 arch/mips/pci/fixup-victor-mpc30x.c create mode 100644 arch/mips/pci/ops-gt64240.c create mode 100644 arch/mips/pci/ops-titan-ht.c create mode 100644 arch/mips/pci/ops-vr41xx.c create mode 100644 arch/mips/pci/pci-yosemite.c create mode 100644 arch/mips/pmc-sierra/yosemite/dbg_io.c create mode 100644 arch/mips/pmc-sierra/yosemite/i2c-yosemite.c create mode 100644 arch/mips/pmc-sierra/yosemite/py-console.c delete mode 100644 arch/mips/vr41xx/tanbac-tb0229/reboot.c create mode 100644 arch/mips/vr41xx/tanbac-tb0229/tb0219.c create mode 100644 include/asm-mips/gt64240.h create mode 100644 include/asm-mips/mach-yosemite/cpu-feature-overrides.h create mode 100644 include/asm-mips/vr41xx/tb0219.h delete mode 100644 include/asm-mips/vr41xx/tb0229.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 080eb3c37aba..ebfd35e5544d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -96,11 +96,13 @@ config NEC_EAGLE select DMA_NONCOHERENT select IRQ_CPU depends on MACH_VR41XX + select HW_HAS_PCI config TANBAC_TB0226 bool "Support for TANBAC TB0226 (Mbase)" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help The TANBAC TB0226 (Mbase) is a MIPS-based platform manufactured by TANBAC. @@ -110,6 +112,7 @@ config TANBAC_TB0229 bool "Support for TANBAC TB0229 (VR4131DIMM)" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC. @@ -118,6 +121,7 @@ config TANBAC_TB0229 config VICTOR_MPC30X bool "Support for Victor MP-C303/304" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU depends on MACH_VR41XX @@ -125,17 +129,22 @@ config ZAO_CAPCELLA bool "Support for ZAO Networks Capcella" depends on MACH_VR41XX select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU +config PCI_VR41XX + bool "Add PCI control unit support of NEC VR4100 series" + depends on MACH_VR41XX && PCI + config VRC4171 - tristate "add NEC VRC4171 companion chip support" + tristate "Add NEC VRC4171 companion chip support" depends on MACH_VR41XX && ISA ---help--- The NEC VRC4171/4171A is a companion chip for NEC VR4111/VR4121. config VRC4173 - tristate "add NEC VRC4173 companion chip support" - depends on MACH_VR41XX && PCI + tristate "Add NEC VRC4173 companion chip support" + depends on MACH_VR41XX && PCI_VR41XX ---help--- The NEC VRC4173 is a companion chip for NEC VR4122/VR4131. @@ -143,11 +152,13 @@ config TOSHIBA_JMR3927 bool "Support for Toshiba JMR-TX3927 board" depends on MIPS32 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_COBALT bool "Support for Cobalt Server (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU config MACH_DECSTATION @@ -174,6 +185,7 @@ config MIPS_EV64120 bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI help This is an evaluation board based on the Galileo GT-64120 single-chip system controller that contains a MIPS R5000 compatible @@ -189,6 +201,7 @@ config MIPS_EV96100 bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select MIPS_GT96100 select RM7000_CPU_SCACHE @@ -201,6 +214,7 @@ config MIPS_EV96100 config MIPS_IVR bool "Support for Globespan IVR board" select DMA_NONCOHERENT + select HW_HAS_PCI help This is an evaluation board built by Globespan to showcase thir iVR (Internet Video Recorder) design. It utilizes a QED RM5231 @@ -211,6 +225,7 @@ config MIPS_IVR config LASAT bool "Support for LASAT Networks platforms" select DMA_NONCOHERENT + select HW_HAS_PCI select R5000_CPU_SCACHE config PICVUE @@ -233,11 +248,13 @@ config HP_LASERJET bool "Support for Hewlett Packard LaserJet board" depends on BROKEN select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU config MIPS_ITE8172 bool "Support for ITE 8172G board" select DMA_NONCOHERENT + select HW_HAS_PCI help Ths is an evaluation board made by ITE with ATX form factor that utilizes a MIPS R5000 to work with its @@ -257,6 +274,7 @@ config IT8172_REVC config MIPS_ATLAS bool "Support for MIPS Atlas board" select DMA_NONCOHERENT + select HW_HAS_PCI help This enables support for the QED R5231-based MIPS Atlas evaluation board. @@ -265,6 +283,7 @@ config MIPS_MALTA bool "Support for MIPS Malta board" select HAVE_STD_PC_SERIAL_PORT select DMA_NONCOHERENT + select HW_HAS_PCI help This enables support for the VR5000-based MIPS Malta evaluation board. @@ -278,6 +297,7 @@ config MIPS_SEAD config MOMENCO_OCELOT bool "Support for Momentum Ocelot board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select RM7000_CPU_SCACHE @@ -288,6 +308,7 @@ config MOMENCO_OCELOT config MOMENCO_OCELOT_G bool "Support for Momentum Ocelot-G board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select RM7000_CPU_SCACHE @@ -298,6 +319,7 @@ config MOMENCO_OCELOT_G config MOMENCO_OCELOT_C bool "Support for Momentum Ocelot-C board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select RM7000_CPU_SCACHE help @@ -307,6 +329,7 @@ config MOMENCO_OCELOT_C config MOMENCO_JAGUAR_ATX bool "Support for Momentum Jaguar board" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K select LIMITED_DMA @@ -324,7 +347,10 @@ config JAGUAR_DMALOW config PMC_YOSEMITE bool "Support for PMC-Sierra Yosemite eval board" - select DMA_NONCOHERENT + select DMA_COHERENT + select HW_HAS_PCI + select IRQ_CPU + select IRQ_CPU_RM7K help Yosemite is an evaluation board for the RM9000x2 processor manufactured by PMC-Sierra @@ -338,6 +364,7 @@ config DDB5074 depends on EXPERIMENTAL select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select IRQ_CPU select ISA help @@ -348,6 +375,7 @@ config DDB5476 bool "Support for NEC DDB Vrc-5476" select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select IRQ_CPU select ISA help @@ -361,6 +389,7 @@ config DDB5476 config DDB5477 bool "Support for NEC DDB Vrc-5477" select DMA_NONCOHERENT + select HW_HAS_PCI select IRQ_CPU help This enables support for the R5432-based NEC DDB Vrc-5477, @@ -393,6 +422,7 @@ config SGI_IP27 bool "Support for SGI IP27 (Origin200/2000)" depends on MIPS64 select DMA_IP27 + select HW_HAS_PCI help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -457,6 +487,7 @@ config SGI_IP32 bool "Support for SGI IP32 (O2) (EXPERIMENTAL)" depends on EXPERIMENTAL select DMA_NONCOHERENT + select HW_HAS_PCI select R5000_CPU_SCACHE select RM7000_CPU_SCACHE help @@ -499,26 +530,31 @@ config MIPS_PB1000 bool "PB1000 board" depends on SOC_AU1000 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1100 bool "PB1100 board" depends on SOC_AU1100 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1500 bool "PB1500 board" depends on SOC_AU1500 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_PB1550 bool "PB1550 board" depends on SOC_AU1550 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1000 bool "DB1000 board" depends on SOC_AU1000 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1100 bool "DB1100 board" @@ -529,10 +565,12 @@ config MIPS_DB1500 bool "DB1500 board" depends on SOC_AU1500 select DMA_NONCOHERENT + select HW_HAS_PCI config MIPS_DB1550 bool "DB1550 board" depends on SOC_AU1550 + select HW_HAS_PCI config MIPS_BOSPORUS bool "Bosporus board" @@ -642,6 +680,7 @@ endchoice config SIBYTE_SB1250 bool + select HW_HAS_PCI config SIBYTE_BCM1120 bool @@ -649,10 +688,12 @@ config SIBYTE_BCM1120 config SIBYTE_BCM1125 bool + select HW_HAS_PCI select SIBYTE_BCM112X config SIBYTE_BCM1125H bool + select HW_HAS_PCI select SIBYTE_BCM112X config SIBYTE_BCM112X @@ -699,11 +740,6 @@ endchoice config CPU_SB1_PASS_2 bool -config SIBYTE_HAS_PCI - bool - depends on SIBYTE_SB1250 || SIBYTE_BCM1125 || SIBYTE_BCM1125H - default y - config SIBYTE_HAS_LDT bool depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H) @@ -770,6 +806,7 @@ config SNI_RM200_PCI bool "Support for SNI RM200 PCI" select DMA_NONCOHERENT select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI select ISA help The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens @@ -781,6 +818,7 @@ config TOSHIBA_RBTX4927 bool "Support for Toshiba TBTX49[23]7 board" depends on MIPS32 select DMA_NONCOHERENT + select HW_HAS_PCI select ISA config RWSEM_GENERIC_SPINLOCK @@ -860,11 +898,6 @@ config IRQ_CPU config IRQ_CPU_RM7K bool -config DUMMY_KEYB - bool - depends on ZAO_CAPCELLA || VICTOR_MPC30X || SIBYTE_SB1xxx_SOC || NEC_EAGLE || NEC_OSPREY || DDB5477 || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 - default y - config DDB5XXX_COMMON bool depends on DDB5074 || DDB5476 || DDB5477 @@ -1164,6 +1197,16 @@ config PAGE_SIZE_4KB 4kB page size will minimize memory consumption and is therefore recommended for low memory systems. +config PAGE_SIZE_8KB + bool "8kB" + depends on EXPERIMENTAL && CPU_R8000 + help + Using 8kB page size will result in higher performance kernel at + the price of higher memory consumption. This option is available + only on the R8000 processor. Not that at the time of this writing + this option is still high experimental; there are also issues with + compatibility of user applications. + config PAGE_SIZE_16KB bool "16kB" depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX @@ -1377,9 +1420,12 @@ endmenu menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" +config HW_HAS_PCI + bool + config PCI bool "Support for PCI controller" - depends on MIPS_DB1000 || DDB5074 || DDB5476 || DDB5477 || HP_LASERJET || LASAT || MIPS_IVR || MIPS_ATLAS || MIPS_COBALT || MIPS_EV64120 || MIPS_EV96100 || MIPS_ITE8172 || MIPS_MALTA || MOMENCO_OCELOT || MOMENCO_OCELOT_C || MOMENCO_OCELOT_G || MOMENCO_JAGUAR_ATX || MIPS_PB1000 || MIPS_PB1100 || SOC_AU1500 || SOC_AU1550 || NEC_EAGLE || SGI_IP27 || SGI_IP32 || SIBYTE_HAS_PCI || SNI_RM200_PCI || TANBAC_TB0226 || TANBAC_TB0229 || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || VICTOR_MPC30X || ZAO_CAPCELLA + depends on HW_HAS_PCI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -1559,7 +1605,7 @@ config DEBUG_STACK_USAGE config DEBUG_SLAB bool "Debug memory allocations" - depends on DEBUG_KERNEL && !CPU_HAS_LLDSCD + depends on DEBUG_KERNEL help Say Y here to have the kernel do limited verification on memory allocation as well as poisoning memory on free to catch use of freed diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 8c4fb4b1d33f..c1aabc835f62 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -405,6 +405,13 @@ load-$(CONFIG_MOMENCO_OCELOT_G) += 0x80100000 core-$(CONFIG_MOMENCO_OCELOT_C) += arch/mips/momentum/ocelot_c/ load-$(CONFIG_MOMENCO_OCELOT_C) += 0x80100000 +# +# PMC-Sierra Yosemite +# +core-$(CONFIG_PMC_YOSEMITE) += arch/mips/pmc-sierra/yosemite/ +cflags-$(CONFIG_PMC_YOSEMITE) += -Iinclude/asm-mips/mach-yosemite +load-$(CONFIG_PMC_YOSEMITE) += 0x80100000 + # # Momentum Jaguar ATX # @@ -659,8 +666,6 @@ libs-$(CONFIG_MIPS32) += arch/mips/lib-32/ libs-$(CONFIG_MIPS64) += arch/mips/lib-64/ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ -core-$(CONFIG_MIPS32) += arch/mips/mm-32/ -core-$(CONFIG_MIPS64) += arch/mips/mm-64/ ifdef CONFIG_BAGET_MIPS diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index a6e88d3180cb..c010290e55a6 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -39,7 +39,7 @@ $(obj)/addinitrd: $(obj)/addinitrd.c archhelp: @echo '* vmlinux.ecoff - ECOFF boot image' -CLEAN_FILES += addinitrd \ +clean-files += addinitrd \ elf2ecoff \ vmlinux.ecoff \ vmlinux.srec \ diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 9814c8e6dc79..cd4da1fb9f85 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -107,6 +107,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -121,6 +122,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -197,7 +199,6 @@ CONFIG_BLK_DEV_SD=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -216,11 +217,11 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -229,6 +230,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -395,7 +397,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -616,7 +617,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -651,3 +651,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/bosporus_defconfig b/arch/mips/configs/bosporus_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/bosporus_defconfig +++ b/arch/mips/configs/bosporus_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index 910a796dfb0f..44799daa96b6 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -59,7 +59,8 @@ CONFIG_MACH_VR41XX=y # CONFIG_TANBAC_TB0229 is not set # CONFIG_VICTOR_MPC30X is not set CONFIG_ZAO_CAPCELLA=y -# CONFIG_VRC4173 is not set +CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -185,7 +187,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -197,6 +198,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -214,7 +216,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -357,7 +358,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -591,7 +591,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -626,3 +625,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index fb148427e050..c3fda0f4e154 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -104,6 +104,7 @@ CONFIG_CPU_NEVADA=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -116,6 +117,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -176,7 +178,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -188,6 +189,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -205,7 +207,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -344,7 +345,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -567,7 +567,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,3 +601,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index fbb3ecda03ca..3ec36c06285c 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -522,6 +524,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -593,7 +598,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -678,11 +682,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 088b3a1069c8..f649a7cafc04 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -518,6 +519,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -589,7 +593,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -674,11 +677,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 86ecbe185aa3..ff5ec324a67e 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -259,7 +261,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -271,6 +272,7 @@ CONFIG_BLK_DEV_IDECS=m # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -592,6 +594,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -665,7 +670,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -750,11 +754,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig index 5f74857ae904..2385348b99a7 100644 --- a/arch/mips/configs/ddb5476_defconfig +++ b/arch/mips/configs/ddb5476_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_R5432=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -117,6 +118,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -179,7 +181,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +192,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -214,7 +216,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -363,7 +364,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -487,6 +487,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -606,7 +607,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -641,3 +641,4 @@ CONFIG_CMDLINE="ip=any" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index 13222c363ccf..3a2e7ca35066 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -80,7 +80,6 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_I8259=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_DDB5XXX_COMMON=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -106,6 +105,7 @@ CONFIG_CPU_R5432=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -118,6 +118,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -184,7 +185,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -345,7 +345,6 @@ CONFIG_PCNET32=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -567,7 +566,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,3 +600,4 @@ CONFIG_CMDLINE="ip=any" # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 9f41a3d0f6e4..c2bf43ff126b 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -109,6 +109,7 @@ CONFIG_CPU_R3000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -184,7 +185,6 @@ CONFIG_BLK_DEV_SD=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -537,7 +537,6 @@ CONFIG_RAMFS=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -587,3 +586,4 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index b0154fa605f7..cda052941dbb 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -91,7 +91,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +115,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -180,7 +180,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +190,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -570,7 +570,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -605,3 +604,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/eagle_defconfig b/arch/mips/configs/eagle_defconfig index 9a4517f6afbd..78feb1ac0945 100644 --- a/arch/mips/configs/eagle_defconfig +++ b/arch/mips/configs/eagle_defconfig @@ -59,6 +59,7 @@ CONFIG_NEC_EAGLE=y # CONFIG_TANBAC_TB0229 is not set # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set +CONFIG_PCI_VR41XX=y CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -261,7 +263,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=y # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -274,6 +275,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -291,7 +293,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -447,7 +448,6 @@ CONFIG_PCMCIA_PCNET=m # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -692,7 +692,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -739,11 +738,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig index 2cbeb69b967a..f1c310de72cc 100644 --- a/arch/mips/configs/ev64120_defconfig +++ b/arch/mips/configs/ev64120_defconfig @@ -111,6 +111,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -124,6 +125,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -191,7 +193,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -339,7 +340,6 @@ CONFIG_PPP_ASYNC=y # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -559,7 +559,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -594,3 +593,4 @@ CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/d # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig index 4d6bd5352903..506214b4bbeb 100644 --- a/arch/mips/configs/ev96100_defconfig +++ b/arch/mips/configs/ev96100_defconfig @@ -110,6 +110,7 @@ CONFIG_CPU_RM7000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -514,7 +516,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -549,3 +550,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 912beee0c66c..83d850031444 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -114,6 +114,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -196,7 +197,6 @@ CONFIG_BLK_DEV_SR=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -750,7 +750,6 @@ CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -850,11 +849,13 @@ CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index c7cff248c5c7..a75dfcdd4bf4 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -113,6 +113,7 @@ CONFIG_CPU_R10000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -128,6 +129,7 @@ CONFIG_NR_CPUS=64 # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -203,7 +205,6 @@ CONFIG_CHR_DEV_ST=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -226,7 +227,6 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -235,6 +235,7 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set CONFIG_SCSI_QLOGIC_ISP=y # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -267,6 +268,7 @@ CONFIG_SCSI_QLA2XXX=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -638,7 +640,6 @@ CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -700,11 +701,13 @@ CONFIG_CRYPTO_CAST6=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 7dcbf62c9219..f6e3592da18b 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -102,6 +102,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -116,6 +117,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -193,7 +195,6 @@ CONFIG_CHR_DEV_SG=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -222,7 +223,6 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -231,6 +231,7 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -263,6 +264,7 @@ CONFIG_SCSI_QLA2XXX=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -617,7 +619,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -663,3 +664,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig index d7f83618a35a..3460da6ad76a 100644 --- a/arch/mips/configs/it8172_defconfig +++ b/arch/mips/configs/it8172_defconfig @@ -110,6 +110,7 @@ CONFIG_CPU_NEVADA=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -122,6 +123,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -231,7 +233,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -242,6 +243,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -615,7 +617,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -650,3 +651,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig index 58a83eece110..4f3e01b3b8cc 100644 --- a/arch/mips/configs/ivr_defconfig +++ b/arch/mips/configs/ivr_defconfig @@ -108,6 +108,7 @@ CONFIG_CPU_NEVADA=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -120,6 +121,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -179,7 +181,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +192,7 @@ CONFIG_IDE_TASKFILE_IO=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -208,7 +210,6 @@ CONFIG_IDE_GENERIC=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -350,7 +351,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -571,7 +571,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -606,3 +605,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig index 99cda767b71c..f28e0657e6a7 100644 --- a/arch/mips/configs/jaguar-atx_defconfig +++ b/arch/mips/configs/jaguar-atx_defconfig @@ -100,6 +100,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_CPU_RM9000=y # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -118,6 +119,7 @@ CONFIG_HIGHMEM=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -184,7 +186,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -538,3 +539,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 95e463724cda..17b715a04735 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -104,6 +104,7 @@ CONFIG_CPU_TX39XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -115,6 +116,7 @@ CONFIG_RTC_DS1742=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -182,7 +184,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -324,7 +325,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -462,6 +462,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -578,7 +579,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -613,3 +613,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index f7208748c51f..d5874a83fbf4 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -112,6 +112,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -127,6 +128,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set @@ -242,7 +244,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -283,6 +284,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -301,7 +303,6 @@ CONFIG_IDEDMA_AUTO=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -438,7 +439,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -665,7 +665,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -700,3 +699,4 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 67a995528818..87e171b5f008 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -115,6 +115,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -129,6 +130,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -197,7 +199,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -357,7 +358,6 @@ CONFIG_PCNET32=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -580,7 +580,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -615,3 +614,4 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/mirage_defconfig b/arch/mips/configs/mirage_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/mirage_defconfig +++ b/arch/mips/configs/mirage_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 3ccf5a617072..a78627cddd1d 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -59,6 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_TANBAC_TB0229 is not set CONFIG_VICTOR_MPC30X=y # CONFIG_ZAO_CAPCELLA is not set +CONFIG_PCI_VR41XX=y CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -116,6 +116,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -126,6 +127,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -192,7 +194,6 @@ CONFIG_TRAD_SIGNALS=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -335,7 +336,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -555,7 +555,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -602,11 +601,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig index f33d867cc300..704bd7e7845d 100644 --- a/arch/mips/configs/ocelot_c_defconfig +++ b/arch/mips/configs/ocelot_c_defconfig @@ -100,6 +100,7 @@ CONFIG_CPU_RM7000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -114,7 +115,10 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_PCI is not set +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y CONFIG_MMU=y # @@ -154,8 +158,13 @@ CONFIG_BINFMT_ELF32=y # Block devices # # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set # CONFIG_BLK_DEV_RAM is not set # @@ -185,6 +194,7 @@ CONFIG_BINFMT_ELF32=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -257,27 +267,51 @@ CONFIG_NETDEVICES=y # CONFIG_TUN is not set # CONFIG_ETHERTAP is not set +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # -CONFIG_MV64340_ETH=y -CONFIG_MV64340_ETH_0=y -# CONFIG_MV64340_ETH_1 is not set -# CONFIG_MV64340_ETH_2 is not set +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_MV64340_ETH is not set # # Ethernet (10000 Mbit) # +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -288,6 +322,8 @@ CONFIG_MV64340_ETH_0=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -329,6 +365,7 @@ CONFIG_SERIO=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # # Input Device Drivers @@ -426,6 +463,7 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # +# CONFIG_USB is not set # # USB Gadget Support @@ -509,7 +547,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -544,3 +581,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index c3d713ac4ebd..e83e3f965082 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -108,6 +108,7 @@ CONFIG_CPU_RM7000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -124,6 +125,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -513,7 +515,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -548,3 +549,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig new file mode 100644 index 000000000000..d8e4d007a8c5 --- /dev/null +++ b/arch/mips/configs/ocelot_g_defconfig @@ -0,0 +1,587 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS64=y +CONFIG_64BIT=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_MACH_JAZZ is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +CONFIG_MOMENCO_OCELOT_G=y +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_CPU_RM7K=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_SYSCLK_75 is not set +# CONFIG_SYSCLK_83 is not set +CONFIG_SYSCLK_100=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_RM7000_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_GALILEO_64240_ETH=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/osprey_defconfig b/arch/mips/configs/osprey_defconfig index 6d6e26201134..c7a3bbd48560 100644 --- a/arch/mips/configs/osprey_defconfig +++ b/arch/mips/configs/osprey_defconfig @@ -83,7 +83,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set CONFIG_VR4181=y @@ -109,6 +108,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -507,7 +507,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -542,3 +541,4 @@ CONFIG_CMDLINE="ip=bootp ether=46,0x03fe0300,eth0" # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m diff --git a/arch/mips/configs/pb1000_defconfig b/arch/mips/configs/pb1000_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/pb1000_defconfig +++ b/arch/mips/configs/pb1000_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index edf9ced7a727..2b71a0410b4e 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 533dc53ae283..fbf01a172524 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -123,6 +123,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -137,6 +138,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -213,7 +215,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -254,6 +255,7 @@ CONFIG_BLK_DEV_HPT366=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -272,7 +274,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -452,7 +453,6 @@ CONFIG_PPP_DEFLATE=m # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -611,6 +611,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -682,7 +685,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -767,11 +769,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index ad953c3a9630..382b9f126477 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -122,6 +122,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -136,6 +137,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -212,7 +214,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -253,6 +254,7 @@ CONFIG_BLK_DEV_HPT366=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -271,7 +273,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -451,7 +452,6 @@ CONFIG_PPP_DEFLATE=m # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -610,6 +610,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -681,7 +684,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -766,11 +768,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 2317b23ed6e1..68d9ef86ac1c 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -116,6 +116,7 @@ CONFIG_CPU_R4X00=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -129,6 +130,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set @@ -246,7 +248,6 @@ CONFIG_BLK_DEV_SR_VENDOR=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -268,12 +269,12 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -294,6 +295,7 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set @@ -695,7 +697,6 @@ CONFIG_PLIP=m # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -908,6 +909,7 @@ CONFIG_USB_WACOM=m CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m # CONFIG_USB_MTOUCH is not set +CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m # CONFIG_USB_ATI_REMOTE is not set @@ -1016,6 +1018,7 @@ CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_LED=m CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGETSERVO=m CONFIG_USB_TEST=m # @@ -1051,10 +1054,14 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y CONFIG_JFS_FS=m # CONFIG_JFS_POSIX_ACL is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m # CONFIG_XFS_RT is not set CONFIG_XFS_QUOTA=y @@ -1140,6 +1147,7 @@ CONFIG_RPCSEC_GSS_KRB5=m CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y @@ -1151,7 +1159,6 @@ CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y CONFIG_CODA_FS=m CONFIG_CODA_FS_OLD_API=y -CONFIG_INTERMEZZO_FS=m CONFIG_AFS_FS=m CONFIG_RXRPC=m @@ -1252,11 +1259,13 @@ CONFIG_CRYPTO_CAST6=m # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set CONFIG_CRYPTO_TEST=m # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 593f119b4b76..7d3c4df26207 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -93,7 +93,6 @@ CONFIG_CPU_SB1_PASS_1=y # CONFIG_CPU_SB1_PASS_4 is not set # CONFIG_CPU_SB1_PASS_2_112x is not set # CONFIG_CPU_SB1_PASS_3 is not set -CONFIG_SIBYTE_HAS_PCI=y CONFIG_SIBYTE_HAS_LDT=y # CONFIG_SIMULATION is not set CONFIG_SIBYTE_CFE=y @@ -107,7 +106,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_DUMMY_KEYB=y CONFIG_SWAP_IO_SPACE=y CONFIG_BOOT_ELF32=y CONFIG_MIPS_L1_CACHE_SHIFT=5 @@ -134,6 +132,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_CPU_RM9000 is not set CONFIG_CPU_SB1=y CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_SIBYTE_DMA_PAGEOPS is not set @@ -154,6 +153,7 @@ CONFIG_NR_CPUS=2 # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -213,7 +213,30 @@ CONFIG_BLK_DEV_INITRD=y # # ATA/ATAPI/MFM/RLL support # -# CONFIG_IDE is not set +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDETAPE=y +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPCI is not set +CONFIG_BLK_DEV_IDE_SWARM=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support @@ -228,7 +251,6 @@ CONFIG_BLK_DEV_INITRD=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -371,7 +393,6 @@ CONFIG_NET_SB1250_MAC=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -575,7 +596,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -623,11 +643,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index ba93024bf7ad..d9b6532c23c4 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -19,7 +19,6 @@ CONFIG_BROKEN_ON_SMP=y # CONFIG_SWAP=y # CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set @@ -103,6 +102,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -429,3 +429,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index f32841b8023d..818bf63b72ea 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -90,7 +90,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_FB=y @@ -115,6 +114,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -125,6 +125,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set CONFIG_MMU=y @@ -179,7 +180,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -191,6 +191,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -215,7 +216,6 @@ CONFIG_CHR_DEV_SG=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -608,7 +608,6 @@ CONFIG_SMB_NLS_REMOTE="cp932" # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -681,5 +680,6 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig index 730a994abc2c..146c70cd6944 100644 --- a/arch/mips/configs/tb0229_defconfig +++ b/arch/mips/configs/tb0229_defconfig @@ -59,7 +59,8 @@ CONFIG_MACH_VR41XX=y CONFIG_TANBAC_TB0229=y # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set -# CONFIG_VRC4173 is not set +CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -91,7 +92,6 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_NONCOHERENT=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_DUMMY_KEYB=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set CONFIG_TANBAC_TB0219=y @@ -117,6 +117,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -127,6 +128,7 @@ CONFIG_CPU_HAS_SYNC=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -196,7 +198,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -355,7 +356,6 @@ CONFIG_SLIP=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set @@ -599,7 +599,6 @@ CONFIG_SMB_NLS_REMOTE="cp932" # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -672,5 +671,6 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index cfe12d1c4a7f..e1923900c710 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -115,6 +115,7 @@ CONFIG_CPU_VR41XX=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set @@ -179,7 +180,6 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -190,6 +190,7 @@ CONFIG_IDE_TASKFILE_IO=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set @@ -573,7 +574,6 @@ CONFIG_SUNRPC=y # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -608,3 +608,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/configs/xxs1500_defconfig b/arch/mips/configs/xxs1500_defconfig index edf9ced7a727..188176e34b83 100644 --- a/arch/mips/configs/xxs1500_defconfig +++ b/arch/mips/configs/xxs1500_defconfig @@ -105,6 +105,7 @@ CONFIG_CPU_MIPS32=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -496,6 +497,9 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set @@ -567,7 +571,6 @@ CONFIG_SMB_FS=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -652,11 +655,13 @@ CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=y +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index fc1eddbbd1d2..37d39a6677b5 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -9,20 +9,20 @@ CONFIG_MIPS32=y # # Code maturity level options # -CONFIG_EXPERIMENTAL=y +# CONFIG_EXPERIMENTAL is not set CONFIG_CLEAN_COMPILE=y CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y # # General setup # CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=15 +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -41,47 +41,40 @@ CONFIG_IOSCHED_CFQ=y # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y -CONFIG_MODVERSIONS=y CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y # # Machine selection # # CONFIG_MACH_JAZZ is not set -# CONFIG_BAGET_MIPS is not set # CONFIG_MACH_VR41XX is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_DDB5074 is not set +CONFIG_PMC_YOSEMITE=y +# CONFIG_HYPERTRANSPORT is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SOC_AU1X00 is not set -# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set # CONFIG_TOSHIBA_RBTX4927 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_HAVE_DEC_LOCK=y +CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_CPU_RM7K=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_FB is not set @@ -106,6 +99,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_CPU_RM9000=y # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y @@ -114,15 +108,18 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y CONFIG_CPU_HAS_SYNC=y -# CONFIG_HIGHMEM is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 +CONFIG_HIGHMEM=y +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y CONFIG_MMU=y # @@ -159,11 +156,14 @@ CONFIG_TRAD_SIGNALS=y # Block devices # # CONFIG_BLK_DEV_FD is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_LBD=y +# CONFIG_LBD is not set # # ATA/ATAPI/MFM/RLL support @@ -173,40 +173,7 @@ CONFIG_LBD=y # # SCSI device support # -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_REPORT_LUNS=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI is not set # # Multi-device support (RAID and LVM) @@ -225,6 +192,7 @@ CONFIG_SCSI_REPORT_LUNS=y # # I2O device support # +# CONFIG_I2O is not set # # Networking support @@ -234,46 +202,31 @@ CONFIG_NET=y # # Networking options # -CONFIG_PACKET=y +CONFIG_PACKET=m CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set +CONFIG_NETLINK_DEV=m CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set # # QoS and/or fair queueing @@ -295,23 +248,50 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +CONFIG_TITAN_GE=y # # Ethernet (10000 Mbit) # +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -322,10 +302,9 @@ CONFIG_NET_ETHERNET=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set # # ISDN subsystem @@ -351,10 +330,8 @@ CONFIG_NET_ETHERNET=y # # CONFIG_GAMEPORT is not set CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set # # Input Device Drivers @@ -364,22 +341,21 @@ CONFIG_SERIO_SERPORT=y # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_SYNCLINK is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_N_HDLC is not set -# CONFIG_STALDRV is not set +# CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # -# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support # +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -403,6 +379,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +# CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -438,6 +415,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # # USB support # +# CONFIG_USB is not set # # USB Gadget Support @@ -448,13 +426,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # File systems # # CONFIG_EXT2_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_XFS_FS is not set @@ -482,7 +455,6 @@ CONFIG_FS_MBCACHE=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set @@ -491,13 +463,7 @@ CONFIG_RAMFS=y # # Miscellaneous filesystems # -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -509,22 +475,16 @@ CONFIG_RAMFS=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFS_V3 is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y # CONFIG_EXPORTFS is not set CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_AFS_FS is not set # # Partition Types @@ -558,3 +518,4 @@ CONFIG_CMDLINE="" # Library routines # # CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 912beee0c66c..83d850031444 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -114,6 +114,7 @@ CONFIG_CPU_R5000=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_BOARD_SCACHE=y @@ -196,7 +197,6 @@ CONFIG_BLK_DEV_SR=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -750,7 +750,6 @@ CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -850,11 +849,13 @@ CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # # Library routines # # CONFIG_CRC32 is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 9ce8090eff68..3a7f766fd961 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -9,7 +9,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ time.o traps.o unaligned.o ifdef CONFIG_MODULES -obj-y += mips_ksyms.o +obj-y += mips_ksyms.o module.o obj-$(CONFIG_MIPS32) += module-elf32.o obj-$(CONFIG_MIPS64) += module-elf64.o endif @@ -23,6 +23,7 @@ obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 31c17ced894e..1375d448308b 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -177,7 +177,7 @@ static inline void check_daddi(void) extern asmlinkage void handle_daddi_ov(void); unsigned long flags; void *handler; - long v; + long v, tmp; printk("Checking for the daddi bug... "); @@ -197,13 +197,15 @@ static inline void check_daddi(void) ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" + "addiu %1, $0, %2\n\t" + "dsrl %1, %1, 1\n\t" #ifdef HAVE_AS_SET_DADDI ".set daddi\n\t" #endif - "daddi %0, %1, %2\n\t" + "daddi %0, %1, %3\n\t" ".set pop" - : "=r" (v) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=r" (v), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -217,9 +219,11 @@ static inline void check_daddi(void) local_irq_save(flags); handler = set_except_vector(12, handle_daddi_ov); asm volatile( - "daddi %0, %1, %2" - : "=r" (v) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + "addiu %1, $0, %2\n\t" + "dsrl %1, %1, 1\n\t" + "daddi %0, %1, %3" + : "=r" (v), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -240,7 +244,7 @@ static inline void check_daddi(void) static inline void check_daddiu(void) { - long v, w; + long v, w, tmp; printk("Checking for the daddiu bug... "); @@ -265,15 +269,17 @@ static inline void check_daddiu(void) ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" + "addiu %2, $0, %3\n\t" + "dsrl %2, %2, 1\n\t" #ifdef HAVE_AS_SET_DADDI ".set daddi\n\t" #endif - "daddiu %0, %2, %3\n\t" - "addiu %1, $0, %3\n\t" + "daddiu %0, %2, %4\n\t" + "addiu %1, $0, %4\n\t" "daddu %1, %2\n\t" ".set pop" - : "=&r" (v), "=&r" (w) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=&r" (v), "=&r" (w), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); if (v == w) { printk("no.\n"); @@ -283,11 +289,13 @@ static inline void check_daddiu(void) printk("yes, workaround... "); asm volatile( - "daddiu %0, %2, %3\n\t" - "addiu %1, $0, %3\n\t" + "addiu %2, $0, %3\n\t" + "dsrl %2, %2, 1\n\t" + "daddiu %0, %2, %4\n\t" + "addiu %1, $0, %4\n\t" "daddu %1, %2" - : "=&r" (v), "=&r" (w) - : "r" (0x7fffffffffffedcd), "I" (0x1234)); + : "=&r" (v), "=&r" (w), "=&r" (tmp) + : "I" (0xffffffffffffdb9a), "I" (0x1234)); if (v == w) { printk("yes.\n"); diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 5013599347e3..36777476dae1 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1,6 +1,8 @@ /* * Processor capabilities determination functions. * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 2003 Maciej W. Rozycki * Copyright (C) 1994 - 2003 Ralf Baechle * Copyright (C) 2001 MIPS Inc. * @@ -49,6 +51,14 @@ static void r4k_wait(void) ".set\tmips0"); } +/* + * The Au1xxx wait is available only if we run CONFIG_PM and + * the timer setup found we had a 32KHz counter available. + * There are still problems with functions that may call au1k_wait + * directly, but that will be discovered pretty quickly. + */ +extern void (*au1k_wait_ptr)(void); + void au1k_wait(void) { #ifdef CONFIG_PM @@ -90,7 +100,6 @@ static inline void check_wait(void) case CPU_R5000: case CPU_NEVADA: case CPU_RM7000: -/* case CPU_RM9000: */ case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: @@ -102,12 +111,19 @@ static inline void check_wait(void) cpu_wait = r4k_wait; printk(" available.\n"); break; +#ifdef CONFIG_PM case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: - cpu_wait = au1k_wait; - printk(" available.\n"); + if (au1k_wait_ptr != NULL) { + cpu_wait = au1k_wait_ptr; + printk(" available.\n"); + } + else { + printk(" unavailable.\n"); + } break; +#endif default: printk(" unavailable.\n"); break; @@ -238,8 +254,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - c->cputype = CPU_VR41XX; - break; + c->cputype = CPU_VR41XX; + break; } c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS; @@ -371,7 +387,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) c->cputype = CPU_RM9000; c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; + MIPS_CPU_LLSC; /* * Bit 29 in the info register of the RM9000 * indicates if the TLB has 48 or 64 entries. @@ -407,9 +423,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) MIPS_CPU_LLSC; c->tlbsize = 64; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -475,9 +488,6 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) /* Probe for L2 cache */ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -505,9 +515,6 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) break; } c->isa_level = MIPS_CPU_ISA_M32; - break; - default: - c->cputype = CPU_UNKNOWN; break; } } @@ -528,9 +535,6 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -542,14 +546,11 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) c->cputype = CPU_SR71000; c->isa_level = MIPS_CPU_ISA_M64; c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; c->scache.ways = 8; c->tlbsize = 64; break; - default: - c->cputype = CPU_UNKNOWN; - break; } } @@ -563,7 +564,6 @@ __init void cpu_probe(void) c->processor_id = read_c0_prid(); switch (c->processor_id & 0xff0000) { - case PRID_COMP_LEGACY: cpu_probe_legacy(c); break; diff --git a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c index 35818bb1a359..ffd216d6d6dc 100644 --- a/arch/mips/kernel/module-elf32.c +++ b/arch/mips/kernel/module-elf32.c @@ -248,14 +248,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, me->name); return -ENOEXEC; } - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c index da7295d53113..e804792ee1ee 100644 --- a/arch/mips/kernel/module-elf64.c +++ b/arch/mips/kernel/module-elf64.c @@ -272,14 +272,3 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return 0; } - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c new file mode 100644 index 000000000000..581687080082 --- /dev/null +++ b/arch/mips/kernel/module.c @@ -0,0 +1,53 @@ +#include +#include + +static LIST_HEAD(dbe_list); +static spinlock_t dbe_lock = SPIN_LOCK_UNLOCKED; + +/* Given an address, look for it in the module exception tables. */ +const struct exception_table_entry *search_module_dbetables(unsigned long addr) +{ + unsigned long flags; + const struct exception_table_entry *e = NULL; + struct mod_arch_specific *dbe; + + spin_lock_irqsave(&dbe_lock, flags); + list_for_each_entry(dbe, &dbe_list, dbe_list) { + e = search_extable(dbe->dbe_start, dbe->dbe_end - 1, addr); + if (e) + break; + } + spin_unlock_irqrestore(&dbe_lock, flags); + + /* Now, if we found one, we are running inside it now, hence + we cannot unload the module, hence no refcnt needed. */ + return e; +} + +/* Put in dbe list if neccessary. */ +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + const Elf_Shdr *s; + char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + INIT_LIST_HEAD(&me->arch.dbe_list); + for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { + if (strcmp("__dbe_table", secstrings + s->sh_name) != 0) + continue; + me->arch.dbe_start = (void *)s->sh_addr; + me->arch.dbe_end = (void *)s->sh_addr + s->sh_size; + spin_lock_irq(&dbe_lock); + list_add(&me->arch.dbe_list, &dbe_list); + spin_unlock_irq(&dbe_lock); + } + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ + spin_lock_irq(&dbe_lock); + list_del(&mod->arch.dbe_list); + spin_unlock_irq(&dbe_lock); +} diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 09477c1e3e7b..24eab2f9d7dd 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -627,6 +627,7 @@ out: jr ra sys sys_mq_timedreceive 5 sys sys_mq_notify 2 /* 4275 */ sys sys_mq_getsetattr 3 + sys sys_ni_syscall 0 /* sys_vserver */ .endm diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 19e430d62c47..3125b634faec 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -447,3 +447,4 @@ sys_call_table: PTR sys_mq_timedreceive PTR sys_mq_notify PTR sys_mq_getsetattr /* 5235 */ + PTR sys_ni_syscall /* sys_vserver */ diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 9993a8a15397..c00459f8f59d 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -357,3 +357,4 @@ EXPORT(sysn32_call_table) PTR compat_sys_mq_timedreceive PTR compat_sys_mq_notify PTR compat_sys_mq_getsetattr /* 6239 */ + PTR sys_ni_syscall /* sys_vserver */ diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b351656863af..3a89bf425bf6 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -535,6 +535,7 @@ out: jr ra sys compat_sys_mq_timedreceive 5 sys compat_sys_mq_notify 2 /* 4275 */ sys compat_sys_mq_getsetattr 3 + sys sys_ni_syscall 0 /* sys_vserver */ .endm diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c index 51c3e772c029..4197b4109dc3 100644 --- a/arch/mips/kernel/semaphore.c +++ b/arch/mips/kernel/semaphore.c @@ -1,273 +1,165 @@ /* - * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * MIPS-specific semaphore code. * - * Heavily inspired by the Alpha implementation + * Copyright (C) 1999 Cort Dougan + * Copyright (C) 2004 Ralf Baechle + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * April 2001 - Reworked by Paul Mackerras + * to eliminate the SMP races in the old version between the updates + * of `count' and `waking'. Now we use negative `count' values to + * indicate that some process(es) are waiting for the semaphore. */ + #include -#include #include -#include #include +#include +#include +#include +#include -#ifdef CONFIG_CPU_HAS_LLDSCD -/* - * On machines without lld/scd we need a spinlock to make the manipulation of - * sem->count and sem->waking atomic. Scalability isn't an issue because - * this lock is used on UP only so it's just an empty variable. - */ -spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; - -EXPORT_SYMBOL(semaphore_lock); -#endif +#ifdef CONFIG_CPU_HAS_LLSC /* - * Semaphores are implemented using a two-way counter: The "count" variable is - * decremented for each process that tries to sleep, while the "waking" variable - * is incremented when the "up()" code goes to wake up waiting processes. - * - * Notably, the inline "up()" and "down()" functions can efficiently test if - * they need to do any extra work (up needs to do something only if count was - * negative before the increment operation. - * - * waking_non_zero() must execute atomically. + * Atomically update sem->count. + * This does the equivalent of the following: * - * When __up() is called, the count was negative before incrementing it, and we - * need to wake up somebody. - * - * This routine adds one to the count of processes that need to wake up and - * exit. ALL waiting processes actually wake up but only the one that gets to - * the "waking" field first will gate through and acquire the semaphore. The - * others will go back to sleep. - * - * Note that these functions are only called when there is contention on the - * lock, and as such all this is the "non-critical" part of the whole semaphore - * business. The critical part is the inline stuff in where - * we want to avoid any extra jumps and calls. + * old_count = sem->count; + * tmp = MAX(old_count, 0) + incr; + * sem->count = tmp; + * return old_count; */ -void __up_wakeup(struct semaphore *sem) +static inline int __sem_update_count(struct semaphore *sem, int incr) { - wake_up(&sem->wait); -} - -EXPORT_SYMBOL(__up_wakeup); - -#ifdef CONFIG_CPU_HAS_LLSC - -static inline int waking_non_zero(struct semaphore *sem) -{ - int ret, tmp; + int old_count, tmp; __asm__ __volatile__( - "1: ll %1, %2 # waking_non_zero \n" - " blez %1, 2f \n" - " subu %0, %1, 1 \n" - " sc %0, %2 \n" - " beqz %0, 1b \n" - "2: \n" - : "=r" (ret), "=r" (tmp), "+m" (sem->waking) - : "0" (0)); - - return ret; + "1: ll %0, %2 \n" + " sra %1, %0, 31 \n" + " not %1 \n" + " and %1, %0, %1 \n" + " add %1, %1, %3 \n" + " sc %1, %2 \n" + " beqz %1, 1b \n" + : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) + : "r" (incr), "m" (sem->count)); + + return old_count; } -#else /* !CONFIG_CPU_HAS_LLSC */ +#else -static inline int waking_non_zero(struct semaphore *sem) +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + +static inline int __sem_update_count(struct semaphore *sem, int incr) { unsigned long flags; - int waking, ret = 0; + int old_count, tmp; spin_lock_irqsave(&semaphore_lock, flags); - waking = atomic_read(&sem->waking); - if (waking > 0) { - atomic_set(&sem->waking, waking - 1); - ret = 1; - } + old_count = atomic_read(&sem->count); + tmp = max_t(int, old_count, 0) + incr; + atomic_set(&sem->count, tmp); spin_unlock_irqrestore(&semaphore_lock, flags); - return ret; + return old_count; } -#endif /* !CONFIG_CPU_HAS_LLSC */ - -/* - * Perform the "down" function. Return zero for semaphore acquired, return - * negative for signalled out of the function. - * - * If called from down, the return is ignored and the wait loop is not - * interruptible. This means that a task waiting on a semaphore using "down()" - * cannot be killed until someone does an "up()" on the semaphore. - * - * If called from down_interruptible, the return value gets checked upon return. - * If the return value is negative then the task continues with the negative - * value in the return register (it can be tested by the caller). - * - * Either form may be used in conjunction with "up()". - */ +#endif -void __sched __down_failed(struct semaphore * sem) +void __up(struct semaphore *sem) { - struct task_struct *tsk = current; - wait_queue_t wait; - - init_waitqueue_entry(&wait, tsk); - __set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue_exclusive(&sem->wait, &wait); - /* - * Ok, we're set up. sem->count is known to be less than zero - * so we must wait. - * - * We can let go the lock for purposes of waiting. - * We re-acquire it after awaking so as to protect - * all semaphore operations. - * - * If "up()" is called before we call waking_non_zero() then - * we will catch it right away. If it is called later then - * we will have to go through a wakeup cycle to catch it. - * - * Multiple waiters contend for the semaphore lock to see - * who gets to gate through and who has to wait some more. + * Note that we incremented count in up() before we came here, + * but that was ineffective since the result was <= 0, and + * any negative value of count is equivalent to 0. + * This ends up setting count to 1, unless count is now > 0 + * (i.e. because some other cpu has called up() in the meantime), + * in which case we just increment count. */ - for (;;) { - if (waking_non_zero(sem)) - break; - schedule(); - __set_current_state(TASK_UNINTERRUPTIBLE); - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&sem->wait, &wait); + __sem_update_count(sem, 1); + wake_up(&sem->wait); } -EXPORT_SYMBOL(__down_failed); - -#ifdef CONFIG_CPU_HAS_LLDSCD +EXPORT_SYMBOL(__up); /* - * waking_non_zero_interruptible: - * 1 got the lock - * 0 go to sleep - * -EINTR interrupted - * - * We must undo the sem->count down_interruptible decrement - * simultaneously and atomically with the sem->waking adjustment, - * otherwise we can race with wake_one_more. - * - * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. - * - * This is crazy. Normally it's strictly forbidden to use 64-bit operations - * in the 32-bit MIPS kernel. In this case it's however ok because if an - * interrupt has destroyed the upper half of registers sc will fail. - * Note also that this will not work for MIPS32 CPUs! - * - * Pseudocode: - * - * If(sem->waking > 0) { - * Decrement(sem->waking) - * Return(SUCCESS) - * } else If(signal_pending(tsk)) { - * Increment(sem->count) - * Return(-EINTR) - * } else { - * Return(SLEEP) - * } + * Note that when we come in to __down or __down_interruptible, + * we have already decremented count, but that decrement was + * ineffective since the result was < 0, and any negative value + * of count is equivalent to 0. + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. */ - -static inline int -waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) -{ - long ret, tmp; - - __asm__ __volatile__( - " .set push # waking_non_zero_interruptible \n" - " .set mips3 \n" - " .set noat \n" - "0: lld %1, %2 \n" - " li %0, 0 \n" - " sll $1, %1, 0 \n" - " blez $1, 1f \n" - " daddiu %1, %1, -1 \n" - " li %0, 1 \n" - " b 2f \n" - "1: beqz %3, 2f \n" - " li %0, %4 \n" - " dli $1, 0x0000000100000000 \n" - " daddu %1, %1, $1 \n" - "2: scd %1, %2 \n" - " beqz %1, 0b \n" - " .set pop \n" - : "=&r" (ret), "=&r" (tmp), "=m" (*sem) - : "r" (signal_pending(tsk)), "i" (-EINTR)); - - return ret; -} - -#else /* !CONFIG_CPU_HAS_LLDSCD */ - -static inline int waking_non_zero_interruptible(struct semaphore *sem, - struct task_struct *tsk) +void __sched __down(struct semaphore *sem) { - int waking, pending, ret = 0; - unsigned long flags; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); - pending = signal_pending(tsk); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); - spin_lock_irqsave(&semaphore_lock, flags); - waking = atomic_read(&sem->waking); - if (waking > 0) { - atomic_set(&sem->waking, waking - 1); - ret = 1; - } else if (pending) { - atomic_set(&sem->count, atomic_read(&sem->count) + 1); - ret = -EINTR; + /* + * Try to get the semaphore. If the count is > 0, then we've + * got the semaphore; we decrement count and exit the loop. + * If the count is 0 or negative, we set it to -1, indicating + * that we are asleep, and then sleep. + */ + while (__sem_update_count(sem, -1) <= 0) { + schedule(); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); } - spin_unlock_irqrestore(&semaphore_lock, flags); + remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); - return ret; + /* + * If there are any more sleepers, wake one of them up so + * that it can either get the semaphore, or set count to -1 + * indicating that there are still processes sleeping. + */ + wake_up(&sem->wait); } -#endif /* !CONFIG_CPU_HAS_LLDSCD */ +EXPORT_SYMBOL(__down); -int __sched __down_failed_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { + int retval = 0; struct task_struct *tsk = current; - wait_queue_t wait; - int ret = 0; + DECLARE_WAITQUEUE(wait, tsk); - init_waitqueue_entry(&wait, tsk); - __set_current_state(TASK_INTERRUPTIBLE); + __set_task_state(tsk, TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); - /* - * Ok, we're set up. sem->count is known to be less than zero - * so we must wait. - * - * We can let go the lock for purposes of waiting. - * We re-acquire it after awaking so as to protect - * all semaphore operations. - * - * If "up()" is called before we call waking_non_zero() then - * we will catch it right away. If it is called later then - * we will have to go through a wakeup cycle to catch it. - * - * Multiple waiters contend for the semaphore lock to see - * who gets to gate through and who has to wait some more. - */ - for (;;) { - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; + while (__sem_update_count(sem, -1) <= 0) { + if (signal_pending(current)) { + /* + * A signal is pending - give up trying. + * Set sem->count to 0 if it is negative, + * since we are no longer sleeping. + */ + __sem_update_count(sem, 0); + retval = -EINTR; break; } schedule(); - __set_current_state(TASK_INTERRUPTIBLE); + set_task_state(tsk, TASK_INTERRUPTIBLE); } - __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); + __set_task_state(tsk, TASK_RUNNING); - return ret; + wake_up(&sem->wait); + return retval; } -EXPORT_SYMBOL(__down_failed_interruptible); +EXPORT_SYMBOL(__down_interruptible); diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 8a5acf174730..c7d1d76c9c8b 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -452,14 +452,18 @@ static void __init do_earlyinitcalls(void) void __init setup_arch(char **cmdline_p) { + unsigned int status; + cpu_probe(); prom_init(); cpu_report(); #ifdef CONFIG_MIPS32 /* Disable coprocessors and set FPU for 16/32 FPR register model */ - clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); - set_c0_status(ST0_CU0); + status = read_c0_status(); + status &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); + status |= ST0_CU0; + write_c0_status(status); #endif #ifdef CONFIG_MIPS64 /* @@ -467,8 +471,10 @@ void __init setup_arch(char **cmdline_p) * Maybe because the kernel is in ckseg0 and not xkphys? Clear it * anyway ... */ - clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); - set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + status = read_c0_status(); + status &= ~(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); + status |= (ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + write_c0_status(status); #endif #if defined(CONFIG_VT) diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 7e1eca9736b1..16519f7e8c3b 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -36,7 +36,7 @@ #include #include -asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs) +asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs) { int fd[2]; int error, res; diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 25d7e97edfca..494d1872df32 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -1639,7 +1639,7 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf) printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n", current->comm, current->pid, fname, buf); - error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); + error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64)); if(error) goto out; error = user_path_walk(fname, &nd); diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index d0c980a9b859..0199485a4a8f 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -789,3 +789,8 @@ EXPORT_SYMBOL(rtc_lock); EXPORT_SYMBOL(to_tm); EXPORT_SYMBOL(rtc_set_time); EXPORT_SYMBOL(rtc_get_time); + +unsigned long long sched_clock(void) +{ + return (unsigned long long)jiffies*(1000000000/HZ); +} diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 752dbd3e93fb..362c1fd66b12 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -234,6 +234,7 @@ void show_regs(struct pt_regs *regs) void show_registers(struct pt_regs *regs) { show_regs(regs); + print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", current->comm, current->pid, current_thread_info(), current); show_stack(current, (long *) regs->regs[29]); @@ -278,47 +279,8 @@ void __declare_dbe_table(void) ); } -#ifdef CONFIG_MDULES - -/* Given an address, look for it in the module exception tables. */ -const struct exception_table_entry *search_module_dbetables(unsigned long addr) -{ - unsigned long flags; - const struct exception_table_entry *e = NULL; - struct module *mod; - - spin_lock_irqsave(&modlist_lock, flags); - list_for_each_entry(mod, &modules, list) { - if (mod->arch.num_dbeentries == 0) - continue; - - e = search_extable(mod->arch.dbe_table_start, - mod->arch.dbe_table_end + - mod->arch.num_dbeentries - 1, - addr); - if (e) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - - /* Now, if we found one, we are running inside it now, hence - we cannot unload the module, hence no refcnt needed. */ - return e; -} - -#else - /* Given an address, look for it in the exception tables. */ -static inline const struct exception_table_entry * -search_module_dbetables(unsigned long addr) -{ - return NULL; -} - -#endif - -/* Given an address, look for it in the exception tables. */ -const struct exception_table_entry *search_dbe_tables(unsigned long addr) +static const struct exception_table_entry *search_dbe_tables(unsigned long addr) { const struct exception_table_entry *e; @@ -745,12 +707,25 @@ asmlinkage void do_reserved(struct pt_regs *regs) static inline void parity_protection_init(void) { switch (current_cpu_data.cputype) { + case CPU_24K: + /* 24K cache parity not currently implemented in FPGA */ + printk(KERN_INFO "Disable cache parity protection for " + "MIPS 24K CPU.\n"); + write_c0_ecc(read_c0_ecc() & ~0x80000000); + break; case CPU_5KC: /* Set the PE bit (bit 31) in the c0_ecc register. */ - printk(KERN_INFO "Enable the cache parity protection for " - "MIPS 5KC CPUs.\n"); + printk(KERN_INFO "Enable cache parity protection for " + "MIPS 5KC/24K CPUs.\n"); write_c0_ecc(read_c0_ecc() | 0x80000000); break; + case CPU_20KC: + case CPU_25KF: + /* Clear the DE bit (bit 16) in the c0_status register. */ + printk(KERN_INFO "Enable cache parity protection for " + "MIPS 20KC/25KF CPUs.\n"); + clear_c0_status(ST0_DE); + break; default: break; } diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile index 1bde2a003249..fd6a2bafdfcf 100644 --- a/arch/mips/lib-32/Makefile +++ b/arch/mips/lib-32/Makefile @@ -4,10 +4,22 @@ lib-y += csum_partial.o memset.o watch.o -ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) - lib-y += r3k_dump_tlb.o -else - lib-y += dump_tlb.o -endif +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile index 1bde2a003249..fd6a2bafdfcf 100644 --- a/arch/mips/lib-64/Makefile +++ b/arch/mips/lib-64/Makefile @@ -4,10 +4,22 @@ lib-y += csum_partial.o memset.o watch.o -ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) - lib-y += r3k_dump_tlb.o -else - lib-y += dump_tlb.o -endif +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c index c1b46edc6ed9..1871c30ed2eb 100644 --- a/arch/mips/mips-boards/generic/cmdline.c +++ b/arch/mips/mips-boards/generic/cmdline.c @@ -51,7 +51,9 @@ void __init prom_init_cmdline(void) *cp++ = ' '; actr++; } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + if (cp != &(arcs_cmdline[0])) { + /* get rid of trailing space */ --cp; - *cp = '\0'; + *cp = '\0'; + } } diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c index b1edd90b9805..2c1ab1f19fdc 100644 --- a/arch/mips/mips-boards/generic/printf.c +++ b/arch/mips/mips-boards/generic/printf.c @@ -59,7 +59,7 @@ static inline void serial_out(int offset, int value) outb(value, PORT(offset)); } -int putPromChar(char c) +int prom_putchar(char c) { while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; @@ -69,7 +69,7 @@ int putPromChar(char c) return 1; } -char getPromChar(void) +char prom_getchar(void) { while (!(serial_in(UART_LSR) & UART_LSR_DR)) ; @@ -77,33 +77,3 @@ char getPromChar(void) return serial_in(UART_RX); } -static spinlock_t con_lock = SPIN_LOCK_UNLOCKED; - -static char buf[1024]; - -void __init prom_printf(char *fmt, ...) -{ - va_list args; - int l; - char *p, *buf_end; - long flags; - - spin_lock_irqsave(con_lock, flags); - - va_start(args, fmt); - l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ - va_end(args); - - buf_end = buf + l; - - for (p = buf; p < buf_end; p++) { - /* Crude cr/nl handling is better than none */ - if (*p == '\n') - putPromChar('\r'); - putPromChar(*p); - } - /* wait for output to drain */ - while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0) - ; - spin_unlock_irqrestore(con_lock, flags); -} diff --git a/arch/mips/mm-32/Makefile b/arch/mips/mm-32/Makefile deleted file mode 100644 index 956f4bb8a29d..000000000000 --- a/arch/mips/mm-32/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# Makefile for the Linux/MIPS-specific parts of the memory manager. -# - -obj-$(CONFIG_CPU_TX49XX) += tlbex-r4k.o -obj-$(CONFIG_CPU_R4300) += tlbex-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlbex-r4k.o -obj-$(CONFIG_CPU_VR41XX) += tlbex-r4k.o -obj-$(CONFIG_CPU_R5000) += tlbex-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlbex-r4k.o -obj-$(CONFIG_CPU_R5432) += tlbex-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlbex-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlbex-r4k.o -obj-$(CONFIG_CPU_R10000) += tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS32) += tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS64) += tlbex-r4k.o -obj-$(CONFIG_CPU_SB1) += tlbex-r4k.o - -EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/mm-32/tlbex-r4k.S b/arch/mips/mm-32/tlbex-r4k.S deleted file mode 100644 index 49742718da0a..000000000000 --- a/arch/mips/mm-32/tlbex-r4k.S +++ /dev/null @@ -1,524 +0,0 @@ -/* - * TLB exception handling code for r4k. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-cpu abstraction and reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define PTE_L ld -#define PTE_S sd -#define PTE_SRL dsrl -#define P_MTC0 dmtc0 -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 -#else -#define PTE_L lw -#define PTE_S sw -#define PTE_SRL srl -#define P_MTC0 mtc0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 -#endif - -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ - PTE_L ptr, 0(ptr); \ - PTE_SRL tmp, tmp, 6; \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_SRL ptr, ptr, 6; \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - - __INIT - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define GET_PTE_OFF(reg) -#elif CONFIG_CPU_VR41XX -#define GET_PTE_OFF(reg) srl reg, reg, 3 -#else -#define GET_PTE_OFF(reg) srl reg, reg, 1 -#endif - -/* - * These handlers much be written in a relocatable manner - * because based upon the cpu type an arbitrary one of the - * following pieces of code will be copied to the KSEG0 - * vector location. - */ - /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ - .set noreorder - .set noat - LEAF(except_vec0_r4000) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - mtc0_tlbw_hazard - tlbwr # write random tlb entry - tlbw_eret_hazard - eret # return from trap - END(except_vec0_r4000) - - /* TLB refill, EXL == 0, R4600 version */ - LEAF(except_vec0_r4600) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - P_MTC0 k1, CP0_ENTRYLO1 - nop - tlbwr - nop - eret - END(except_vec0_r4600) - - /* TLB refill, EXL == 0, R52x0 "Nevada" version */ - /* - * This version has a bug workaround for the Nevada. It seems - * as if under certain circumstances the move from cp0_context - * might produce a bogus result when the mfc0 instruction and - * it's consumer are in a different cacheline or a load instruction, - * probably any memory reference, is between them. This is - * potencially slower than the R4000 version, so we use this - * special version. - */ - .set noreorder - .set noat - LEAF(except_vec0_nevada) - .set mips3 - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - lw k1, pgd_current # get pgd pointer - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 # add in pgd offset - lw k1, (k1) - mfc0 k0, CP0_CONTEXT # get context reg - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - nop # QED specified nops - nop - tlbwr # write random tlb entry - nop # traditional nop - eret # return from trap - END(except_vec0_nevada) - - /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ - LEAF(except_vec0_sb1) -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - bnez k0, 1f -#endif - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, _PGDIR_SHIFT # get pgd only bits - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) - GET_PTE_OFF(k0) # get pte offset - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 # add in offset - PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte - PTE_SRL k0, k0, 6 # convert to entrylo0 - P_MTC0 k0, CP0_ENTRYLO0 # load it - PTE_SRL k1, k1, 6 # convert to entrylo1 - P_MTC0 k1, CP0_ENTRYLO1 # load it - tlbwr # write random tlb entry -1: eret # return from trap - END(except_vec0_sb1) - - /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ - LEAF(except_vec0_r45k_bvahwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - mfc0 k0, CP0_INDEX - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r45k_bvahwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ - LEAF(except_vec0_r4k_mphwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - mfc0 k0, CP0_INDEX - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_mphwbug) -#endif - - /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ - LEAF(except_vec0_r4k_250MHZhwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - PTE_SRL k0, k0, 6 - P_MTC0 zero, CP0_ENTRYLO0 - P_MTC0 k0, CP0_ENTRYLO0 - PTE_SRL k1, k1, 6 - P_MTC0 zero, CP0_ENTRYLO1 - P_MTC0 k1, CP0_ENTRYLO1 - b 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_250MHZhwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ - LEAF(except_vec0_r4k_MP250MHZhwbug) - .set mips3 - GET_PGD(k0, k1) # get pgd pointer - mfc0 k0, CP0_BADVADDR - srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif - and k0, k0, PTEP_INDX_MSK - addu k1, k1, k0 - PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) - nop /* XXX */ - tlbp - PTE_SRL k0, k0, 6 - P_MTC0 zero, CP0_ENTRYLO0 - P_MTC0 k0, CP0_ENTRYLO0 - mfc0 k0, CP0_INDEX - PTE_SRL k1, k1, 6 - P_MTC0 zero, CP0_ENTRYLO1 - P_MTC0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_MP250MHZhwbug) -#endif - - __FINIT - - .set noreorder - -/* - * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: - * 2. A timing hazard exists for the TLBP instruction. - * - * stalling_instruction - * TLBP - * - * The JTLB is being read for the TLBP throughout the stall generated by the - * previous instruction. This is not really correct as the stalling instruction - * can modify the address used to access the JTLB. The failure symptom is that - * the TLBP instruction will use an address created for the stalling instruction - * and not the address held in C0_ENHI and thus report the wrong results. - * - * The software work-around is to not allow the instruction preceding the TLBP - * to stall - make it an NOP or some other instruction guaranteed not to stall. - * - * Errata 2 will not be fixed. This errata is also on the R5000. - * - * As if we MIPS hackers wouldn't know how to nop pipelines happy ... - */ -#define R5K_HAZARD nop - - /* - * Note for many R4k variants tlb probes cannot be executed out - * of the instruction cache else you get bogus results. - */ - .align 5 - NESTED(handle_tlbl, PT_SIZE, sp) - .set noat -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - beqz k0, 1f - nop - .set mips3 - eret - .set mips0 -1: -#endif -invalid_tlbl: -#ifdef TLB_OPTIMIZE - .set mips3 - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbl: - DO_FAULT(0) - END(handle_tlbl) - - .align 5 - NESTED(handle_tlbs, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - li k0,0 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbs: - DO_FAULT(1) - END(handle_tlbs) - - .align 5 - NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - PTE_L k0, (k1) - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nowrite_mod: - DO_FAULT(1) - END(handle_mod) diff --git a/arch/mips/mm-64/Makefile b/arch/mips/mm-64/Makefile deleted file mode 100644 index 30b4d332e7ec..000000000000 --- a/arch/mips/mm-64/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# -# Makefile for the Linux/MIPS-specific parts of the memory manager. -# - -obj-y := tlbex-r4k.o - -obj-$(CONFIG_CPU_R4300) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5432) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_R10000) += tlb-glue-r4k.o -obj-$(CONFIG_CPU_SB1) += tlb-glue-sb1.o -obj-$(CONFIG_CPU_MIPS64) += tlb-glue-r4k.o - -# -# Debug TLB exception handler, currently unused -# -#obj-y += tlb-dbg-r4k.o - -AFLAGS_tlb-glue-r4k.o := -P - -EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/mm-64/tlb-dbg-r4k.c b/arch/mips/mm-64/tlb-dbg-r4k.c deleted file mode 100644 index 44e64f7ca420..000000000000 --- a/arch/mips/mm-64/tlb-dbg-r4k.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - * - * TLB debugging routines. These perform horribly slow but can easily be - * modified for debugging purposes. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, - unsigned long address); - -asmlinkage void tlb_refill_debug(struct pt_regs regs) -{ - show_regs(®s); - panic("%s called. This Does Not Happen (TM).", __FUNCTION__); -} - -asmlinkage void xtlb_refill_debug(struct pt_regs *regs) -{ - unsigned long addr; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1); - pgd = pgd_offset(current->active_mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - - write_c0_entrylo0(pte_val(pte[0]) >> 6); - write_c0_entrylo1(pte_val(pte[1]) >> 6); - __asm__ __volatile__("nop;nop;nop"); - - tlb_write_random(); -} - -asmlinkage void xtlb_mod_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} - -asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 0, addr); -} - -asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} diff --git a/arch/mips/mm-64/tlb-glue-r4k.S b/arch/mips/mm-64/tlb-glue-r4k.S deleted file mode 100644 index 4e0194aa58f1..000000000000 --- a/arch/mips/mm-64/tlb-glue-r4k.S +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 - tlb_handler xtlb_tlbl kmode 0 - tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm-64/tlb-glue-sb1.S b/arch/mips/mm-64/tlb-glue-sb1.S deleted file mode 100644 index 3c236539f423..000000000000 --- a/arch/mips/mm-64/tlb-glue-sb1.S +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - .macro tlb_handler_m3 name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, PAGE_SHIFT + 1 - bnez k0, 1f - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault -1: - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 -#if BCM1250_M3_WAR - tlb_handler_m3 xtlb_tlbl kmode 0 -#else - tlb_handler xtlb_tlbl kmode 0 -#endif - tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm-64/tlbex-r4k.S b/arch/mips/mm-64/tlbex-r4k.S deleted file mode 100644 index 728d18f004d2..000000000000 --- a/arch/mips/mm-64/tlbex-r4k.S +++ /dev/null @@ -1,203 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * Copyright (C) 2002 Maciej W. Rozycki - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define _VMALLOC_START 0xc000000000000000 - - /* - * After this macro runs we have a pointer to the pte of the address - * that caused the fault in PTR. - */ - .macro LOAD_PTE2, ptr, tmp, kaddr -#ifdef CONFIG_SMP - dmfc0 \ptr, CP0_CONTEXT - dmfc0 \tmp, CP0_BADVADDR - dsra \ptr, 23 # get pgd_current[cpu] -#else - dmfc0 \tmp, CP0_BADVADDR - dla \ptr, pgd_current -#endif - bltz \tmp, \kaddr - ld \ptr, (\ptr) - dsrl \tmp, (_PGDIR_SHIFT-3) # get pgd offset in bytes - andi \tmp, ((_PTRS_PER_PGD - 1)<<3) - daddu \ptr, \tmp # add in pgd offset - dmfc0 \tmp, CP0_BADVADDR - ld \ptr, (\ptr) # get pmd pointer - dsrl \tmp, (_PMD_SHIFT-3) # get pmd offset in bytes - andi \tmp, ((_PTRS_PER_PMD - 1)<<3) - daddu \ptr, \tmp # add in pmd offset - dmfc0 \tmp, CP0_XCONTEXT - ld \ptr, (\ptr) # get pte pointer - andi \tmp, 0xff0 # get pte offset - daddu \ptr, \tmp - .endm - - - /* - * Ditto for the kernel table. - */ - .macro LOAD_KPTE2, ptr, tmp, not_vmalloc - /* - * First, determine that the address is in/above vmalloc range. - */ - dmfc0 \tmp, CP0_BADVADDR - dli \ptr, _VMALLOC_START - - /* - * Now find offset into kptbl. - */ - dsubu \tmp, \tmp, \ptr - dla \ptr, kptbl - dsrl \tmp, (_PAGE_SHIFT+1) # get vpn2 - dsll \tmp, 4 # byte offset of pte - daddu \ptr, \ptr, \tmp - - /* - * Determine that fault address is within vmalloc range. - */ - dla \tmp, ekptbl - slt \tmp, \ptr, \tmp - beqz \tmp, \not_vmalloc # not vmalloc - nop - .endm - - - /* - * This places the even/odd pte pair in the page table at the pte - * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. - */ - .macro PTE_RELOAD, pte0, pte1 - dsrl \pte0, 6 # convert to entrylo0 - dmtc0 \pte0, CP0_ENTRYLO0 # load it - dsrl \pte1, 6 # convert to entrylo1 - dmtc0 \pte1, CP0_ENTRYLO1 # load it - .endm - - - .text - .set noreorder - .set mips3 - - __INIT - - /* - * TLB refill handlers for the R4000 and SB1. - * Attention: We may only use 32 instructions / 128 bytes. - */ - .align 5 -LEAF(except_vec1_r4k) - .set noat - dla k0, handle_vec1_r4k - jr k0 - nop -END(except_vec1_r4k) - -LEAF(except_vec1_sb1) -#if BCM1250_M3_WAR - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, _PAGE_SHIFT+1 - bnez k0, 1f -#endif - .set noat - dla k0, handle_vec1_r4k - jr k0 - nop - -1: eret - nop -END(except_vec1_sb1) - - __FINIT - - .align 5 -LEAF(handle_vec1_r4k) - .set noat - LOAD_PTE2 k1 k0 9f - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - mtc0_tlbw_hazard - tlbwr - tlbw_eret_hazard - eret - -9: # handle the vmalloc range - LOAD_KPTE2 k1 k0 invalid_vmalloc_address - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - mtc0_tlbw_hazard - tlbwr - tlbw_eret_hazard - eret -END(handle_vec1_r4k) - - - __INIT - - /* - * TLB refill handler for the R10000. - * Attention: We may only use 32 instructions / 128 bytes. - */ - .align 5 -LEAF(except_vec1_r10k) - .set noat - dla k0, handle_vec1_r10k - jr k0 - nop -END(except_vec1_r10k) - - __FINIT - - .align 5 -LEAF(handle_vec1_r10k) - .set noat - LOAD_PTE2 k1 k0 9f - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret - -9: # handle the vmalloc range - LOAD_KPTE2 k1 k0 invalid_vmalloc_address - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret -END(handle_vec1_r10k) - - - .align 5 -LEAF(invalid_vmalloc_address) - .set noat - SAVE_ALL - CLI - dmfc0 t0, CP0_BADVADDR - sd t0, PT_BVADDR(sp) - move a0, sp - jal show_regs - PANIC("Invalid kernel address") -END(invalid_vmalloc_address) diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 2fdae0a8739f..04c393f26228 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -12,19 +12,54 @@ obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-andes.o -obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o tlbex-r3k.o +obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o +obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_SB1) += c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \ tlb-sb1.o -obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o +# +# TLB exception handling code differs between 32-bit and 64-bit kernels. +# +ifdef CONFIG_MIPS32 +obj-$(CONFIG_CPU_R3000) += tlbex32-r3k.o +obj-$(CONFIG_CPU_TX49XX) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R4300) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R4X00) += tlbex32-r4k.o +obj-$(CONFIG_CPU_VR41XX) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R5000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_NEVADA) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R5432) += tlbex32-r4k.o +obj-$(CONFIG_CPU_RM7000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_RM9000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_R10000) += tlbex32-r4k.o +obj-$(CONFIG_CPU_MIPS32) += tlbex32-r4k.o +obj-$(CONFIG_CPU_MIPS64) += tlbex32-r4k.o +obj-$(CONFIG_CPU_SB1) += tlbex32-r4k.o +obj-$(CONFIG_CPU_TX39XX) += tlbex32-r3k.o +endif +ifdef CONFIG_MIPS64 +obj-$(CONFIG_CPU_R4300) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R4X00) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R5000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_NEVADA) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R5432) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_RM7000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_RM9000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_R10000) += tlb64-glue-r4k.o tlbex64-r4k.o +obj-$(CONFIG_CPU_SB1) += tlb64-glue-sb1.o tlbex64-r4k.o +obj-$(CONFIG_CPU_MIPS64) += tlb64-glue-r4k.o tlbex64-r4k.o +endif + + obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c new file mode 100644 index 000000000000..daac80ea3c0a --- /dev/null +++ b/arch/mips/mm/tlb-r8k.c @@ -0,0 +1,253 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern void except_vec0_generic(void); +extern void except_vec1_r8k(void); + +#define TFP_TLB_SIZE 384 +#define TFP_TLB_SET_SHIFT 7 + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi(); + write_c0_entrylo(0); + + for (entry = 0; entry < TFP_TLB_SIZE; entry++) { + write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT); + write_c0_vaddr(entry << PAGE_SHIFT); + write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); + mtc0_tlbw_hazard(); + tlb_write(); + } + tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) + drop_mmu_context(mm,cpu); +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + unsigned long flags; + int oldpid, newpid, size; + + if (!cpu_context(cpu, mm)) + return; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + local_irq_save(flags); + + if (size > TFP_TLB_SIZE / 2) { + drop_mmu_context(mm, cpu); + goto out_restore; + } + + oldpid = read_c0_entryhi(); + newpid = cpu_asid(cpu, mm); + + write_c0_entrylo(0); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + while (start < end) { + signed long idx; + + write_c0_vaddr(start); + write_c0_entryhi(start); + start += PAGE_SIZE; + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + continue; + + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + } + write_c0_entryhi(oldpid); + +out_restore: + local_irq_restore(flags); +} + +/* Usable for KV1 addresses only! */ +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + if (size > TFP_TLB_SIZE / 2) { + local_flush_tlb_all(); + return; + } + + local_irq_save(flags); + + write_c0_entrylo(0); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + while (start < end) { + signed long idx; + + write_c0_vaddr(start); + write_c0_entryhi(start); + start += PAGE_SIZE; + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + continue; + + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + } + + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + int cpu = smp_processor_id(); + unsigned long flags; + int oldpid, newpid; + signed long idx; + + if (!cpu_context(cpu, vma->vm_mm)) + return; + + newpid = cpu_asid(cpu, vma->vm_mm); + page &= PAGE_MASK; + local_irq_save(flags); + oldpid = read_c0_entryhi(); + write_c0_vaddr(page); + write_c0_entryhi(newpid); + tlb_probe(); + idx = read_c0_tlbset(); + if (idx < 0) + goto finish; + + write_c0_entrylo(0); + write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); + tlb_write(); + +finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} + +/* + * We will need multiple versions of update_mmu_cache(), one that just + * updates the TLB with the new pte(s), and another which also checks + * for the R4k "end of page" hardware bug and does the needy. + */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + address &= PAGE_MASK; + write_c0_vaddr(address); + write_c0_entryhi(pid); + pgdp = pgd_offset(vma->vm_mm, address); + pmdp = pmd_offset(pgdp, address); + ptep = pte_offset_map(pmdp, address); + tlb_probe(); + + write_c0_entrylo(pte_val(*ptep++) >> 6); + tlb_write(); + + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +static void __init probe_tlb(unsigned long config) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->tlbsize = 3 * 128; /* 3 sets each 128 entries */ +} + +void __init tlb_init(void) +{ + unsigned int config = read_c0_config(); + unsigned long status; + + probe_tlb(config); + + status = read_c0_status(); + status &= ~(ST0_UPS | ST0_KPS); +#ifdef CONFIG_PAGE_SIZE_4KB + status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36); +#elif defined(CONFIG_PAGE_SIZE_8KB) + status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36); +#elif defined(CONFIG_PAGE_SIZE_16KB) + status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36); +#elif defined(CONFIG_PAGE_SIZE_64KB) + status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36); +#endif + write_c0_status(status); + + write_c0_wired(0); + + local_flush_tlb_all(); + + memcpy((void *)(CKSEG0 + 0x00), &except_vec0_generic, 0x80); + memcpy((void *)(CKSEG0 + 0x80), except_vec1_r8k, 0x80); + flush_icache_range(CKSEG0 + 0x80, CKSEG0 + 0x100); +} diff --git a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c index e2096dc21ac0..33c177e65908 100644 --- a/arch/mips/mm/tlb-sb1.c +++ b/arch/mips/mm/tlb-sb1.c @@ -125,7 +125,7 @@ void local_flush_tlb_all(void) * with the firmware, go back and give all the entries invalid addresses with * the normal flush routine. Wired entries will be killed as well! */ -void sb1_sanitize_tlb(void) +static void __init sb1_sanitize_tlb(void) { int entry; long addr = 0; diff --git a/arch/mips/mm/tlb64-glue-r4k.S b/arch/mips/mm/tlb64-glue-r4k.S new file mode 100644 index 000000000000..4e0194aa58f1 --- /dev/null +++ b/arch/mips/mm/tlb64-glue-r4k.S @@ -0,0 +1,41 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 + tlb_handler xtlb_tlbl kmode 0 + tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm/tlb64-glue-sb1.S b/arch/mips/mm/tlb64-glue-sb1.S new file mode 100644 index 000000000000..3c236539f423 --- /dev/null +++ b/arch/mips/mm/tlb64-glue-sb1.S @@ -0,0 +1,66 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + .macro tlb_handler_m3 name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT + 1 + bnez k0, 1f + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault +1: + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 +#if BCM1250_M3_WAR + tlb_handler_m3 xtlb_tlbl kmode 0 +#else + tlb_handler xtlb_tlbl kmode 0 +#endif + tlb_handler xtlb_tlbs kmode 1 diff --git a/arch/mips/mm/tlbex-r3k.S b/arch/mips/mm/tlbex-r3k.S deleted file mode 100644 index cc4a4642e28c..000000000000 --- a/arch/mips/mm/tlbex-r3k.S +++ /dev/null @@ -1,224 +0,0 @@ -/* - * TLB exception handling code for R2000/R3000. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-CPU abstraction reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Further modifications to make this work: - * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov - * Copyright (c) 2001 Ralf Baechle - * Copyright (c) 2001 MIPS Technologies, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - - .text - .set mips1 - .set noreorder - - __INIT - - /* TLB refill, R[23]00 version */ - LEAF(except_vec0_r2300) - .set noat - .set mips1 - mfc0 k0, CP0_BADVADDR - lw k1, pgd_current # get pgd pointer - srl k0, k0, 22 - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - and k0, k0, 0xffc - addu k1, k1, k0 - lw k0, (k1) - nop - mtc0 k0, CP0_ENTRYLO0 - mfc0 k1, CP0_EPC - tlbwr - jr k1 - rfe - END(except_vec0_r2300) - - __FINIT - - /* ABUSE of CPP macros 101. */ - - /* After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ -#define LOAD_PTE(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, pgd_current; \ - srl pte, pte, 22; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_CONTEXT; \ - lw ptr, (ptr); \ - andi pte, pte, 0xffc; \ - addu ptr, ptr, pte; \ - lw pte, (ptr); \ - nop; - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr) \ - lw ptr, (ptr) ; \ - nop ; \ - mtc0 ptr, CP0_ENTRYLO0; \ - nop; - -#define DO_FAULT(write) \ - .set noat; \ - .set macro; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; \ - .set nomacro; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - sw pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - sw pte, (ptr); - -/* - * The index register may have the probe fail bit set, - * because we would trap on access kseg2, i.e. without refill. - */ -#define TLB_WRITE(reg) \ - mfc0 reg, CP0_INDEX; \ - nop; \ - bltz reg, 1f; \ - nop; \ - tlbwi; \ - j 2f; \ - nop; \ -1: tlbwr; \ -2: - -#define RET(reg) \ - mfc0 reg, CP0_EPC; \ - nop; \ - jr reg; \ - rfe - - .set noreorder - - .align 5 -NESTED(handle_tlbl, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbl: -#endif - - DO_FAULT(0) -END(handle_tlbl) - -NESTED(handle_tlbs, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbs: -#endif - - DO_FAULT(1) -END(handle_tlbs) - - .align 5 -NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - .set push - .set reorder - lw k0, (k1) - .set pop - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1) - tlbwi - RET(k0) -#endif - -nowrite_mod: - DO_FAULT(1) -END(handle_mod) diff --git a/arch/mips/mm/tlbex32-r3k.S b/arch/mips/mm/tlbex32-r3k.S new file mode 100644 index 000000000000..cc4a4642e28c --- /dev/null +++ b/arch/mips/mm/tlbex32-r3k.S @@ -0,0 +1,224 @@ +/* + * TLB exception handling code for R2000/R3000. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-CPU abstraction reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Further modifications to make this work: + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov + * Copyright (c) 2001 Ralf Baechle + * Copyright (c) 2001 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + + .text + .set mips1 + .set noreorder + + __INIT + + /* TLB refill, R[23]00 version */ + LEAF(except_vec0_r2300) + .set noat + .set mips1 + mfc0 k0, CP0_BADVADDR + lw k1, pgd_current # get pgd pointer + srl k0, k0, 22 + sll k0, k0, 2 + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + and k0, k0, 0xffc + addu k1, k1, k0 + lw k0, (k1) + nop + mtc0 k0, CP0_ENTRYLO0 + mfc0 k1, CP0_EPC + tlbwr + jr k1 + rfe + END(except_vec0_r2300) + + __FINIT + + /* ABUSE of CPP macros 101. */ + + /* After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ +#define LOAD_PTE(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, pgd_current; \ + srl pte, pte, 22; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_CONTEXT; \ + lw ptr, (ptr); \ + andi pte, pte, 0xffc; \ + addu ptr, ptr, pte; \ + lw pte, (ptr); \ + nop; + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr) \ + lw ptr, (ptr) ; \ + nop ; \ + mtc0 ptr, CP0_ENTRYLO0; \ + nop; + +#define DO_FAULT(write) \ + .set noat; \ + .set macro; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; \ + .set nomacro; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + sw pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + sw pte, (ptr); + +/* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ +#define TLB_WRITE(reg) \ + mfc0 reg, CP0_INDEX; \ + nop; \ + bltz reg, 1f; \ + nop; \ + tlbwi; \ + j 2f; \ + nop; \ +1: tlbwr; \ +2: + +#define RET(reg) \ + mfc0 reg, CP0_EPC; \ + nop; \ + jr reg; \ + rfe + + .set noreorder + + .align 5 +NESTED(handle_tlbl, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbl: +#endif + + DO_FAULT(0) +END(handle_tlbl) + +NESTED(handle_tlbs, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbs: +#endif + + DO_FAULT(1) +END(handle_tlbs) + + .align 5 +NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + .set push + .set reorder + lw k0, (k1) + .set pop + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1) + tlbwi + RET(k0) +#endif + +nowrite_mod: + DO_FAULT(1) +END(handle_mod) diff --git a/arch/mips/mm/tlbex32-r4k.S b/arch/mips/mm/tlbex32-r4k.S new file mode 100644 index 000000000000..49742718da0a --- /dev/null +++ b/arch/mips/mm/tlbex32-r4k.S @@ -0,0 +1,524 @@ +/* + * TLB exception handling code for r4k. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-cpu abstraction and reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PTE_L ld +#define PTE_S sd +#define PTE_SRL dsrl +#define P_MTC0 dmtc0 +#define PTE_SIZE 8 +#define PTEP_INDX_MSK 0xff0 +#define PTE_INDX_MSK 0xff8 +#define PTE_INDX_SHIFT 9 +#else +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_SIZE 4 +#define PTEP_INDX_MSK 0xff8 +#define PTE_INDX_MSK 0xffc +#define PTE_INDX_SHIFT 10 +#endif + +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, _PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, PTE_SIZE(ptr); \ + PTE_L ptr, 0(ptr); \ + PTE_SRL tmp, tmp, 6; \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_SRL ptr, ptr, 6; \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + + __INIT + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define GET_PTE_OFF(reg) +#elif CONFIG_CPU_VR41XX +#define GET_PTE_OFF(reg) srl reg, reg, 3 +#else +#define GET_PTE_OFF(reg) srl reg, reg, 1 +#endif + +/* + * These handlers much be written in a relocatable manner + * because based upon the cpu type an arbitrary one of the + * following pieces of code will be copied to the KSEG0 + * vector location. + */ + /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ + .set noreorder + .set noat + LEAF(except_vec0_r4000) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + mtc0_tlbw_hazard + tlbwr # write random tlb entry + tlbw_eret_hazard + eret # return from trap + END(except_vec0_r4000) + + /* TLB refill, EXL == 0, R4600 version */ + LEAF(except_vec0_r4600) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 k1, CP0_ENTRYLO1 + nop + tlbwr + nop + eret + END(except_vec0_r4600) + + /* TLB refill, EXL == 0, R52x0 "Nevada" version */ + /* + * This version has a bug workaround for the Nevada. It seems + * as if under certain circumstances the move from cp0_context + * might produce a bogus result when the mfc0 instruction and + * it's consumer are in a different cacheline or a load instruction, + * probably any memory reference, is between them. This is + * potencially slower than the R4000 version, so we use this + * special version. + */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + lw k1, pgd_current # get pgd pointer + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 # add in pgd offset + lw k1, (k1) + mfc0 k0, CP0_CONTEXT # get context reg + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + nop # QED specified nops + nop + tlbwr # write random tlb entry + nop # traditional nop + eret # return from trap + END(except_vec0_nevada) + + /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ + LEAF(except_vec0_sb1) +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry +1: eret # return from trap + END(except_vec0_sb1) + + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ + LEAF(except_vec0_r45k_bvahwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r45k_bvahwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ + LEAF(except_vec0_r4k_mphwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_mphwbug) +#endif + + /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ + LEAF(except_vec0_r4k_250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + b 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_250MHZhwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ + LEAF(except_vec0_r4k_MP250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + mfc0 k0, CP0_INDEX + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_MP250MHZhwbug) +#endif + + __FINIT + + .set noreorder + +/* + * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: + * 2. A timing hazard exists for the TLBP instruction. + * + * stalling_instruction + * TLBP + * + * The JTLB is being read for the TLBP throughout the stall generated by the + * previous instruction. This is not really correct as the stalling instruction + * can modify the address used to access the JTLB. The failure symptom is that + * the TLBP instruction will use an address created for the stalling instruction + * and not the address held in C0_ENHI and thus report the wrong results. + * + * The software work-around is to not allow the instruction preceding the TLBP + * to stall - make it an NOP or some other instruction guaranteed not to stall. + * + * Errata 2 will not be fixed. This errata is also on the R5000. + * + * As if we MIPS hackers wouldn't know how to nop pipelines happy ... + */ +#define R5K_HAZARD nop + + /* + * Note for many R4k variants tlb probes cannot be executed out + * of the instruction cache else you get bogus results. + */ + .align 5 + NESTED(handle_tlbl, PT_SIZE, sp) + .set noat +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + beqz k0, 1f + nop + .set mips3 + eret + .set mips0 +1: +#endif +invalid_tlbl: +#ifdef TLB_OPTIMIZE + .set mips3 + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbl: + DO_FAULT(0) + END(handle_tlbl) + + .align 5 + NESTED(handle_tlbs, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + li k0,0 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbs: + DO_FAULT(1) + END(handle_tlbs) + + .align 5 + NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + PTE_L k0, (k1) + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) + mtc0_tlbw_hazard + tlbwi + tlbw_eret_hazard + .set mips3 + eret + .set mips0 +#endif + +nowrite_mod: + DO_FAULT(1) + END(handle_mod) diff --git a/arch/mips/mm/tlbex64-r4k.S b/arch/mips/mm/tlbex64-r4k.S new file mode 100644 index 000000000000..728d18f004d2 --- /dev/null +++ b/arch/mips/mm/tlbex64-r4k.S @@ -0,0 +1,203 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define _VMALLOC_START 0xc000000000000000 + + /* + * After this macro runs we have a pointer to the pte of the address + * that caused the fault in PTR. + */ + .macro LOAD_PTE2, ptr, tmp, kaddr +#ifdef CONFIG_SMP + dmfc0 \ptr, CP0_CONTEXT + dmfc0 \tmp, CP0_BADVADDR + dsra \ptr, 23 # get pgd_current[cpu] +#else + dmfc0 \tmp, CP0_BADVADDR + dla \ptr, pgd_current +#endif + bltz \tmp, \kaddr + ld \ptr, (\ptr) + dsrl \tmp, (_PGDIR_SHIFT-3) # get pgd offset in bytes + andi \tmp, ((_PTRS_PER_PGD - 1)<<3) + daddu \ptr, \tmp # add in pgd offset + dmfc0 \tmp, CP0_BADVADDR + ld \ptr, (\ptr) # get pmd pointer + dsrl \tmp, (_PMD_SHIFT-3) # get pmd offset in bytes + andi \tmp, ((_PTRS_PER_PMD - 1)<<3) + daddu \ptr, \tmp # add in pmd offset + dmfc0 \tmp, CP0_XCONTEXT + ld \ptr, (\ptr) # get pte pointer + andi \tmp, 0xff0 # get pte offset + daddu \ptr, \tmp + .endm + + + /* + * Ditto for the kernel table. + */ + .macro LOAD_KPTE2, ptr, tmp, not_vmalloc + /* + * First, determine that the address is in/above vmalloc range. + */ + dmfc0 \tmp, CP0_BADVADDR + dli \ptr, _VMALLOC_START + + /* + * Now find offset into kptbl. + */ + dsubu \tmp, \tmp, \ptr + dla \ptr, kptbl + dsrl \tmp, (_PAGE_SHIFT+1) # get vpn2 + dsll \tmp, 4 # byte offset of pte + daddu \ptr, \ptr, \tmp + + /* + * Determine that fault address is within vmalloc range. + */ + dla \tmp, ekptbl + slt \tmp, \ptr, \tmp + beqz \tmp, \not_vmalloc # not vmalloc + nop + .endm + + + /* + * This places the even/odd pte pair in the page table at the pte + * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. + */ + .macro PTE_RELOAD, pte0, pte1 + dsrl \pte0, 6 # convert to entrylo0 + dmtc0 \pte0, CP0_ENTRYLO0 # load it + dsrl \pte1, 6 # convert to entrylo1 + dmtc0 \pte1, CP0_ENTRYLO1 # load it + .endm + + + .text + .set noreorder + .set mips3 + + __INIT + + /* + * TLB refill handlers for the R4000 and SB1. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r4k) + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop +END(except_vec1_r4k) + +LEAF(except_vec1_sb1) +#if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, _PAGE_SHIFT+1 + bnez k0, 1f +#endif + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop + +1: eret + nop +END(except_vec1_sb1) + + __FINIT + + .align 5 +LEAF(handle_vec1_r4k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + mtc0_tlbw_hazard + tlbwr + tlbw_eret_hazard + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + mtc0_tlbw_hazard + tlbwr + tlbw_eret_hazard + eret +END(handle_vec1_r4k) + + + __INIT + + /* + * TLB refill handler for the R10000. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r10k) + .set noat + dla k0, handle_vec1_r10k + jr k0 + nop +END(except_vec1_r10k) + + __FINIT + + .align 5 +LEAF(handle_vec1_r10k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret +END(handle_vec1_r10k) + + + .align 5 +LEAF(invalid_vmalloc_address) + .set noat + SAVE_ALL + CLI + dmfc0 t0, CP0_BADVADDR + sd t0, PT_BVADDR(sp) + move a0, sp + jal show_regs + PANIC("Invalid kernel address") +END(invalid_vmalloc_address) diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c index 10acbe9b0cb6..0ec82a10df5c 100644 --- a/arch/mips/momentum/jaguar_atx/prom.c +++ b/arch/mips/momentum/jaguar_atx/prom.c @@ -245,20 +245,6 @@ void __init prom_fixup_mem_map(unsigned long start, unsigned long end) { } -/* - * SMP support - */ -int prom_setup_smp(void) -{ - int num_cpus = 2; - - /* - * We know that the RM9000 on the Jaguar ATX board has 2 cores. - * Hence, this can be hardcoded for now. - */ - return num_cpus; -} - int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) { /* Clear the semaphore */ diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index 7c2f25ffc6df..261250737528 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 6efdd145e7d7..91240777f978 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile @@ -2,7 +2,7 @@ # Makefile for Momentum Computer's Ocelot-C and -CS boards. # -obj-y += cpci-irq.o uart-irq.o int-handler.o irq.o pci-irq.o \ - prom.o reset.o setup.o +obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ + setup.o uart-irq.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index 37ad81291d82..13dd8bd74041 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c @@ -44,8 +44,9 @@ #include #include #include -#include +#include #include +#include #include extern asmlinkage void ocelot_handle_int(void); diff --git a/arch/mips/momentum/ocelot_c/pci-irq.c b/arch/mips/momentum/ocelot_c/pci-irq.c deleted file mode 100644 index c14b6d99577e..000000000000 --- a/arch/mips/momentum/ocelot_c/pci-irq.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for mv64340 controller. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - - -void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - /* loop over all known devices on this bus */ - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if ((current_bus->number == 0) && - (PCI_SLOT(devices->devfn) == 1) && - (PCI_FUNC(devices->devfn) == 0)) { - /* LSI 53C10101R SCSI (A) */ - devices->irq = 2; - } else if ((current_bus->number == 0) && - (PCI_SLOT(devices->devfn) == 1) && - (PCI_FUNC(devices->devfn) == 1)) { - /* LSI 53C10101R SCSI (B) */ - devices->irq = 2; - } else if ((current_bus->number == 1) && - (PCI_SLOT(devices->devfn) == 1)) { - /* Intel 21555 bridge */ - devices->irq = 12; - } else if ((current_bus->number == 1) && - (PCI_SLOT(devices->devfn) == 2)) { - /* PMC Slot */ - devices->irq = 4; - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); - - /* enable master for everything but the MV-64340 */ - if (((current_bus->number != 0) && (current_bus->number != 1)) - || (PCI_SLOT(devices->devfn) != 0)) { - bus->ops->read_word(devices, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write_word(devices, PCI_COMMAND, cmd); - } - } -} diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 0387b562b6a8..a01bedb4485c 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c @@ -147,13 +147,14 @@ char *arg64(unsigned long addrin, int arg_index) #endif /* CONFIG_MIPS64 */ -/* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(void) { int argc = fw_arg0; char **arg = (char **) fw_arg1; char **env = (char **) fw_arg2; + struct callvectors *cv = (struct callvectors *) fw_arg3; int i; + #ifdef CONFIG_MIPS64 char *ptr; diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 1079858bff79..1bd2ba659bfd 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -193,7 +193,7 @@ int m48t37y_set_time(unsigned long sec) rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = CONV_BIN2BCD(tm.tm_wday + 1); + rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); /* disable writing */ rtc_base[0x7ff8] = 0x00; diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile index bdd8d3292d7b..e5f1cb086973 100644 --- a/arch/mips/momentum/ocelot_g/Makefile +++ b/arch/mips/momentum/ocelot_g/Makefile @@ -2,8 +2,7 @@ # Makefile for Momentum Computer's Ocelot-G board. # -obj-y += gt-irq.o pci-irq.o int-handler.o irq.o prom.o \ - reset.o setup.o +obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o obj-$(CONFIG_KGDB) += dbg_io.o EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c index 3afe3273921c..4ec4aefd6952 100644 --- a/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/arch/mips/momentum/ocelot_g/gt-irq.c @@ -17,8 +17,8 @@ #include #include #include +#include #include -#include "gt64240.h" unsigned long bus_clock; @@ -108,25 +108,25 @@ int disable_galileo_irq(int int_cause, int bit_num) * we keep this particular structure in the function. */ -static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs) { uint32_t irq_src, irq_src_mask; int handled; /* get the low interrupt cause register */ - GT_READ(LOW_INTERRUPT_CAUSE_REGISTER, &irq_src); + irq_src = GT_READ(LOW_INTERRUPT_CAUSE_REGISTER); /* get the mask register for this pin */ - GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, &irq_src_mask); + irq_src_mask = GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW); /* mask off only the interrupts we're interested in */ irq_src = irq_src & irq_src_mask; - handled = 0; + handled = IRQ_NONE; /* Check for timer interrupt */ if (irq_src & 0x00000100) { - handled = 1; + handled = IRQ_HANDLED; irq_src &= ~0x00000100; /* Clear any pending cause bits */ @@ -141,90 +141,8 @@ static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs) "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n", irq_src); } -} - -/* - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be built in ethernet ports etc... - */ -static void gt64240_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - -#if 0 - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); -#endif - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } -#if 0 - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); -#endif -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - * Future I2O support. We currently attach I2O interrupt handlers to - * the Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - * This normally would be outside of the ifdef, but since we're - * handling I2O outside of this handler, this printk shows up every - * time we get a valid I2O interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif + return handled; } /* diff --git a/arch/mips/momentum/ocelot_g/gt64240.h b/arch/mips/momentum/ocelot_g/gt64240.h deleted file mode 100644 index c6cfc0b06e26..000000000000 --- a/arch/mips/momentum/ocelot_g/gt64240.h +++ /dev/null @@ -1,1238 +0,0 @@ -/* gt64240r.h - GT-64240 Internal registers definition file */ - -/* Copyright - Galileo technology. */ - -#ifndef __INCgt64240rh -#define __INCgt64240rh - -#define GTREG(v) (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \ - (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00) - -#if 0 -#define GTREG_SHORT(X) (((X) << 8) | ((X) >> 8)) - -#define LONG_GTREG(X) ((l64) \ - (((X)&0x00000000000000ffULL) << 56) | \ - (((X)&0x000000000000ff00ULL) << 40) | \ - (((X)&0x0000000000ff0000ULL) << 24) | \ - (((X)&0x00000000ff000000ULL) << 8) | \ - (((X)&0x000000ff00000000ULL) >> 8) | \ - (((X)&0x0000ff0000000000ULL) >> 24) | \ - (((X)&0x00ff000000000000ULL) >> 40) | \ - (((X)&0xff00000000000000ULL) >> 56)) -#endif - -#include "gt64240_dep.h" - -/****************************************/ -/* CPU Control Registers */ -/****************************************/ - -#define CPU_CONFIGURATION 0x000 -#define CPU_MODE 0x120 -#define CPU_READ_RESPONSE_CROSSBAR_LOW 0x170 -#define CPU_READ_RESPONSE_CROSSBAR_HIGH 0x178 - -/****************************************/ -/* Processor Address Space */ -/****************************************/ - -/* Sdram's BAR'S */ -#define SCS_0_LOW_DECODE_ADDRESS 0x008 -#define SCS_0_HIGH_DECODE_ADDRESS 0x010 -#define SCS_1_LOW_DECODE_ADDRESS 0x208 -#define SCS_1_HIGH_DECODE_ADDRESS 0x210 -#define SCS_2_LOW_DECODE_ADDRESS 0x018 -#define SCS_2_HIGH_DECODE_ADDRESS 0x020 -#define SCS_3_LOW_DECODE_ADDRESS 0x218 -#define SCS_3_HIGH_DECODE_ADDRESS 0x220 -/* Devices BAR'S */ -#define CS_0_LOW_DECODE_ADDRESS 0x028 -#define CS_0_HIGH_DECODE_ADDRESS 0x030 -#define CS_1_LOW_DECODE_ADDRESS 0x228 -#define CS_1_HIGH_DECODE_ADDRESS 0x230 -#define CS_2_LOW_DECODE_ADDRESS 0x248 -#define CS_2_HIGH_DECODE_ADDRESS 0x250 -#define CS_3_LOW_DECODE_ADDRESS 0x038 -#define CS_3_HIGH_DECODE_ADDRESS 0x040 -#define BOOTCS_LOW_DECODE_ADDRESS 0x238 -#define BOOTCS_HIGH_DECODE_ADDRESS 0x240 - -#define PCI_0I_O_LOW_DECODE_ADDRESS 0x048 -#define PCI_0I_O_HIGH_DECODE_ADDRESS 0x050 -#define PCI_0MEMORY0_LOW_DECODE_ADDRESS 0x058 -#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS 0x060 -#define PCI_0MEMORY1_LOW_DECODE_ADDRESS 0x080 -#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS 0x088 -#define PCI_0MEMORY2_LOW_DECODE_ADDRESS 0x258 -#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS 0x260 -#define PCI_0MEMORY3_LOW_DECODE_ADDRESS 0x280 -#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS 0x288 - -#define PCI_1I_O_LOW_DECODE_ADDRESS 0x090 -#define PCI_1I_O_HIGH_DECODE_ADDRESS 0x098 -#define PCI_1MEMORY0_LOW_DECODE_ADDRESS 0x0a0 -#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS 0x0a8 -#define PCI_1MEMORY1_LOW_DECODE_ADDRESS 0x0b0 -#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS 0x0b8 -#define PCI_1MEMORY2_LOW_DECODE_ADDRESS 0x2a0 -#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS 0x2a8 -#define PCI_1MEMORY3_LOW_DECODE_ADDRESS 0x2b0 -#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS 0x2b8 - -#define INTERNAL_SPACE_DECODE 0x068 - -#define CPU_0_LOW_DECODE_ADDRESS 0x290 -#define CPU_0_HIGH_DECODE_ADDRESS 0x298 -#define CPU_1_LOW_DECODE_ADDRESS 0x2c0 -#define CPU_1_HIGH_DECODE_ADDRESS 0x2c8 - -#define PCI_0I_O_ADDRESS_REMAP 0x0f0 -#define PCI_0MEMORY0_ADDRESS_REMAP 0x0f8 -#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP 0x320 -#define PCI_0MEMORY1_ADDRESS_REMAP 0x100 -#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP 0x328 -#define PCI_0MEMORY2_ADDRESS_REMAP 0x2f8 -#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP 0x330 -#define PCI_0MEMORY3_ADDRESS_REMAP 0x300 -#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP 0x338 - -#define PCI_1I_O_ADDRESS_REMAP 0x108 -#define PCI_1MEMORY0_ADDRESS_REMAP 0x110 -#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP 0x340 -#define PCI_1MEMORY1_ADDRESS_REMAP 0x118 -#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP 0x348 -#define PCI_1MEMORY2_ADDRESS_REMAP 0x310 -#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP 0x350 -#define PCI_1MEMORY3_ADDRESS_REMAP 0x318 -#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP 0x358 - -/****************************************/ -/* CPU Sync Barrier */ -/****************************************/ - -#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER 0x0c0 -#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER 0x0c8 - - -/****************************************/ -/* CPU Access Protect */ -/****************************************/ - -#define CPU_LOW_PROTECT_ADDRESS_0 0X180 -#define CPU_HIGH_PROTECT_ADDRESS_0 0X188 -#define CPU_LOW_PROTECT_ADDRESS_1 0X190 -#define CPU_HIGH_PROTECT_ADDRESS_1 0X198 -#define CPU_LOW_PROTECT_ADDRESS_2 0X1a0 -#define CPU_HIGH_PROTECT_ADDRESS_2 0X1a8 -#define CPU_LOW_PROTECT_ADDRESS_3 0X1b0 -#define CPU_HIGH_PROTECT_ADDRESS_3 0X1b8 -#define CPU_LOW_PROTECT_ADDRESS_4 0X1c0 -#define CPU_HIGH_PROTECT_ADDRESS_4 0X1c8 -#define CPU_LOW_PROTECT_ADDRESS_5 0X1d0 -#define CPU_HIGH_PROTECT_ADDRESS_5 0X1d8 -#define CPU_LOW_PROTECT_ADDRESS_6 0X1e0 -#define CPU_HIGH_PROTECT_ADDRESS_6 0X1e8 -#define CPU_LOW_PROTECT_ADDRESS_7 0X1f0 -#define CPU_HIGH_PROTECT_ADDRESS_7 0X1f8 - - -/****************************************/ -/* Snoop Control */ -/****************************************/ - -#define SNOOP_BASE_ADDRESS_0 0x380 -#define SNOOP_TOP_ADDRESS_0 0x388 -#define SNOOP_BASE_ADDRESS_1 0x390 -#define SNOOP_TOP_ADDRESS_1 0x398 -#define SNOOP_BASE_ADDRESS_2 0x3a0 -#define SNOOP_TOP_ADDRESS_2 0x3a8 -#define SNOOP_BASE_ADDRESS_3 0x3b0 -#define SNOOP_TOP_ADDRESS_3 0x3b8 - -/****************************************/ -/* CPU Error Report */ -/****************************************/ - -#define CPU_ERROR_ADDRESS_LOW 0x070 -#define CPU_ERROR_ADDRESS_HIGH 0x078 -#define CPU_ERROR_DATA_LOW 0x128 -#define CPU_ERROR_DATA_HIGH 0x130 -#define CPU_ERROR_PARITY 0x138 -#define CPU_ERROR_CAUSE 0x140 -#define CPU_ERROR_MASK 0x148 - -/****************************************/ -/* Pslave Debug */ -/****************************************/ - -#define X_0_ADDRESS 0x360 -#define X_0_COMMAND_ID 0x368 -#define X_1_ADDRESS 0x370 -#define X_1_COMMAND_ID 0x378 -#define WRITE_DATA_LOW 0x3c0 -#define WRITE_DATA_HIGH 0x3c8 -#define WRITE_BYTE_ENABLE 0X3e0 -#define READ_DATA_LOW 0x3d0 -#define READ_DATA_HIGH 0x3d8 -#define READ_ID 0x3e8 - - -/****************************************/ -/* SDRAM and Device Address Space */ -/****************************************/ - - -/****************************************/ -/* SDRAM Configuration */ -/****************************************/ - -#define SDRAM_CONFIGURATION 0x448 -#define SDRAM_OPERATION_MODE 0x474 -#define SDRAM_ADDRESS_DECODE 0x47C -#define SDRAM_TIMING_PARAMETERS 0x4b4 -#define SDRAM_UMA_CONTROL 0x4a4 -#define SDRAM_CROSS_BAR_CONTROL_LOW 0x4a8 -#define SDRAM_CROSS_BAR_CONTROL_HIGH 0x4ac -#define SDRAM_CROSS_BAR_TIMEOUT 0x4b0 - - -/****************************************/ -/* SDRAM Parameters */ -/****************************************/ - -#define SDRAM_BANK0PARAMETERS 0x44C -#define SDRAM_BANK1PARAMETERS 0x450 -#define SDRAM_BANK2PARAMETERS 0x454 -#define SDRAM_BANK3PARAMETERS 0x458 - - -/****************************************/ -/* SDRAM Error Report */ -/****************************************/ - -#define SDRAM_ERROR_DATA_LOW 0x484 -#define SDRAM_ERROR_DATA_HIGH 0x480 -#define SDRAM_AND_DEVICE_ERROR_ADDRESS 0x490 -#define SDRAM_RECEIVED_ECC 0x488 -#define SDRAM_CALCULATED_ECC 0x48c -#define SDRAM_ECC_CONTROL 0x494 -#define SDRAM_ECC_ERROR_COUNTER 0x498 - - -/****************************************/ -/* SDunit Debug (for internal use) */ -/****************************************/ - -#define X0_ADDRESS 0x500 -#define X0_COMMAND_AND_ID 0x504 -#define X0_WRITE_DATA_LOW 0x508 -#define X0_WRITE_DATA_HIGH 0x50c -#define X0_WRITE_BYTE_ENABLE 0x518 -#define X0_READ_DATA_LOW 0x510 -#define X0_READ_DATA_HIGH 0x514 -#define X0_READ_ID 0x51c -#define X1_ADDRESS 0x520 -#define X1_COMMAND_AND_ID 0x524 -#define X1_WRITE_DATA_LOW 0x528 -#define X1_WRITE_DATA_HIGH 0x52c -#define X1_WRITE_BYTE_ENABLE 0x538 -#define X1_READ_DATA_LOW 0x530 -#define X1_READ_DATA_HIGH 0x534 -#define X1_READ_ID 0x53c -#define X0_SNOOP_ADDRESS 0x540 -#define X0_SNOOP_COMMAND 0x544 -#define X1_SNOOP_ADDRESS 0x548 -#define X1_SNOOP_COMMAND 0x54c - - -/****************************************/ -/* Device Parameters */ -/****************************************/ - -#define DEVICE_BANK0PARAMETERS 0x45c -#define DEVICE_BANK1PARAMETERS 0x460 -#define DEVICE_BANK2PARAMETERS 0x464 -#define DEVICE_BANK3PARAMETERS 0x468 -#define DEVICE_BOOT_BANK_PARAMETERS 0x46c -#define DEVICE_CONTROL 0x4c0 -#define DEVICE_CROSS_BAR_CONTROL_LOW 0x4c8 -#define DEVICE_CROSS_BAR_CONTROL_HIGH 0x4cc -#define DEVICE_CROSS_BAR_TIMEOUT 0x4c4 - - -/****************************************/ -/* Device Interrupt */ -/****************************************/ - -#define DEVICE_INTERRUPT_CAUSE 0x4d0 -#define DEVICE_INTERRUPT_MASK 0x4d4 -#define DEVICE_ERROR_ADDRESS 0x4d8 - -/****************************************/ -/* DMA Record */ -/****************************************/ - -#define CHANNEL0_DMA_BYTE_COUNT 0x800 -#define CHANNEL1_DMA_BYTE_COUNT 0x804 -#define CHANNEL2_DMA_BYTE_COUNT 0x808 -#define CHANNEL3_DMA_BYTE_COUNT 0x80C -#define CHANNEL4_DMA_BYTE_COUNT 0x900 -#define CHANNEL5_DMA_BYTE_COUNT 0x904 -#define CHANNEL6_DMA_BYTE_COUNT 0x908 -#define CHANNEL7_DMA_BYTE_COUNT 0x90C -#define CHANNEL0_DMA_SOURCE_ADDRESS 0x810 -#define CHANNEL1_DMA_SOURCE_ADDRESS 0x814 -#define CHANNEL2_DMA_SOURCE_ADDRESS 0x818 -#define CHANNEL3_DMA_SOURCE_ADDRESS 0x81C -#define CHANNEL4_DMA_SOURCE_ADDRESS 0x910 -#define CHANNEL5_DMA_SOURCE_ADDRESS 0x914 -#define CHANNEL6_DMA_SOURCE_ADDRESS 0x918 -#define CHANNEL7_DMA_SOURCE_ADDRESS 0x91C -#define CHANNEL0_DMA_DESTINATION_ADDRESS 0x820 -#define CHANNEL1_DMA_DESTINATION_ADDRESS 0x824 -#define CHANNEL2_DMA_DESTINATION_ADDRESS 0x828 -#define CHANNEL3_DMA_DESTINATION_ADDRESS 0x82C -#define CHANNEL4_DMA_DESTINATION_ADDRESS 0x920 -#define CHANNEL5_DMA_DESTINATION_ADDRESS 0x924 -#define CHANNEL6_DMA_DESTINATION_ADDRESS 0x928 -#define CHANNEL7_DMA_DESTINATION_ADDRESS 0x92C -#define CHANNEL0NEXT_RECORD_POINTER 0x830 -#define CHANNEL1NEXT_RECORD_POINTER 0x834 -#define CHANNEL2NEXT_RECORD_POINTER 0x838 -#define CHANNEL3NEXT_RECORD_POINTER 0x83C -#define CHANNEL4NEXT_RECORD_POINTER 0x930 -#define CHANNEL5NEXT_RECORD_POINTER 0x934 -#define CHANNEL6NEXT_RECORD_POINTER 0x938 -#define CHANNEL7NEXT_RECORD_POINTER 0x93C -#define CHANNEL0CURRENT_DESCRIPTOR_POINTER 0x870 -#define CHANNEL1CURRENT_DESCRIPTOR_POINTER 0x874 -#define CHANNEL2CURRENT_DESCRIPTOR_POINTER 0x878 -#define CHANNEL3CURRENT_DESCRIPTOR_POINTER 0x87C -#define CHANNEL4CURRENT_DESCRIPTOR_POINTER 0x970 -#define CHANNEL5CURRENT_DESCRIPTOR_POINTER 0x974 -#define CHANNEL6CURRENT_DESCRIPTOR_POINTER 0x978 -#define CHANNEL7CURRENT_DESCRIPTOR_POINTER 0x97C -#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS 0x890 -#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS 0x894 -#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS 0x898 -#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS 0x89c -#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS 0x990 -#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS 0x994 -#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS 0x998 -#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS 0x99c -#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a0 -#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a4 -#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a8 -#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8ac -#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a0 -#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a4 -#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a8 -#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9ac -#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b0 -#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b4 -#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b8 -#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8bc -#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b0 -#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b4 -#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b8 -#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9bc - -/****************************************/ -/* DMA Channel Control */ -/****************************************/ - -#define CHANNEL0CONTROL 0x840 -#define CHANNEL0CONTROL_HIGH 0x880 - -#define CHANNEL1CONTROL 0x844 -#define CHANNEL1CONTROL_HIGH 0x884 - -#define CHANNEL2CONTROL 0x848 -#define CHANNEL2CONTROL_HIGH 0x888 - -#define CHANNEL3CONTROL 0x84C -#define CHANNEL3CONTROL_HIGH 0x88C - -#define CHANNEL4CONTROL 0x940 -#define CHANNEL4CONTROL_HIGH 0x980 - -#define CHANNEL5CONTROL 0x944 -#define CHANNEL5CONTROL_HIGH 0x984 - -#define CHANNEL6CONTROL 0x948 -#define CHANNEL6CONTROL_HIGH 0x988 - -#define CHANNEL7CONTROL 0x94C -#define CHANNEL7CONTROL_HIGH 0x98C - - -/****************************************/ -/* DMA Arbiter */ -/****************************************/ - -#define ARBITER_CONTROL_0_3 0x860 -#define ARBITER_CONTROL_4_7 0x960 - - -/****************************************/ -/* DMA Interrupt */ -/****************************************/ - -#define CHANELS0_3_INTERRUPT_CAUSE 0x8c0 -#define CHANELS0_3_INTERRUPT_MASK 0x8c4 -#define CHANELS0_3_ERROR_ADDRESS 0x8c8 -#define CHANELS0_3_ERROR_SELECT 0x8cc -#define CHANELS4_7_INTERRUPT_CAUSE 0x9c0 -#define CHANELS4_7_INTERRUPT_MASK 0x9c4 -#define CHANELS4_7_ERROR_ADDRESS 0x9c8 -#define CHANELS4_7_ERROR_SELECT 0x9cc - - -/****************************************/ -/* DMA Debug (for internal use) */ -/****************************************/ - -#define DMA_X0_ADDRESS 0x8e0 -#define DMA_X0_COMMAND_AND_ID 0x8e4 -#define DMA_X0_WRITE_DATA_LOW 0x8e8 -#define DMA_X0_WRITE_DATA_HIGH 0x8ec -#define DMA_X0_WRITE_BYTE_ENABLE 0x8f8 -#define DMA_X0_READ_DATA_LOW 0x8f0 -#define DMA_X0_READ_DATA_HIGH 0x8f4 -#define DMA_X0_READ_ID 0x8fc -#define DMA_X1_ADDRESS 0x9e0 -#define DMA_X1_COMMAND_AND_ID 0x9e4 -#define DMA_X1_WRITE_DATA_LOW 0x9e8 -#define DMA_X1_WRITE_DATA_HIGH 0x9ec -#define DMA_X1_WRITE_BYTE_ENABLE 0x9f8 -#define DMA_X1_READ_DATA_LOW 0x9f0 -#define DMA_X1_READ_DATA_HIGH 0x9f4 -#define DMA_X1_READ_ID 0x9fc - -/****************************************/ -/* Timer_Counter */ -/****************************************/ - -#define TIMER_COUNTER0 0x850 -#define TIMER_COUNTER1 0x854 -#define TIMER_COUNTER2 0x858 -#define TIMER_COUNTER3 0x85C -#define TIMER_COUNTER_0_3_CONTROL 0x864 -#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 -#define TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c -#define TIMER_COUNTER4 0x950 -#define TIMER_COUNTER5 0x954 -#define TIMER_COUNTER6 0x958 -#define TIMER_COUNTER7 0x95C -#define TIMER_COUNTER_4_7_CONTROL 0x964 -#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE 0x968 -#define TIMER_COUNTER_4_7_INTERRUPT_MASK 0x96c - -/****************************************/ -/* PCI Slave Address Decoding */ -/****************************************/ - -#define PCI_0SCS_0_BANK_SIZE 0xc08 -#define PCI_1SCS_0_BANK_SIZE 0xc88 -#define PCI_0SCS_1_BANK_SIZE 0xd08 -#define PCI_1SCS_1_BANK_SIZE 0xd88 -#define PCI_0SCS_2_BANK_SIZE 0xc0c -#define PCI_1SCS_2_BANK_SIZE 0xc8c -#define PCI_0SCS_3_BANK_SIZE 0xd0c -#define PCI_1SCS_3_BANK_SIZE 0xd8c -#define PCI_0CS_0_BANK_SIZE 0xc10 -#define PCI_1CS_0_BANK_SIZE 0xc90 -#define PCI_0CS_1_BANK_SIZE 0xd10 -#define PCI_1CS_1_BANK_SIZE 0xd90 -#define PCI_0CS_2_BANK_SIZE 0xd18 -#define PCI_1CS_2_BANK_SIZE 0xd98 -#define PCI_0CS_3_BANK_SIZE 0xc14 -#define PCI_1CS_3_BANK_SIZE 0xc94 -#define PCI_0CS_BOOT_BANK_SIZE 0xd14 -#define PCI_1CS_BOOT_BANK_SIZE 0xd94 -#define PCI_0P2P_MEM0_BAR_SIZE 0xd1c -#define PCI_1P2P_MEM0_BAR_SIZE 0xd9c -#define PCI_0P2P_MEM1_BAR_SIZE 0xd20 -#define PCI_1P2P_MEM1_BAR_SIZE 0xda0 -#define PCI_0P2P_I_O_BAR_SIZE 0xd24 -#define PCI_1P2P_I_O_BAR_SIZE 0xda4 -#define PCI_0CPU_BAR_SIZE 0xd28 -#define PCI_1CPU_BAR_SIZE 0xda8 -#define PCI_0DAC_SCS_0_BANK_SIZE 0xe00 -#define PCI_1DAC_SCS_0_BANK_SIZE 0xe80 -#define PCI_0DAC_SCS_1_BANK_SIZE 0xe04 -#define PCI_1DAC_SCS_1_BANK_SIZE 0xe84 -#define PCI_0DAC_SCS_2_BANK_SIZE 0xe08 -#define PCI_1DAC_SCS_2_BANK_SIZE 0xe88 -#define PCI_0DAC_SCS_3_BANK_SIZE 0xe0c -#define PCI_1DAC_SCS_3_BANK_SIZE 0xe8c -#define PCI_0DAC_CS_0_BANK_SIZE 0xe10 -#define PCI_1DAC_CS_0_BANK_SIZE 0xe90 -#define PCI_0DAC_CS_1_BANK_SIZE 0xe14 -#define PCI_1DAC_CS_1_BANK_SIZE 0xe94 -#define PCI_0DAC_CS_2_BANK_SIZE 0xe18 -#define PCI_1DAC_CS_2_BANK_SIZE 0xe98 -#define PCI_0DAC_CS_3_BANK_SIZE 0xe1c -#define PCI_1DAC_CS_3_BANK_SIZE 0xe9c -#define PCI_0DAC_BOOTCS_BANK_SIZE 0xe20 -#define PCI_1DAC_BOOTCS_BANK_SIZE 0xea0 -#define PCI_0DAC_P2P_MEM0_BAR_SIZE 0xe24 -#define PCI_1DAC_P2P_MEM0_BAR_SIZE 0xea4 -#define PCI_0DAC_P2P_MEM1_BAR_SIZE 0xe28 -#define PCI_1DAC_P2P_MEM1_BAR_SIZE 0xea8 -#define PCI_0DAC_CPU_BAR_SIZE 0xe2c -#define PCI_1DAC_CPU_BAR_SIZE 0xeac -#define PCI_0EXPANSION_ROM_BAR_SIZE 0xd2c -#define PCI_1EXPANSION_ROM_BAR_SIZE 0xdac -#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 0xc3c -#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 0xcbc -#define PCI_0SCS_0_BASE_ADDRESS_REMAP 0xc48 -#define PCI_1SCS_0_BASE_ADDRESS_REMAP 0xcc8 -#define PCI_0SCS_1_BASE_ADDRESS_REMAP 0xd48 -#define PCI_1SCS_1_BASE_ADDRESS_REMAP 0xdc8 -#define PCI_0SCS_2_BASE_ADDRESS_REMAP 0xc4c -#define PCI_1SCS_2_BASE_ADDRESS_REMAP 0xccc -#define PCI_0SCS_3_BASE_ADDRESS_REMAP 0xd4c -#define PCI_1SCS_3_BASE_ADDRESS_REMAP 0xdcc -#define PCI_0CS_0_BASE_ADDRESS_REMAP 0xc50 -#define PCI_1CS_0_BASE_ADDRESS_REMAP 0xcd0 -#define PCI_0CS_1_BASE_ADDRESS_REMAP 0xd50 -#define PCI_1CS_1_BASE_ADDRESS_REMAP 0xdd0 -#define PCI_0CS_2_BASE_ADDRESS_REMAP 0xd58 -#define PCI_1CS_2_BASE_ADDRESS_REMAP 0xdd8 -#define PCI_0CS_3_BASE_ADDRESS_REMAP 0xc54 -#define PCI_1CS_3_BASE_ADDRESS_REMAP 0xcd4 -#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP 0xd54 -#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP 0xdd4 -#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xd5c -#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xddc -#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xd60 -#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xde0 -#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xd64 -#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xde4 -#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xd68 -#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xde8 -#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP 0xd6c -#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP 0xdec -#define PCI_0CPU_BASE_ADDRESS_REMAP 0xd70 -#define PCI_1CPU_BASE_ADDRESS_REMAP 0xdf0 -#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP 0xf00 -#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP 0xff0 -#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP 0xf04 -#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP 0xf84 -#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP 0xf08 -#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP 0xf88 -#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP 0xf0c -#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP 0xf8c -#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP 0xf10 -#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP 0xf90 -#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP 0xf14 -#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP 0xf94 -#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP 0xf18 -#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP 0xf98 -#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP 0xf1c -#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP 0xf9c -#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP 0xf20 -#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP 0xfa0 -#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xf24 -#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xfa4 -#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xf28 -#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xfa8 -#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xf2c -#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xfac -#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xf30 -#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xfb0 -#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP 0xf34 -#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP 0xfb4 -#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP 0xf38 -#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP 0xfb8 -#define PCI_0ADDRESS_DECODE_CONTROL 0xd3c -#define PCI_1ADDRESS_DECODE_CONTROL 0xdbc - -/****************************************/ -/* PCI Control */ -/****************************************/ - -#define PCI_0COMMAND 0xc00 -#define PCI_1COMMAND 0xc80 -#define PCI_0MODE 0xd00 -#define PCI_1MODE 0xd80 -#define PCI_0TIMEOUT_RETRY 0xc04 -#define PCI_1TIMEOUT_RETRY 0xc84 -#define PCI_0READ_BUFFER_DISCARD_TIMER 0xd04 -#define PCI_1READ_BUFFER_DISCARD_TIMER 0xd84 -#define MSI_0TRIGGER_TIMER 0xc38 -#define MSI_1TRIGGER_TIMER 0xcb8 -#define PCI_0ARBITER_CONTROL 0x1d00 -#define PCI_1ARBITER_CONTROL 0x1d80 -/* changing untill here */ -#define PCI_0CROSS_BAR_CONTROL_LOW 0x1d08 -#define PCI_0CROSS_BAR_CONTROL_HIGH 0x1d0c -#define PCI_0CROSS_BAR_TIMEOUT 0x1d04 -#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d18 -#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d1c -#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER 0x1d10 -#define PCI_0P2P_CONFIGURATION 0x1d14 -#define PCI_0ACCESS_CONTROL_BASE_0_LOW 0x1e00 -#define PCI_0ACCESS_CONTROL_BASE_0_HIGH 0x1e04 -#define PCI_0ACCESS_CONTROL_TOP_0 0x1e08 -#define PCI_0ACCESS_CONTROL_BASE_1_LOW 0c1e10 -#define PCI_0ACCESS_CONTROL_BASE_1_HIGH 0x1e14 -#define PCI_0ACCESS_CONTROL_TOP_1 0x1e18 -#define PCI_0ACCESS_CONTROL_BASE_2_LOW 0c1e20 -#define PCI_0ACCESS_CONTROL_BASE_2_HIGH 0x1e24 -#define PCI_0ACCESS_CONTROL_TOP_2 0x1e28 -#define PCI_0ACCESS_CONTROL_BASE_3_LOW 0c1e30 -#define PCI_0ACCESS_CONTROL_BASE_3_HIGH 0x1e34 -#define PCI_0ACCESS_CONTROL_TOP_3 0x1e38 -#define PCI_0ACCESS_CONTROL_BASE_4_LOW 0c1e40 -#define PCI_0ACCESS_CONTROL_BASE_4_HIGH 0x1e44 -#define PCI_0ACCESS_CONTROL_TOP_4 0x1e48 -#define PCI_0ACCESS_CONTROL_BASE_5_LOW 0c1e50 -#define PCI_0ACCESS_CONTROL_BASE_5_HIGH 0x1e54 -#define PCI_0ACCESS_CONTROL_TOP_5 0x1e58 -#define PCI_0ACCESS_CONTROL_BASE_6_LOW 0c1e60 -#define PCI_0ACCESS_CONTROL_BASE_6_HIGH 0x1e64 -#define PCI_0ACCESS_CONTROL_TOP_6 0x1e68 -#define PCI_0ACCESS_CONTROL_BASE_7_LOW 0c1e70 -#define PCI_0ACCESS_CONTROL_BASE_7_HIGH 0x1e74 -#define PCI_0ACCESS_CONTROL_TOP_7 0x1e78 -#define PCI_1CROSS_BAR_CONTROL_LOW 0x1d88 -#define PCI_1CROSS_BAR_CONTROL_HIGH 0x1d8c -#define PCI_1CROSS_BAR_TIMEOUT 0x1d84 -#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d98 -#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d9c -#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER 0x1d90 -#define PCI_1P2P_CONFIGURATION 0x1d94 -#define PCI_1ACCESS_CONTROL_BASE_0_LOW 0x1e80 -#define PCI_1ACCESS_CONTROL_BASE_0_HIGH 0x1e84 -#define PCI_1ACCESS_CONTROL_TOP_0 0x1e88 -#define PCI_1ACCESS_CONTROL_BASE_1_LOW 0c1e90 -#define PCI_1ACCESS_CONTROL_BASE_1_HIGH 0x1e94 -#define PCI_1ACCESS_CONTROL_TOP_1 0x1e98 -#define PCI_1ACCESS_CONTROL_BASE_2_LOW 0c1ea0 -#define PCI_1ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 -#define PCI_1ACCESS_CONTROL_TOP_2 0x1ea8 -#define PCI_1ACCESS_CONTROL_BASE_3_LOW 0c1eb0 -#define PCI_1ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 -#define PCI_1ACCESS_CONTROL_TOP_3 0x1eb8 -#define PCI_1ACCESS_CONTROL_BASE_4_LOW 0c1ec0 -#define PCI_1ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 -#define PCI_1ACCESS_CONTROL_TOP_4 0x1ec8 -#define PCI_1ACCESS_CONTROL_BASE_5_LOW 0c1ed0 -#define PCI_1ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 -#define PCI_1ACCESS_CONTROL_TOP_5 0x1ed8 -#define PCI_1ACCESS_CONTROL_BASE_6_LOW 0c1ee0 -#define PCI_1ACCESS_CONTROL_BASE_6_HIGH 0x1ee4 -#define PCI_1ACCESS_CONTROL_TOP_6 0x1ee8 -#define PCI_1ACCESS_CONTROL_BASE_7_LOW 0c1ef0 -#define PCI_1ACCESS_CONTROL_BASE_7_HIGH 0x1ef4 -#define PCI_1ACCESS_CONTROL_TOP_7 0x1ef8 - -/****************************************/ -/* PCI Snoop Control */ -/****************************************/ - -#define PCI_0SNOOP_CONTROL_BASE_0_LOW 0x1f00 -#define PCI_0SNOOP_CONTROL_BASE_0_HIGH 0x1f04 -#define PCI_0SNOOP_CONTROL_TOP_0 0x1f08 -#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW 0x1f10 -#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH 0x1f14 -#define PCI_0SNOOP_CONTROL_TOP_1 0x1f18 -#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW 0x1f20 -#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH 0x1f24 -#define PCI_0SNOOP_CONTROL_TOP_2 0x1f28 -#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW 0x1f30 -#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH 0x1f34 -#define PCI_0SNOOP_CONTROL_TOP_3 0x1f38 -#define PCI_1SNOOP_CONTROL_BASE_0_LOW 0x1f80 -#define PCI_1SNOOP_CONTROL_BASE_0_HIGH 0x1f84 -#define PCI_1SNOOP_CONTROL_TOP_0 0x1f88 -#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW 0x1f90 -#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH 0x1f94 -#define PCI_1SNOOP_CONTROL_TOP_1 0x1f98 -#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW 0x1fa0 -#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH 0x1fa4 -#define PCI_1SNOOP_CONTROL_TOP_2 0x1fa8 -#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW 0x1fb0 -#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH 0x1fb4 -#define PCI_1SNOOP_CONTROL_TOP_3 0x1fb8 - -/****************************************/ -/* PCI Configuration Address */ -/****************************************/ - -#define PCI_0CONFIGURATION_ADDRESS 0xcf8 -#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER 0xcfc -#define PCI_1CONFIGURATION_ADDRESS 0xc78 -#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 0xc7c -#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xc34 -#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xcb4 - -/****************************************/ -/* PCI Error Report */ -/****************************************/ - -#define PCI_0SERR_MASK 0xc28 -#define PCI_0ERROR_ADDRESS_LOW 0x1d40 -#define PCI_0ERROR_ADDRESS_HIGH 0x1d44 -#define PCI_0ERROR_DATA_LOW 0x1d48 -#define PCI_0ERROR_DATA_HIGH 0x1d4c -#define PCI_0ERROR_COMMAND 0x1d50 -#define PCI_0ERROR_CAUSE 0x1d58 -#define PCI_0ERROR_MASK 0x1d5c - -#define PCI_1SERR_MASK 0xca8 -#define PCI_1ERROR_ADDRESS_LOW 0x1dc0 -#define PCI_1ERROR_ADDRESS_HIGH 0x1dc4 -#define PCI_1ERROR_DATA_LOW 0x1dc8 -#define PCI_1ERROR_DATA_HIGH 0x1dcc -#define PCI_1ERROR_COMMAND 0x1dd0 -#define PCI_1ERROR_CAUSE 0x1dd8 -#define PCI_1ERROR_MASK 0x1ddc - - -/****************************************/ -/* Lslave Debug (for internal use) */ -/****************************************/ - -#define L_SLAVE_X0_ADDRESS 0x1d20 -#define L_SLAVE_X0_COMMAND_AND_ID 0x1d24 -#define L_SLAVE_X1_ADDRESS 0x1d28 -#define L_SLAVE_X1_COMMAND_AND_ID 0x1d2c -#define L_SLAVE_WRITE_DATA_LOW 0x1d30 -#define L_SLAVE_WRITE_DATA_HIGH 0x1d34 -#define L_SLAVE_WRITE_BYTE_ENABLE 0x1d60 -#define L_SLAVE_READ_DATA_LOW 0x1d38 -#define L_SLAVE_READ_DATA_HIGH 0x1d3c -#define L_SLAVE_READ_ID 0x1d64 - -/****************************************/ -/* PCI Configuration Function 0 */ -/****************************************/ - -#define PCI_DEVICE_AND_VENDOR_ID 0x000 -#define PCI_STATUS_AND_COMMAND 0x004 -#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 -#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C -#define PCI_SCS_0_BASE_ADDRESS 0x010 -#define PCI_SCS_1_BASE_ADDRESS 0x014 -#define PCI_SCS_2_BASE_ADDRESS 0x018 -#define PCI_SCS_3_BASE_ADDRESS 0x01C -#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS 0x020 -#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS 0x024 -#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02C -#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER 0x030 -#define PCI_CAPABILTY_LIST_POINTER 0x034 -#define PCI_INTERRUPT_PIN_AND_LINE 0x03C -#define PCI_POWER_MANAGEMENT_CAPABILITY 0x040 -#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 -#define PCI_VPD_ADDRESS 0x048 -#define PCI_VPD_DATA 0X04c -#define PCI_MSI_MESSAGE_CONTROL 0x050 -#define PCI_MSI_MESSAGE_ADDRESS 0x054 -#define PCI_MSI_MESSAGE_UPPER_ADDRESS 0x058 -#define PCI_MSI_MESSAGE_DATA 0x05c -#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY 0x058 - -/****************************************/ -/* PCI Configuration Function 1 */ -/****************************************/ - -#define PCI_CS_0_BASE_ADDRESS 0x110 -#define PCI_CS_1_BASE_ADDRESS 0x114 -#define PCI_CS_2_BASE_ADDRESS 0x118 -#define PCI_CS_3_BASE_ADDRESS 0x11c -#define PCI_BOOTCS_BASE_ADDRESS 0x120 - -/****************************************/ -/* PCI Configuration Function 2 */ -/****************************************/ - -#define PCI_P2P_MEM0_BASE_ADDRESS 0x210 -#define PCI_P2P_MEM1_BASE_ADDRESS 0x214 -#define PCI_P2P_I_O_BASE_ADDRESS 0x218 -#define PCI_CPU_BASE_ADDRESS 0x21c - -/****************************************/ -/* PCI Configuration Function 4 */ -/****************************************/ - -#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 0x410 -#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH 0x414 -#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW 0x418 -#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH 0x41c -#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW 0x420 -#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH 0x424 - - -/****************************************/ -/* PCI Configuration Function 5 */ -/****************************************/ - -#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 0x510 -#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH 0x514 -#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW 0x518 -#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH 0x51c -#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW 0x520 -#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH 0x524 - - -/****************************************/ -/* PCI Configuration Function 6 */ -/****************************************/ - -#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 0x610 -#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH 0x614 -#define PCI_DAC_CS_1_BASE_ADDRESS_LOW 0x618 -#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH 0x61c -#define PCI_DAC_CS_2_BASE_ADDRESS_LOW 0x620 -#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH 0x624 - -/****************************************/ -/* PCI Configuration Function 7 */ -/****************************************/ - -#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 0x710 -#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH 0x714 -#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW 0x718 -#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH 0x71c -#define PCI_DAC_CPU_BASE_ADDRESS_LOW 0x720 -#define PCI_DAC_CPU_BASE_ADDRESS_HIGH 0x724 - -/****************************************/ -/* Interrupts */ -/****************************************/ - -#define LOW_INTERRUPT_CAUSE_REGISTER 0xc18 -#define HIGH_INTERRUPT_CAUSE_REGISTER 0xc68 -#define CPU_INTERRUPT_MASK_REGISTER_LOW 0xc1c -#define CPU_INTERRUPT_MASK_REGISTER_HIGH 0xc6c -#define CPU_SELECT_CAUSE_REGISTER 0xc70 -#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xc24 -#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xc64 -#define PCI_0SELECT_CAUSE 0xc74 -#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xca4 -#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xce4 -#define PCI_1SELECT_CAUSE 0xcf4 -#define CPU_INT_0_MASK 0xe60 -#define CPU_INT_1_MASK 0xe64 -#define CPU_INT_2_MASK 0xe68 -#define CPU_INT_3_MASK 0xe6c - -/****************************************/ -/* I20 Support registers */ -/****************************************/ - -#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x010 -#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x014 -#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x018 -#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x01C -#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x020 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x024 -#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x028 -#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x02C -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x030 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x034 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x040 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x044 -#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 0x050 -#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 0x054 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x060 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x064 -#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x068 -#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x06C -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x070 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x074 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x0F8 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x0FC - -#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x090 -#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x094 -#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x098 -#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x09C -#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0A0 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0A4 -#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0A8 -#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0AC -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0B0 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0B4 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C0 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C4 -#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 0x0D0 -#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 0x0D4 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E0 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0E4 -#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E8 -#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0EC -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0F0 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0F4 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x078 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x07C - -#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C10 -#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C14 -#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C18 -#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C1C -#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C20 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C24 -#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C28 -#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C2C -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C30 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C34 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C40 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C44 -#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 0X1C50 -#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 0X1C54 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C60 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C64 -#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C68 -#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C6C -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C70 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C74 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1CF8 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1CFC - -#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C90 -#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C94 -#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C98 -#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C9C -#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CA0 -#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CA4 -#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CA8 -#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CAC -#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CB0 -#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CB4 -#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC0 -#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC4 -#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 0X1CD0 -#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 0X1CD4 -#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE0 -#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CE4 -#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE8 -#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CEC -#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CF0 -#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CF4 -#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1C78 -#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1C7C - -/****************************************/ -/* Communication Unit Registers */ -/****************************************/ - -#define ETHERNET_0_ADDRESS_CONTROL_LOW -#define ETHERNET_0_ADDRESS_CONTROL_HIGH 0xf204 -#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf208 -#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf20c -#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf210 -#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf214 -#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS 0xf218 -#define ETHERNET_1_ADDRESS_CONTROL_LOW 0xf220 -#define ETHERNET_1_ADDRESS_CONTROL_HIGH 0xf224 -#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf228 -#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf22c -#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf230 -#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf234 -#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS 0xf238 -#define ETHERNET_2_ADDRESS_CONTROL_LOW 0xf240 -#define ETHERNET_2_ADDRESS_CONTROL_HIGH 0xf244 -#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf248 -#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf24c -#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf250 -#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf254 -#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS 0xf258 -#define MPSC_0_ADDRESS_CONTROL_LOW 0xf280 -#define MPSC_0_ADDRESS_CONTROL_HIGH 0xf284 -#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf288 -#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf28c -#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf290 -#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf294 -#define MPSC_1_ADDRESS_CONTROL_LOW 0xf2a0 -#define MPSC_1_ADDRESS_CONTROL_HIGH 0xf2a4 -#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2a8 -#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2ac -#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b0 -#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b4 -#define MPSC_2_ADDRESS_CONTROL_LOW 0xf2c0 -#define MPSC_2_ADDRESS_CONTROL_HIGH 0xf2c4 -#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2c8 -#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2cc -#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d0 -#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d4 -#define SERIAL_INIT_PCI_HIGH_ADDRESS 0xf320 -#define SERIAL_INIT_LAST_DATA 0xf324 -#define SERIAL_INIT_STATUS_AND_CONTROL 0xf328 -#define COMM_UNIT_ARBITER_CONTROL 0xf300 -#define COMM_UNIT_CROSS_BAR_TIMEOUT 0xf304 -#define COMM_UNIT_INTERRUPT_CAUSE 0xf310 -#define COMM_UNIT_INTERRUPT_MASK 0xf314 -#define COMM_UNIT_ERROR_ADDRESS 0xf314 - -/****************************************/ -/* Cunit Debug (for internal use) */ -/****************************************/ - -#define CUNIT_ADDRESS 0xf340 -#define CUNIT_COMMAND_AND_ID 0xf344 -#define CUNIT_WRITE_DATA_LOW 0xf348 -#define CUNIT_WRITE_DATA_HIGH 0xf34c -#define CUNIT_WRITE_BYTE_ENABLE 0xf358 -#define CUNIT_READ_DATA_LOW 0xf350 -#define CUNIT_READ_DATA_HIGH 0xf354 -#define CUNIT_READ_ID 0xf35c - -/****************************************/ -/* Fast Ethernet Unit Registers */ -/****************************************/ - -/* Ethernet */ - -#define ETHERNET_PHY_ADDRESS_REGISTER 0x2000 -#define ETHERNET_SMI_REGISTER 0x2010 - -/* Ethernet 0 */ - -#define ETHERNET0_PORT_CONFIGURATION_REGISTER 0x2400 -#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER 0x2408 -#define ETHERNET0_PORT_COMMAND_REGISTER 0x2410 -#define ETHERNET0_PORT_STATUS_REGISTER 0x2418 -#define ETHERNET0_SERIAL_PARAMETRS_REGISTER 0x2420 -#define ETHERNET0_HASH_TABLE_POINTER_REGISTER 0x2428 -#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2430 -#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2438 -#define ETHERNET0_SDMA_CONFIGURATION_REGISTER 0x2440 -#define ETHERNET0_SDMA_COMMAND_REGISTER 0x2448 -#define ETHERNET0_INTERRUPT_CAUSE_REGISTER 0x2450 -#define ETHERNET0_INTERRUPT_MASK_REGISTER 0x2458 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 0x2480 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1 0x2484 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2 0x2488 -#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3 0x248c -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 0x24a0 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1 0x24a4 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2 0x24a8 -#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3 0x24ac -#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 0x24e0 -#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 0x24e4 -#define ETHERNET0_MIB_COUNTER_BASE 0x2500 - -/* Ethernet 1 */ - -#define ETHERNET1_PORT_CONFIGURATION_REGISTER 0x2800 -#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER 0x2808 -#define ETHERNET1_PORT_COMMAND_REGISTER 0x2810 -#define ETHERNET1_PORT_STATUS_REGISTER 0x2818 -#define ETHERNET1_SERIAL_PARAMETRS_REGISTER 0x2820 -#define ETHERNET1_HASH_TABLE_POINTER_REGISTER 0x2828 -#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2830 -#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2838 -#define ETHERNET1_SDMA_CONFIGURATION_REGISTER 0x2840 -#define ETHERNET1_SDMA_COMMAND_REGISTER 0x2848 -#define ETHERNET1_INTERRUPT_CAUSE_REGISTER 0x2850 -#define ETHERNET1_INTERRUPT_MASK_REGISTER 0x2858 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0 0x2880 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1 0x2884 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2 0x2888 -#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3 0x288c -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0 0x28a0 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1 0x28a4 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2 0x28a8 -#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3 0x28ac -#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0 0x28e0 -#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1 0x28e4 -#define ETHERNET1_MIB_COUNTER_BASE 0x2900 - -/* Ethernet 2 */ - -#define ETHERNET2_PORT_CONFIGURATION_REGISTER 0x2c00 -#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER 0x2c08 -#define ETHERNET2_PORT_COMMAND_REGISTER 0x2c10 -#define ETHERNET2_PORT_STATUS_REGISTER 0x2c18 -#define ETHERNET2_SERIAL_PARAMETRS_REGISTER 0x2c20 -#define ETHERNET2_HASH_TABLE_POINTER_REGISTER 0x2c28 -#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2c30 -#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2c38 -#define ETHERNET2_SDMA_CONFIGURATION_REGISTER 0x2c40 -#define ETHERNET2_SDMA_COMMAND_REGISTER 0x2c48 -#define ETHERNET2_INTERRUPT_CAUSE_REGISTER 0x2c50 -#define ETHERNET2_INTERRUPT_MASK_REGISTER 0x2c58 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0 0x2c80 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1 0x2c84 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2 0x2c88 -#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3 0x2c8c -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0 0x2ca0 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1 0x2ca4 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2 0x2ca8 -#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3 0x2cac -#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0 0x2ce0 -#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1 0x2ce4 -#define ETHERNET2_MIB_COUNTER_BASE 0x2d00 - -/****************************************/ -/* SDMA Registers */ -/****************************************/ - -#define SDMA_GROUP_CONFIGURATION_REGISTER 0xb1f0 -#define CHANNEL0_CONFIGURATION_REGISTER 0x4000 -#define CHANNEL0_COMMAND_REGISTER 0x4008 -#define CHANNEL0_RX_CMD_STATUS 0x4800 -#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES 0x4804 -#define CHANNEL0_RX_BUFFER_POINTER 0x4808 -#define CHANNEL0_RX_NEXT_POINTER 0x480c -#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER 0x4810 -#define CHANNEL0_TX_CMD_STATUS 0x4C00 -#define CHANNEL0_TX_PACKET_SIZE 0x4C04 -#define CHANNEL0_TX_BUFFER_POINTER 0x4C08 -#define CHANNEL0_TX_NEXT_POINTER 0x4C0c -#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER 0x4c10 -#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER 0x4c14 -#define CHANNEL1_CONFIGURATION_REGISTER 0x6000 -#define CHANNEL1_COMMAND_REGISTER 0x6008 -#define CHANNEL1_RX_CMD_STATUS 0x6800 -#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES 0x6804 -#define CHANNEL1_RX_BUFFER_POINTER 0x6808 -#define CHANNEL1_RX_NEXT_POINTER 0x680c -#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 -#define CHANNEL1_TX_CMD_STATUS 0x6C00 -#define CHANNEL1_TX_PACKET_SIZE 0x6C04 -#define CHANNEL1_TX_BUFFER_POINTER 0x6C08 -#define CHANNEL1_TX_NEXT_POINTER 0x6C0c -#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 -#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER 0x6c10 -#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER 0x6c14 - -/* SDMA Interrupt */ - -#define SDMA_CAUSE 0xb820 -#define SDMA_MASK 0xb8a0 - - -/****************************************/ -/* Baude Rate Generators Registers */ -/****************************************/ - -/* BRG 0 */ - -#define BRG0_CONFIGURATION_REGISTER 0xb200 -#define BRG0_BAUDE_TUNING_REGISTER 0xb204 - -/* BRG 1 */ - -#define BRG1_CONFIGURATION_REGISTER 0xb208 -#define BRG1_BAUDE_TUNING_REGISTER 0xb20c - -/* BRG 2 */ - -#define BRG2_CONFIGURATION_REGISTER 0xb210 -#define BRG2_BAUDE_TUNING_REGISTER 0xb214 - -/* BRG Interrupts */ - -#define BRG_CAUSE_REGISTER 0xb834 -#define BRG_MASK_REGISTER 0xb8b4 - -/* MISC */ - -#define MAIN_ROUTING_REGISTER 0xb400 -#define RECEIVE_CLOCK_ROUTING_REGISTER 0xb404 -#define TRANSMIT_CLOCK_ROUTING_REGISTER 0xb408 -#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER 0xb40c -#define WATCHDOG_CONFIGURATION_REGISTER 0xb410 -#define WATCHDOG_VALUE_REGISTER 0xb414 - - -/****************************************/ -/* Flex TDM Registers */ -/****************************************/ - -/* FTDM Port */ - -#define FLEXTDM_TRANSMIT_READ_POINTER 0xa800 -#define FLEXTDM_RECEIVE_READ_POINTER 0xa804 -#define FLEXTDM_CONFIGURATION_REGISTER 0xa808 -#define FLEXTDM_AUX_CHANNELA_TX_REGISTER 0xa80c -#define FLEXTDM_AUX_CHANNELA_RX_REGISTER 0xa810 -#define FLEXTDM_AUX_CHANNELB_TX_REGISTER 0xa814 -#define FLEXTDM_AUX_CHANNELB_RX_REGISTER 0xa818 - -/* FTDM Interrupts */ - -#define FTDM_CAUSE_REGISTER 0xb830 -#define FTDM_MASK_REGISTER 0xb8b0 - - -/****************************************/ -/* GPP Interface Registers */ -/****************************************/ - -#define GPP_IO_CONTROL 0xf100 -#define GPP_LEVEL_CONTROL 0xf110 -#define GPP_VALUE 0xf104 -#define GPP_INTERRUPT_CAUSE 0xf108 -#define GPP_INTERRUPT_MASK 0xf10c - -#define MPP_CONTROL0 0xf000 -#define MPP_CONTROL1 0xf004 -#define MPP_CONTROL2 0xf008 -#define MPP_CONTROL3 0xf00c -#define DEBUG_PORT_MULTIPLEX 0xf014 -#define SERIAL_PORT_MULTIPLEX 0xf010 - -/****************************************/ -/* I2C Registers */ -/****************************************/ - -#define I2C_SLAVE_ADDRESS 0xc000 -#define I2C_EXTENDED_SLAVE_ADDRESS 0xc040 -#define I2C_DATA 0xc004 -#define I2C_CONTROL 0xc008 -#define I2C_STATUS_BAUDE_RATE 0xc00C -#define I2C_SOFT_RESET 0xc01c - -/****************************************/ -/* MPSC Registers */ -/****************************************/ - -/* MPSC0 */ - -#define MPSC0_MAIN_CONFIGURATION_LOW 0x8000 -#define MPSC0_MAIN_CONFIGURATION_HIGH 0x8004 -#define MPSC0_PROTOCOL_CONFIGURATION 0x8008 -#define CHANNEL0_REGISTER1 0x800c -#define CHANNEL0_REGISTER2 0x8010 -#define CHANNEL0_REGISTER3 0x8014 -#define CHANNEL0_REGISTER4 0x8018 -#define CHANNEL0_REGISTER5 0x801c -#define CHANNEL0_REGISTER6 0x8020 -#define CHANNEL0_REGISTER7 0x8024 -#define CHANNEL0_REGISTER8 0x8028 -#define CHANNEL0_REGISTER9 0x802c -#define CHANNEL0_REGISTER10 0x8030 -#define CHANNEL0_REGISTER11 0x8034 - -/* MPSC1 */ - -#define MPSC1_MAIN_CONFIGURATION_LOW 0x9000 -#define MPSC1_MAIN_CONFIGURATION_HIGH 0x9004 -#define MPSC1_PROTOCOL_CONFIGURATION 0x9008 -#define CHANNEL1_REGISTER1 0x900c -#define CHANNEL1_REGISTER2 0x9010 -#define CHANNEL1_REGISTER3 0x9014 -#define CHANNEL1_REGISTER4 0x9018 -#define CHANNEL1_REGISTER5 0x901c -#define CHANNEL1_REGISTER6 0x9020 -#define CHANNEL1_REGISTER7 0x9024 -#define CHANNEL1_REGISTER8 0x9028 -#define CHANNEL1_REGISTER9 0x902c -#define CHANNEL1_REGISTER10 0x9030 -#define CHANNEL1_REGISTER11 0x9034 - -/* MPSCs Interupts */ - -#define MPSC0_CAUSE 0xb804 -#define MPSC0_MASK 0xb884 -#define MPSC1_CAUSE 0xb80c -#define MPSC1_MASK 0xb88c - -#endif /* __INCgt64240rh */ diff --git a/arch/mips/momentum/ocelot_g/gt64240_dep.h b/arch/mips/momentum/ocelot_g/gt64240_dep.h deleted file mode 100644 index f51bf0d6e1fb..000000000000 --- a/arch/mips/momentum/ocelot_g/gt64240_dep.h +++ /dev/null @@ -1,57 +0,0 @@ -/*********************************************************************** - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64240/gt64240-dep.h - * Board-dependent definitions for GT-64120 chip. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - *********************************************************************** - */ - -#ifndef _ASM_GT64240_DEP_H -#define _ASM_GT64240_DEP_H - -#include /* for KSEG1ADDR() */ -#include /* for cpu_to_le32() */ - -/* - * PCI address allocation - */ -#if 0 -#define GT_PCI_MEM_BASE (0x22000000) -#define GT_PCI_MEM_SIZE GT_DEF_PCI0_MEM0_SIZE -#define GT_PCI_IO_BASE (0x20000000) -#define GT_PCI_IO_SIZE GT_DEF_PCI0_IO_SIZE -#endif - -extern unsigned long gt64240_base; - -#define GT64240_BASE (gt64240_base) - -/* - * Because of an error/peculiarity in the Galileo chip, we need to swap the - * bytes when running bigendian. - */ - -#define GT_WRITE(ofs, data) \ - *(volatile u32 *)(GT64240_BASE+(ofs)) = cpu_to_le32(data) -#define GT_READ(ofs, data) \ - *(data) = le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) -#define GT_READ_DATA(ofs) \ - le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) - -#define GT_WRITE_16(ofs, data) \ - *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data) -#define GT_READ_16(ofs, data) \ - *(data) = le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs))) - -#define GT_WRITE_8(ofs, data) \ - *(volatile u8 *)(GT64240_BASE+(ofs)) = data -#define GT_READ_8(ofs, data) \ - *(data) = *(volatile u8 *)(GT64240_BASE+(ofs)) - -#endif /* _ASM_GT64120_MOMENCO_OCELOT_GT64120_DEP_H */ diff --git a/arch/mips/momentum/ocelot_g/pci-irq.c b/arch/mips/momentum/ocelot_g/pci-irq.c deleted file mode 100644 index e300e151ff85..000000000000 --- a/arch/mips/momentum/ocelot_g/pci-irq.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for gt64240 controller. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - - -void __devinit gt64240_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - /* loop over all known devices on this bus */ - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if ((current_bus->number == 0) && - PCI_SLOT(devices->devfn) == 1) { - /* Intel 82543 Gigabit MAC */ - devices->irq = 2; /* irq_nr is 2 for INT0 */ - } else if ((current_bus->number == 0) && - PCI_SLOT(devices->devfn) == 2) { - /* Intel 82543 Gigabit MAC */ - devices->irq = 3; /* irq_nr is 3 for INT1 */ - } else if ((current_bus->number == 1) && - PCI_SLOT(devices->devfn) == 3) { - /* Intel 21555 bridge */ - devices->irq = 5; /* irq_nr is 8 for INT6 */ - } else if ((current_bus->number == 1) && - PCI_SLOT(devices->devfn) == 4) { - /* PMC Slot */ - devices->irq = 9; /* irq_nr is 9 for INT7 */ - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write(current_bus, devices, - PCI_INTERRUPT_LINE, 1, devices->irq); - - /* enable master for everything but the GT-64240 */ - if (((current_bus->number != 0) && (current_bus->number != 1)) - || (PCI_SLOT(devices->devfn) != 0)) { - bus->ops->read(current_bus, devices, - PCI_COMMAND, 2, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write(current_bus, devices, - PCI_COMMAND, 2, cmd); - } - } -} diff --git a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c index 2b480b2ef03b..82bebaeb0087 100644 --- a/arch/mips/momentum/ocelot_g/prom.c +++ b/arch/mips/momentum/ocelot_g/prom.c @@ -20,8 +20,8 @@ #include #include #include +#include -#include "gt64240.h" #include "ocelot_pld.h" struct callvectors* debug_vectors; @@ -38,10 +38,8 @@ const char *get_system_type(void) return "Momentum Ocelot"; } -/* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(void) { - uint32_t tmp; int argc = fw_arg0; char **arg = (char **) fw_arg1; char **env = (char **) fw_arg2; @@ -78,10 +76,8 @@ void __init prom_init(void) bus_clock = simple_strtol(*env + strlen("busclock="), NULL, 10); } - *env++; + env++; } - - debug_vectors->printf("Booting Linux kernel...\n"); } unsigned long __init prom_free_prom_memory(void) diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c index 9a3010dae023..1d313eb56059 100644 --- a/arch/mips/momentum/ocelot_g/setup.c +++ b/arch/mips/momentum/ocelot_g/setup.c @@ -1,6 +1,4 @@ /* - * setup.c - * * BRIEF MODULE DESCRIPTION * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines * @@ -55,14 +53,14 @@ #include #include #include +#include #include #include #include #include #include #include -#include -#include "gt64240.h" + #include "ocelot_pld.h" #ifdef CONFIG_GALILLEO_GT64240_ETH @@ -88,8 +86,6 @@ static unsigned long ENTRYLO(unsigned long paddr) _CACHE_UNCACHED)) >> 6; } -static void __init setup_l3cache(unsigned long size); - /* setup code for a handoff from a version 2 PMON 2000 PROM */ void PMON_v2_setup(void) { @@ -104,8 +100,10 @@ void PMON_v2_setup(void) GT64240 Internal Regs 0xf4000000 0xe0000000 UARTs (CS2) 0xfd000000 0xe0001000 */ - add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); - add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), 0xfd000000, PM_4K); + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), + 0xf4000000, PM_64K); + add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), + 0xfd000000, PM_4K); /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM in the CS[012] region. We can't use ioremap() yet. The NVRAM @@ -114,15 +112,57 @@ void PMON_v2_setup(void) Ocelot PLD (CS0) 0xfc000000 0xe0020000 NVRAM (CS1) 0xfc800000 0xe0030000 */ - add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), 0xfc000000, PM_64K); - add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), 0xfc800000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), + 0xfc000000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), + 0xfc800000, PM_64K); gt64240_base = 0xf4000000; } -static void __init momenco_ocelot_g_setup(void) +extern int rm7k_tcache_enabled; + +/* + * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() + */ +#define Page_Invalidate_T 0x16 +static void __init setup_l3cache(unsigned long size) { - void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); + int register i; + + printk("Enabling L3 cache..."); + + /* Enable the L3 cache in the GT64120A's CPU Configuration register */ + GT_WRITE(0, GT_READ(0) | (1<<14)); + + /* Enable the L3 cache in the CPU */ + set_c0_config(1<<12 /* CONF_TE */); + + /* Clear the cache */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i < size; i+= 4096) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (KSEG0ADDR(i)), + "i" (Page_Invalidate_T)); + } + + /* Let the RM7000 MM code know that the tertiary cache is enabled */ + rm7k_tcache_enabled = 1; + + printk("Done\n"); +} + +static int __init momenco_ocelot_g_setup(void) +{ + void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); unsigned int tmpword; board_time_init = gt64240_time_init; @@ -200,51 +240,11 @@ static void __init momenco_ocelot_g_setup(void) /* FIXME: Fix up the DiskOnChip mapping */ GT_WRITE(0x468, 0xfef73); -} -early_initcall(momenco_ocelot_g_setup); - -extern int rm7k_tcache_enabled; -/* - * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() - */ -#define Page_Invalidate_T 0x16 -static void __init setup_l3cache(unsigned long size) -{ - int register i; - unsigned long tmp; - - printk("Enabling L3 cache..."); - - /* Enable the L3 cache in the GT64120A's CPU Configuration register */ - GT_READ(0, &tmp); - GT_WRITE(0, tmp | (1<<14)); - - /* Enable the L3 cache in the CPU */ - set_c0_config(1<<12 /* CONF_TE */); - - /* Clear the cache */ - write_c0_taglo(0); - write_c0_taghi(0); - - for (i=0; i < size; i+= 4096) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (KSEG0ADDR(i)), - "i" (Page_Invalidate_T)); - } - - /* Let the RM7000 MM code know that the tertiary cache is enabled */ - rm7k_tcache_enabled = 1; - - printk("Done\n"); + return 0; } +early_initcall(momenco_ocelot_g_setup); /* This needs to be one of the first initcalls, because no I/O port access can work before this */ @@ -252,12 +252,12 @@ static void __init setup_l3cache(unsigned long size) static int io_base_ioremap(void) { /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ - void *io_remap_range = ioremap(0xc0000000, 0x30000000); + unsigned long io_remap_range; - if (!io_remap_range) { + io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000); + if (!io_remap_range) panic("Could not ioremap I/O port range"); - } - printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); return 0; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index a380308eff83..9cdb8b8ba00a 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_MIPS_MV64340) += ops-mv64340.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_MIPS_TX3927) += ops-jmr3927.o +obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o # # These are still pretty much in the old state, watch, go blind. @@ -34,20 +35,20 @@ obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o -obj-$(CONFIG_MIPS_MV64340) += fixup-mv64340.o +obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o -obj-$(CONFIG_MOMENCO_OCELOT_C) += pci-ocelot-c.o -obj-$(CONFIG_MOMENCO_OCELOT_G) += pci-ocelot-g.o +obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o +obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o ops-gt64240.o pci-ocelot-g.o obj-$(CONFIG_NEC_EAGLE) += fixup-eagle.o ops-vrc4173.o -obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o +obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ + pci-yosemite.o obj-$(CONFIG_SGI_IP27) += pci-ip27.o obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o obj-$(CONFIG_SIBYTE_SB1250) += pci-sb1250.o obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o +obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o -obj-$(CONFIG_TANBAC_TB0229) += fixup-tb0229.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o -obj-$(CONFIG_VICTOR_MPC30X) += fixup-capcella.o -obj-$(CONFIG_MACH_VR41XX) += pci-vr41xx.o -obj-$(CONFIG_ZAO_CAPCELLA) += fixup-victor-mpc30x.o +obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o +obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c index 167ed4367cdb..9a0d68ed69d5 100644 --- a/arch/mips/pci/fixup-capcella.c +++ b/arch/mips/pci/fixup-capcella.c @@ -1,17 +1,21 @@ /* - * FILE NAME - * arch/mips/vr41xx/zao-capcella/pci_fixup.c + * fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups. * - * BRIEF MODULE DESCRIPTION - * The ZAO Networks Capcella specific PCI fixups. + * Copyright (C) 2002,2004 Yoichi Yuasa * - * Copyright 2002 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include @@ -38,3 +42,7 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_capcella[slot][pin]; } + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-jaguar.c b/arch/mips/pci/fixup-jaguar.c new file mode 100644 index 000000000000..fa78b9b1f435 --- /dev/null +++ b/arch/mips/pci/fixup-jaguar.c @@ -0,0 +1,42 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Marvell MV64340 interrupt fixup code. + * + * Marvell wants an NDA for their docs so this was written without + * documentation. You've been warned. + * + * Copyright (C) 2004 Ralf Baechle + */ +#include +#include +#include + +#include +#include + +/* + * WARNING: Example of how _NOT_ to do it. + */ +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) + return 3; /* PCI-X A */ + if (bus == 0 && slot == 2) + return 4; /* PCI-X B */ + if (bus == 1 && slot == 1) + return 5; /* PCI A */ + if (bus == 1 && slot == 2) + return 6; /* PCI B */ + +return 0; + panic("Whooops in pcibios_map_irq"); +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c new file mode 100644 index 000000000000..1320c42af570 --- /dev/null +++ b/arch/mips/pci/fixup-mpc30x.c @@ -0,0 +1,48 @@ +/* + * fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups. + * + * Copyright (C) 2002,2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include +#include + +static const int internal_func_irqs[] __initdata = { + VRC4173_CASCADE_IRQ, + VRC4173_AC97_IRQ, + VRC4173_USB_IRQ, +}; + +static char irq_tab_mpc30x[] __initdata = { + [12] = VRC4173_PCMCIA1_IRQ, + [13] = VRC4173_PCMCIA2_IRQ, + [29] = MQ200_IRQ, +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot == 30) + return internal_func_irqs[PCI_FUNC(dev->devfn)]; + + return irq_tab_mpc30x[slot]; +} + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-mv64340.c b/arch/mips/pci/fixup-mv64340.c deleted file mode 100644 index fa78b9b1f435..000000000000 --- a/arch/mips/pci/fixup-mv64340.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Marvell MV64340 interrupt fixup code. - * - * Marvell wants an NDA for their docs so this was written without - * documentation. You've been warned. - * - * Copyright (C) 2004 Ralf Baechle - */ -#include -#include -#include - -#include -#include - -/* - * WARNING: Example of how _NOT_ to do it. - */ -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int bus = dev->bus->number; - - if (bus == 0 && slot == 1) - return 3; /* PCI-X A */ - if (bus == 0 && slot == 2) - return 4; /* PCI-X B */ - if (bus == 1 && slot == 1) - return 5; /* PCI A */ - if (bus == 1 && slot == 2) - return 6; /* PCI B */ - -return 0; - panic("Whooops in pcibios_map_irq"); -} - -struct pci_fixup pcibios_fixups[] = { - {0} -}; diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c new file mode 100644 index 000000000000..0cc86ecebff8 --- /dev/null +++ b/arch/mips/pci/fixup-ocelot-c.c @@ -0,0 +1,39 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) + return 2; /* PCI-X A */ + if (bus == 1 && slot == 1) + return 12; /* PCI-X B */ + if (bus == 1 && slot == 2) + return 4; /* PCI B */ + +return 0; + panic("Whooops in pcibios_map_irq"); +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff --git a/arch/mips/pci/fixup-ocelot-g.c b/arch/mips/pci/fixup-ocelot-g.c new file mode 100644 index 000000000000..9a2cc8505db8 --- /dev/null +++ b/arch/mips/pci/fixup-ocelot-g.c @@ -0,0 +1,35 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int bus = dev->bus->number; + + if (bus == 0 && slot == 1) /* Intel 82543 Gigabit MAC */ + return 2; /* irq_nr is 2 for INT0 */ + + if (bus == 0 && slot == 2) /* Intel 82543 Gigabit MAC */ + return 3; /* irq_nr is 3 for INT1 */ + + if (bus == 1 && slot == 3) /* Intel 21555 bridge */ + return 5; /* irq_nr is 8 for INT6 */ + + if (bus == 1 && slot == 4) /* PMC Slot */ + return 9; /* irq_nr is 9 for INT7 */ + + return -1; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c new file mode 100644 index 000000000000..ca4d99fbe123 --- /dev/null +++ b/arch/mips/pci/fixup-tb0219.c @@ -0,0 +1,64 @@ +/* + * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. + * + * Copyright (C) 2003 Megasolution Inc. + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = -1; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT2_IRQ; + break; + case 14: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, + LEVEL_LOW); + irq = TB0219_PCI_SLOT3_IRQ; + break; + default: + break; + } + + return irq; +} + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c index 17c300c8ae34..50e639e04a4a 100644 --- a/arch/mips/pci/fixup-tb0226.c +++ b/arch/mips/pci/fixup-tb0226.c @@ -1,78 +1,83 @@ /* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c + * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups. * - * BRIEF MODULE DESCRIPTION - * The TANBAC TB0226 specific PCI fixups. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include -void __init pcibios_fixup_irqs(void) +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_dev *dev = NULL; - u8 slot, pin; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot = PCI_SLOT(dev->devfn); - dev->irq = 0; + int irq = -1; - switch (slot) { - case 12: - vr41xx_set_irq_trigger(GD82559_1_PIN, + switch (slot) { + case 12: + vr41xx_set_irq_trigger(GD82559_1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); + irq = GD82559_1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(GD82559_2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); + irq = GD82559_2_IRQ; + break; + case 14: + switch (pin) { + case 1: + vr41xx_set_irq_trigger(UPD720100_INTA_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTA_PIN, + LEVEL_LOW); + irq = UPD720100_INTA_IRQ; + break; + case 2: + vr41xx_set_irq_trigger(UPD720100_INTB_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); - dev->irq = GD82559_1_IRQ; + vr41xx_set_irq_level(UPD720100_INTB_PIN, + LEVEL_LOW); + irq = UPD720100_INTB_IRQ; break; - case 13: - vr41xx_set_irq_trigger(GD82559_2_PIN, + case 3: + vr41xx_set_irq_trigger(UPD720100_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); - dev->irq = GD82559_2_IRQ; + vr41xx_set_irq_level(UPD720100_INTC_PIN, + LEVEL_LOW); + irq = UPD720100_INTC_IRQ; break; - case 14: - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - switch (pin) { - case 1: - vr41xx_set_irq_trigger(UPD720100_INTA_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTA_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTA_IRQ; - break; - case 2: - vr41xx_set_irq_trigger(UPD720100_INTB_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTB_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTB_IRQ; - break; - case 3: - vr41xx_set_irq_trigger(UPD720100_INTC_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(UPD720100_INTC_PIN, - LEVEL_LOW); - dev->irq = UPD720100_INTC_IRQ; - break; - } + default: break; } - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + default: + break; } + + return irq; } + +struct pci_fixup pcibios_fixups[] __initdata = { + { .pass = 0, }, +}; diff --git a/arch/mips/pci/fixup-tb0229.c b/arch/mips/pci/fixup-tb0229.c deleted file mode 100644 index 8109c05c5832..000000000000 --- a/arch/mips/pci/fixup-tb0229.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c - * - * BRIEF MODULE DESCRIPTION - * The TANBAC TB0229(VR4131DIMM) specific PCI fixups. - * - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#include - -void __init pcibios_fixup_irqs(void) -{ -#ifdef CONFIG_TANBAC_TB0219 - struct pci_dev *dev = NULL; - u8 slot; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot = PCI_SLOT(dev->devfn); - dev->irq = 0; - - switch (slot) { - case 12: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT1_IRQ; - break; - case 13: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT2_IRQ; - break; - case 14: - vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, - TRIGGER_LEVEL, - SIGNAL_THROUGH); - vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, - LEVEL_LOW); - dev->irq = TB0219_PCI_SLOT3_IRQ; - break; - default: - break; - } - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } -#endif -} diff --git a/arch/mips/pci/fixup-victor-mpc30x.c b/arch/mips/pci/fixup-victor-mpc30x.c deleted file mode 100644 index 3ec5951feab2..000000000000 --- a/arch/mips/pci/fixup-victor-mpc30x.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/victor-mpc30x/pci_fixup.c - * - * BRIEF MODULE DESCRIPTION - * The Victor MP-C303/304 specific PCI fixups. - * - * Copyright 2002 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include -#include - -/* - * Shortcuts - */ -#define PCMCIA1 VRC4173_PCMCIA1_IRQ -#define PCMCIA2 VRC4173_PCMCIA2_IRQ -#define MQ MQ200_IRQ - -static const int internal_func_irqs[8] __initdata = { - VRC4173_CASCADE_IRQ, - VRC4173_AC97_IRQ, - VRC4173_USB_IRQ, - -}; - -static char irq_tab_mpc30x[][5] __initdata = { - [12] = { PCMCIA1, PCMCIA1, 0, 0 }, - [13] = { PCMCIA2, PCMCIA2, 0, 0 }, - [29] = { MQ, MQ, 0, 0 }, /* mediaQ MQ-200 */ -}; - -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (slot == 30) - return internal_func_irqs[PCI_FUNC(dev->devfn)]; - - return irq_tab_mpc30x[slot][pin]; -} diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c index 72b809685bdf..92e40b091643 100644 --- a/arch/mips/pci/fixup-yosemite.c +++ b/arch/mips/pci/fixup-yosemite.c @@ -26,21 +26,12 @@ #include #include -static char irq_tab_yosemite[8][5] __initdata = { - /* INTA INTB INTC INTD */ - { -1, -1, -1, -1, -1 }, - { -1, 3, 3, 3, 3 }, - { -1, 4, 4, 4, 4 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, - { -1, -1, -1, -1, -1 }, -}; - int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - return irq_tab_yosemite[slot][pin]; + if (pin == 0) + return -1; + + return 3; /* Everything goes to one irq bit */ } struct pci_fixup pcibios_fixups[] = { diff --git a/arch/mips/pci/ops-gt64240.c b/arch/mips/pci/ops-gt64240.c new file mode 100644 index 000000000000..6929faa65490 --- /dev/null +++ b/arch/mips/pci/ops-gt64240.c @@ -0,0 +1,149 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm + * Copyright (C) 2004 Ralf Baechle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + + +#define MASTER_ABORT_BIT 0x100 + +/* + * galileo_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + + +static int gt_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int size, u32 *val, u32 address_reg, u32 data_reg) +{ + uint32_t address; + int dev, busno; + + busno = bus->number; + dev = PCI_SLOT(devfn); + + /* verify the range */ + if (dev == 31) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + switch (size) { + case 1: + GT_READ_8(data_reg + (offset & 0x3), val); + break; + case 2: + GT_READ_16(data_reg + (offset & 0x3), val); + break; + case 4: + *val = GT_READ(data_reg); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int gt_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int size, u32 val, u32 address_reg, u32 data_reg) +{ + unsigned int address; + int dev, busno; + + busno = bus->number; + dev = PCI_SLOT(devfn); + + /* verify the range */ + if (dev == 31) + return PCIBIOS_DEVICE_NOT_FOUND; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + switch (size) { + case 1: + GT_WRITE_8(data_reg + (offset & 0x3), val); + break; + case 2: + GT_WRITE_16(data_reg + (offset & 0x3), val); + break; + case 4: + GT_WRITE(data_reg, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +#define BUILD_PCI_OPS(host) \ + \ +static int gt_bus ## host ## _read_config(struct pci_bus *bus, \ + unsigned int devfn, int reg, int size, u32 * val) \ +{ \ + return gt_read_config(bus, devfn, reg, size, val, \ + PCI_ ## host ## CONFIGURATION_ADDRESS, \ + PCI_ ## host ## CONFIGURATION_DATA_VIRTUAL_REGISTER); \ +} \ + \ +static int gt_bus ## host ## _write_config(struct pci_bus *bus, \ + unsigned int devfn, int reg, int size, u32 val) \ +{ \ + return gt_write_config(bus, devfn, reg, size, val, \ + PCI_ ## host ## CONFIGURATION_ADDRESS, \ + PCI_ ## host ## CONFIGURATION_DATA_VIRTUAL_REGISTER); \ +} \ + \ +struct pci_ops gt_bus ## host ## _pci_ops = { \ + .read = gt_bus ## host ## _read_config, \ + .write = gt_bus ## host ## _write_config \ +}; + +BUILD_PCI_OPS(0) +BUILD_PCI_OPS(1) diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c index 51b16d48d031..11184fa64443 100644 --- a/arch/mips/pci/ops-msc.c +++ b/arch/mips/pci/ops-msc.c @@ -48,8 +48,12 @@ static int msc_pcibios_config_access(unsigned char access_type, unsigned char type; u32 intr; - if ((busnum == 0) && (PCI_SLOT(devfn) == 0)) +#ifdef CONFIG_MIPS_BOARDS_GEN + if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) { + /* MIPS Core boards have SOCit connected as device 17 */ return -1; + } +#endif /* Clear status register bits. */ MSC_WRITE(MSC01_PCI_INTSTAT, diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c new file mode 100644 index 000000000000..46c636c27e06 --- /dev/null +++ b/arch/mips/pci/ops-titan-ht.c @@ -0,0 +1,125 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn, + int offset, u32 * val) +{ + volatile uint32_t address; + int busno; + + busno = bus->number; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + if (busno != 0) + address |= 1; + + /* + * RM9000 HT Errata: Issue back to back HT config + * transcations. Issue a BIU sync before and + * after the HT cycle + */ + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + udelay(30); + + *(volatile int32_t *) 0xfb0006f8 = address; + *(val) = *(volatile int32_t *) 0xfb0006fc; + + udelay(30); + + * (volatile int32_t *) 0xfb0000f0 |= 0x2; + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 * val) +{ + uint32_t dword; + + titan_ht_config_read_dword(bus, devfn, offset, &dword); + + dword >>= ((offset & 3) << 3); + dword &= (0xffffffffU >> ((4 - size) << 8)); + + return PCIBIOS_SUCCESSFUL; +} + +static inline int titan_ht_config_write_dword(struct pci_bus *bus, + unsigned int devfn, int offset, u32 val) +{ + volatile uint32_t address; + int busno; + + busno = bus->number; + + address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; + if (busno != 0) + address |= 1; + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + udelay(30); + + *(volatile int32_t *) 0xfb0006f8 = address; + *(volatile int32_t *) 0xfb0006fc = val; + + udelay(30); + + *(volatile int32_t *) 0xfb0000f0 |= 0x2; + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 val) +{ + uint32_t val1, val2, mask; + + titan_ht_config_read_dword(bus, devfn, offset, &val2); + + val1 = val << ((offset & 3) << 3); + mask = ~(0xffffffffU >> ((4 - size) << 8)); + val2 &= ~(mask << ((offset & 3) << 8)); + + titan_ht_config_write_dword(bus, devfn, offset, val1 | val2); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops titan_ht_pci_ops = { + .read = titan_ht_config_read, + .write = titan_ht_config_write, +}; diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c index 12e79346fa58..1ac7880dd2a0 100644 --- a/arch/mips/pci/ops-titan.c +++ b/arch/mips/pci/ops-titan.c @@ -39,30 +39,30 @@ static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 * val) { - int dev, bus, func; + int dev, busno, func; uint32_t address_reg, data_reg; uint32_t address; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); address_reg = TITAN_PCI_0_CONFIG_ADDRESS; data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; + address = (busno << 16) | (dev << 11) | (func << 8) | + (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ TITAN_WRITE(address_reg, address); switch (size) { case 1: - TITAN_READ_8(data_reg + (offset & 0x3), val); + TITAN_READ_8(data_reg + (reg & 0x3), val); break; case 2: - TITAN_READ_16(data_reg + (offset & 0x2), val); + TITAN_READ_16(data_reg + (reg & 0x2), val); break; case 4: @@ -80,17 +80,17 @@ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 val) { uint32_t address_reg, data_reg, address; - int dev, bus, func; + int dev, busno, func; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); address_reg = TITAN_PCI_0_CONFIG_ADDRESS; data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; + address = (busno << 16) | (dev << 11) | (func << 8) | + (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ TITAN_WRITE(address_reg, address); @@ -98,11 +98,11 @@ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, /* write the data */ switch (size) { case 1: - TITAN_WRITE_8(data_reg + (offset & 0x3), val); + TITAN_WRITE_8(data_reg + (reg & 0x3), val); break; case 2: - TITAN_WRITE_16(data_reg + (offset & 0x2), val); + TITAN_WRITE_16(data_reg + (reg & 0x2), val); break; case 4: diff --git a/arch/mips/pci/ops-vr41xx.c b/arch/mips/pci/ops-vr41xx.c new file mode 100644 index 000000000000..44654605e461 --- /dev/null +++ b/arch/mips/pci/ops-vr41xx.c @@ -0,0 +1,126 @@ +/* + * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series. + * + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * Changes: + * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include +#include + +#include + +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) + +static inline int set_pci_configuration_address(unsigned char number, + unsigned int devfn, int where) +{ + if (number == 0) { + /* + * Type 0 configuration + */ + if (PCI_SLOT(devfn) < 11 || where > 0xff) + return -EINVAL; + + writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) | + (where & 0xfc), PCICONFAREG); + } else { + /* + * Type 1 configuration + */ + if (where > 0xff) + return -EINVAL; + + writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) | + (where & 0xfc) | 1U, PCICONFAREG); + } + + return 0; +} + +static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *val) +{ + uint32_t data; + + *val = 0xffffffffU; + if (set_pci_configuration_address(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xffU; + break; + case 2: + *val = (data >> ((where & 2) << 3)) & 0xffffU; + break; + case 4: + *val = data; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t val) +{ + uint32_t data; + int shift; + + if (set_pci_configuration_address(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + shift = (where & 3) << 3; + data &= ~(0xffU << shift); + data |= ((val & 0xffU) << shift); + break; + case 2: + shift = (where & 2) << 3; + data &= ~(0xffffU << shift); + data |= ((val & 0xffffU) << shift); + break; + case 4: + data = val; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + writel(data, PCICONFDREG); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops vr41xx_pci_ops = { + .read = pci_config_read, + .write = pci_config_write, +}; diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c index 29b52757a337..dec6d3754fde 100644 --- a/arch/mips/pci/pci-ocelot-c.c +++ b/arch/mips/pci/pci-ocelot-c.c @@ -1,61 +1,140 @@ /* - * Copyright 2002 Momentum Computer - * Author: Matthew Dharm + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * Copyright (C) 2004 by Ralf Baechle */ + #include #include -#include -#include -#include -#include #include +#include #include /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. + * We assume the address ranges have already been setup appropriately by + * the firmware. PMON in case of the Ocelot C does that. */ +static struct resource mv_pci_io_mem0_resource = { + .name = "MV64340 PCI0 IO MEM", + .flags = IORESOURCE_IO +}; + +static struct resource mv_pci_mem0_resource = { + .name = "MV64340 PCI0 MEM", + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops mv64340_bus0_pci_ops; + +static struct pci_controller mv_bus0_controller = { + .pci_ops = &mv64340_bus0_pci_ops, + .mem_resource = &mv_pci_mem0_resource, + .io_resource = &mv_pci_io_mem0_resource, +}; + +static uint32_t mv_io_base, mv_io_size; + +static void mv64340_pci0_init(void) +{ + uint32_t mem0_base, mem0_size; + uint32_t io_base, io_size; + + io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16; + io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16; + mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16; + mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16; + + mv_pci_io_mem0_resource.start = 0; + mv_pci_io_mem0_resource.end = io_size - 1; + mv_pci_mem0_resource.start = mem0_base; + mv_pci_mem0_resource.end = mem0_base + mem0_size - 1; + mv_bus0_controller.mem_offset = mem0_base; + mv_bus0_controller.io_offset = 0; + + ioport_resource.end = io_size - 1; + + register_pci_controller(&mv_bus0_controller); + + mv_io_base = io_base; + mv_io_size = io_size; +} + +static struct resource mv_pci_io_mem1_resource = { + .name = "MV64340 PCI1 IO MEM", + .flags = IORESOURCE_IO +}; + +static struct resource mv_pci_mem1_resource = { + .name = "MV64340 PCI1 MEM", + .flags = IORESOURCE_MEM +}; -void mv64340_board_pcibios_fixup_bus(struct pci_bus *c); +extern struct pci_ops mv64340_bus1_pci_ops; -struct pci_fixup pcibios_fixups[] = { - {0} +static struct pci_controller mv_bus1_controller = { + .pci_ops = &mv64340_bus1_pci_ops, + .mem_resource = &mv_pci_mem1_resource, + .io_resource = &mv_pci_io_mem1_resource, }; -void __init pcibios_fixup_bus(struct pci_bus *c) +static __init void mv64340_pci1_init(void) { - mv64340_board_pcibios_fixup_bus(c); + uint32_t mem0_base, mem0_size; + uint32_t io_base, io_size; + + io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16; + io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16; + mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16; + mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16; + + /* + * Here we assume the I/O window of second bus to be contiguous with + * the first. A gap is no problem but would waste address space for + * remapping the port space. + */ + mv_pci_io_mem1_resource.start = mv_io_size; + mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1; + mv_pci_mem1_resource.start = mem0_base; + mv_pci_mem1_resource.end = mem0_base + mem0_size - 1; + mv_bus1_controller.mem_offset = mem0_base; + mv_bus1_controller.io_offset = 0; + + ioport_resource.end = io_base + io_size -mv_io_base - 1; + + register_pci_controller(&mv_bus1_controller); + + mv_io_size = io_base + io_size - mv_io_base; } -void __init pcibios_init(void) +static __init int __init ocelot_c_pci_init(void) { - /* Reset PCI I/O and PCI MEM values */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; - - pci_scan_bus(0, &mv64340_bus0_pci_ops, NULL); - pci_scan_bus(1, &mv64340_bus1_pci_ops, NULL); + unsigned long io_v_base; + uint32_t enable; + + enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE); + + /* + * We require at least one enabled I/O or PCI memory window or we + * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3. + */ + if (enable & (0x01 << 9) || enable & (0x01 << 10)) + mv64340_pci0_init(); + + if (enable & (0x01 << 14) || enable & (0x01 << 15)) + mv64340_pci1_init(); + + if (mv_io_size) { + io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size); + if (!io_v_base) + panic("Could not ioremap I/O port range"); + + set_io_port_base(io_v_base); + } + + return 0; } + +arch_initcall(ocelot_c_pci_init); diff --git a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c index 34c3ec8d1645..11b05c7e6751 100644 --- a/arch/mips/pci/pci-ocelot-g.c +++ b/arch/mips/pci/pci-ocelot-g.c @@ -1,460 +1,90 @@ /* - * Copyright 2002 Momentum Computer - * Author: Matthew Dharm + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * Copyright (C) 2004 by Ralf Baechle * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * This doesn't really fly - but I don't have a GT64240 system for testing. */ +#include +#include #include #include -#include -#include -#include -#include -#include "gt64240.h" - -#include - -#define SELF 0 -#define MASTER_ABORT_BIT 0x100 +#include +#include /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. - */ - -void gt64240_board_pcibios_fixup_bus(struct pci_bus *c); - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(int bus, int devfn, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(int bus, int devfn, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(int bus, int devfn, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(int bus, int devfn, - int offset, u8 val); -static int galileo_pcibios_write_config_word(int bus, int devfn, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(int bus, int devfn, - int offset, u32 val); - -static int pci_read(struct pci_bus *bus, unsigned int devfs, int where, - int size, u32 * val); -static int pci_write(struct pci_bus *bus, unsigned int devfs, int where, - int size, u32 val); - -/* - * General-purpose PCI functions. - */ - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - /* Accessing device 31 crashes the GT-64240. */ - if (dev < 5) - return 0; - return -1; -} - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Note that bus 0 and bus 1 are local, and we assume all other busses are - * bridged from bus 1. This is a safe assumption, since any other - * configuration will require major modifications to the CP7000G - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + * We assume these address ranges have been programmed into the GT-64240 by + * the firmware. PMON in case of the Ocelot G does that. Note the size of + * the I/O range is completly stupid; I/O mappings are limited to at most + * 256 bytes by the PCI spec and deprecated; and just to make things worse + * apparently many devices don't decode more than 64k of I/O space. */ -static int galileo_pcibios_read_config_dword(int bus, int devfn, - int offset, u32 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* read the data */ - GT_READ(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_read_config_word(int bus, int devfn, - int offset, u16 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* read the data */ - GT_READ_16(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(int bus, int devfn, - int offset, u8 * val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; +#define gt_io_size 0x20000000UL +#define gt_io_base 0xe0000000UL - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_READ_8(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(int bus, int devfn, - int offset, u32 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_write_config_word(int bus, int devfn, - int offset, u16 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE_16(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(int bus, int devfn, - int offset, u8 val) -{ - int dev, func; - uint32_t address_reg, data_reg; - uint32_t address; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* verify the range */ - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* select the GT-64240 registers to communicate with the PCI bus */ - if (bus == 0) { - address_reg = PCI_0CONFIGURATION_ADDRESS; - data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; - } else { - address_reg = PCI_1CONFIGURATION_ADDRESS; - data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; - if (bus == 1) - bus = 0; - } - - address = (bus << 16) | (dev << 11) | (func << 8) | - (offset & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - GT_WRITE(address_reg, address); - - /* write the data */ - GT_WRITE_8(data_reg + (offset & 0x3), val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops galileo_pci_ops = { - .read = pci_read, - .write = pci_write +static struct resource gt_pci_mem0_resource = { + .name = "MV64240 PCI0 MEM", + .start = 0xc0000000UL, + .end = 0xcfffffffUL, + .flags = IORESOURCE_MEM }; -static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) -{ - switch (size) { - case 1: - return galileo_pcibios_read_config_byte(bus->number, - devfn, where, - (u8 *) val); - case 2: - return galileo_pcibios_read_config_word(bus->number, - devfn, where, - (u16 *) val); - case 4: - return galileo_pcibios_read_config_dword(bus->number, - devfn, where, - (u32 *) val); - } - return PCIBIOS_FUNC_NOT_SUPPORTED; -} - -static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - switch (size) { - case 1: - return galileo_pcibios_write_config_byte(bus->number, - devfn, where, - val); - case 2: - return galileo_pcibios_write_config_word(bus->number, - devfn, where, - val); - case 4: - return galileo_pcibios_write_config_dword(bus->number, - devfn, where, - val); - } - return PCIBIOS_FUNC_NOT_SUPPORTED; -} - -struct pci_fixup pcibios_fixups[] = { - {0} +static struct resource gt_pci_io_mem0_resource = { + .name = "MV64240 PCI0 IO MEM", + .start = 0xe0000000UL, + .end = 0xefffffffUL, + .flags = IORESOURCE_IO }; -void __devinit pcibios_fixup_bus(struct pci_bus *c) -{ - gt64240_board_pcibios_fixup_bus(c); -} +static struct pci_controller gt_bus0_controller = { + .pci_ops = >_bus0_pci_ops, + .mem_resource = >_pci_mem0_resource, + .mem_offset = 0xc0000000UL, + .io_resource = >_pci_io_mem0_resource, + .io_offset = 0x00000000UL +}; +static struct resource gt_pci_mem1_resource = { + .name = "MV64240 PCI1 MEM", + .start = 0xd0000000UL, + .end = 0xdfffffffUL, + .flags = IORESOURCE_MEM +}; -/******************************************************************** -* pci0P2PConfig - This function set the PCI_0 P2P configurate. -* For more information on the P2P read PCI spec. -* -* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. -* -* Returns: true. -*/ -void pci0P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, - unsigned int busNum, unsigned int devNum) -{ - uint32_t regData; +static struct resource gt_pci_io_mem1_resource = { + .name = "MV64240 PCI1 IO MEM", + .start = 0xf0000000UL, + .end = 0xffffffffUL, + .flags = IORESOURCE_IO +}; - regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | - ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); - GT_WRITE(PCI_0P2P_CONFIGURATION, regData); -} +static struct pci_controller gt_bus1_controller = { + .pci_ops = >_bus1_pci_ops, + .mem_resource = >_pci_mem1_resource, + .mem_offset = 0xd0000000UL, + .io_resource = >_pci_io_mem1_resource, + .io_offset = 0x10000000UL +}; -/******************************************************************** -* pci1P2PConfig - This function set the PCI_1 P2P configurate. -* For more information on the P2P read PCI spec. -* -* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower -* Boundry. -* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper -* Boundry. -* unsigned int busNum - The CPI bus number to which the PCI interface -* is connected. -* unsigned int devNum - The PCI interface's device number. -* -* Returns: true. -*/ -void pci1P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, - unsigned int busNum, unsigned int devNum) +static __init int __init ocelot_g_pci_init(void) { - uint32_t regData; + unsigned long io_v_base; - regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | - ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); - GT_WRITE(PCI_1P2P_CONFIGURATION, regData); -} + if (gt_io_size) { + io_v_base = (unsigned long) ioremap(gt_io_base, gt_io_size); + if (!io_v_base) + panic("Could not ioremap I/O port range"); -#define PCI0_STATUS_COMMAND_REG 0x4 -#define PCI1_STATUS_COMMAND_REG 0x84 - -static int __init pcibios_init(void) -{ - /* Reset PCI I/O and PCI MEM values */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + set_io_port_base(io_v_base); + } - pci_scan_bus(0, &galileo_pci_ops, NULL); - pci_scan_bus(1, &galileo_pci_ops, NULL); + register_pci_controller(>_bus0_controller); + register_pci_controller(>_bus1_controller); return 0; } -subsys_initcall(pcibios_init); +arch_initcall(ocelot_g_pci_init); diff --git a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c index 8068b0171f0c..a6db6f028574 100644 --- a/arch/mips/pci/pci-vr41xx.c +++ b/arch/mips/pci/pci-vr41xx.c @@ -1,48 +1,32 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/pciu.c + * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * PCI Control Unit routines for the NEC VR4100 series. + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Copyright 2001-2003 MontaVista Software Inc. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Changes: - * Paul Mundt - * - Fix deadlock-causing PCIU access race for VR4131. - * * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. */ -#include #include #include #include -#include #include #include @@ -51,183 +35,257 @@ #include "pci-vr41xx.h" -static inline int vr41xx_pci_config_access(unsigned char bus, - unsigned int devfn, int where) -{ - if (bus == 0) { - /* - * Type 0 configuration - */ - if (PCI_SLOT(devfn) < 11 || where > 255) - return -1; - - writel((1UL << PCI_SLOT(devfn)) | - (PCI_FUNC(devfn) << 8) | - (where & 0xfc), PCICONFAREG); - } else { - /* - * Type 1 configuration - */ - if (where > 255) - return -1; - - writel((bus << 16) | - (devfn << 8) | (where & 0xfc) | 1UL, PCICONFAREG); - } - - return 0; -} +extern struct pci_ops vr41xx_pci_ops; -static int vr41xx_pci_config_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - u32 data; - - *val = 0xffffffffUL; - if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; +static struct pci_master_address_conversion pci_master_memory1 = { + .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS, + .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK, + .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS, +}; - data = readl(PCICONFDREG); +static struct pci_target_address_conversion pci_target_memory1 = { + .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK, + .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS, +}; - switch (size) { - case 1: - *val = (data >> ((where & 3) << 3)) & 0xffUL; - break; - case 2: - *val = (data >> ((where & 2) << 3)) & 0xffffUL; - break; - case 4: - *val = data; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } +static struct pci_master_address_conversion pci_master_io = { + .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS, + .address_mask = PCI_MASTER_IO_ADDRESS_MASK, + .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS, +}; - return PCIBIOS_SUCCESSFUL; -} +static struct pci_mailbox_address pci_mailbox = { + .base_address = PCI_MAILBOX_BASE_ADDRESS, +}; -static int vr41xx_pci_config_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 data; - int shift; +static struct pci_target_address_window pci_target_window1 = { + .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS, +}; - if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; +static struct resource pci_mem_resource = { + .name = "PCI Memory resources", + .start = PCI_MEM_RESOURCE_START, + .end = PCI_MEM_RESOURCE_END, + .flags = IORESOURCE_MEM, +}; - data = readl(PCICONFDREG); +static struct resource pci_io_resource = { + .name = "PCI I/O resources", + .start = PCI_IO_RESOURCE_START, + .end = PCI_IO_RESOURCE_END, + .flags = IORESOURCE_IO, +}; - switch (size) { - case 1: - shift = (where & 3) << 3; - data &= ~(0xff << shift); - data |= ((val & 0xff) << shift); - break; - case 2: - shift = (where & 2) << 3; - data &= ~(0xffff << shift); - data |= ((val & 0xffff) << shift); - break; - case 4: - data = val; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } +static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = { + .master_memory1 = &pci_master_memory1, + .target_memory1 = &pci_target_memory1, + .master_io = &pci_master_io, + .exclusive_access = CANNOT_LOCK_FROM_DEVICE, + .wait_time_limit_from_irdy_to_trdy = 0, + .mailbox = &pci_mailbox, + .target_window1 = &pci_target_window1, + .master_latency_timer = 0x80, + .retry_limit = 0, + .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR, + .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE, +}; - writel(data, PCICONFDREG); +static struct pci_controller vr41xx_pci_controller = { + .pci_ops = &vr41xx_pci_ops, + .mem_resource = &pci_mem_resource, + .io_resource = &pci_io_resource, +}; - return PCIBIOS_SUCCESSFUL; +void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup) +{ + vr41xx_pci_controller_unit_setup = *setup; } -struct pci_ops vr41xx_pci_ops = { - .read = vr41xx_pci_config_read, - .write = vr41xx_pci_config_write, -}; - -void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map) +static int __init vr41xx_pciu_init(void) { - struct vr41xx_pci_address_space *s; - unsigned long vtclock; - u32 config; - int n; + struct pci_controller_unit_setup *setup; + struct pci_master_address_conversion *master; + struct pci_target_address_conversion *target; + struct pci_mailbox_address *mailbox; + struct pci_target_address_window *window; + unsigned long vtclock, pci_clock_max; + uint32_t val; - if (!map) - return; + setup = &vr41xx_pci_controller_unit_setup; /* Disable PCI interrupt */ - writew(0, MPCIINTREG); + vr41xx_disable_pciint(); /* Supply VTClock to PCIU */ vr41xx_supply_clock(PCIU_CLOCK); - /* - * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK - * before doing any PCIU access to avoid deadlock on VR4131. - */ - udelay(1); + /* Dummy write, waiting for supply of VTClock. */ + vr41xx_disable_pciint(); /* Select PCI clock */ + if (setup->pci_clock_max != 0) + pci_clock_max = setup->pci_clock_max; + else + pci_clock_max = PCI_CLOCK_MAX; vtclock = vr41xx_get_vtclock_frequency(); - if (vtclock < MAX_PCI_CLOCK) + if (vtclock < pci_clock_max) writel(EQUAL_VTCLOCK, PCICLKSELREG); - else if ((vtclock / 2) < MAX_PCI_CLOCK) + else if ((vtclock / 2) < pci_clock_max) writel(HALF_VTCLOCK, PCICLKSELREG); - else if ((vtclock / 4) < MAX_PCI_CLOCK) + else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 && + (vtclock / 3) < pci_clock_max) + writel(ONE_THIRD_VTCLOCK, PCICLKSELREG); + else if ((vtclock / 4) < pci_clock_max) writel(QUARTER_VTCLOCK, PCICLKSELREG); - else - printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n"); + else { + printk(KERN_ERR "PCI Clock is over 33MHz.\n"); + return -EINVAL; + } /* Supply PCI clock by PCI bus */ vr41xx_supply_clock(PCI_CLOCK); - /* - * Set PCI memory & I/O space address conversion registers - * for master transaction. - */ - if (map->mem1 != NULL) { - s = map->mem1; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMMAW1REG); + if (setup->master_memory1 != NULL) { + master = setup->master_memory1; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIA(master->pci_base_address); + writel(val, PCIMMAW1REG); + } else { + val = readl(PCIMMAW1REG); + val &= ~WINEN; + writel(val, PCIMMAW1REG); + } + + if (setup->master_memory2 != NULL) { + master = setup->master_memory2; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIA(master->pci_base_address); + writel(val, PCIMMAW2REG); + } else { + val = readl(PCIMMAW2REG); + val &= ~WINEN; + writel(val, PCIMMAW2REG); + } + + if (setup->target_memory1 != NULL) { + target = setup->target_memory1; + val = TARGET_MSK(target->address_mask) | + WINEN | + ITA(target->bus_base_address); + writel(val, PCITAW1REG); + } else { + val = readl(PCITAW1REG); + val &= ~WINEN; + writel(val, PCITAW1REG); + } + + if (setup->target_memory2 != NULL) { + target = setup->target_memory2; + val = TARGET_MSK(target->address_mask) | + WINEN | + ITA(target->bus_base_address); + writel(val, PCITAW2REG); + } else { + val = readl(PCITAW2REG); + val &= ~WINEN; + writel(val, PCITAW2REG); + } + + if (setup->master_io != NULL) { + master = setup->master_io; + val = IBA(master->bus_base_address) | + MASTER_MSK(master->address_mask) | + WINEN | + PCIIA(master->pci_base_address); + writel(val, PCIMIOAWREG); + } else { + val = readl(PCIMIOAWREG); + val &= ~WINEN; + writel(val, PCIMIOAWREG); + } + + if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE) + writel(UNLOCK, PCIEXACCREG); + else + writel(0, PCIEXACCREG); + + if (current_cpu_data.cputype == CPU_VR4122) + writel(TRDYV(setup->wait_time_limit_from_irdy_to_trdy), PCITRDYVREG); + + writel(MLTIM(setup->master_latency_timer), LATTIMEREG); + + if (setup->mailbox != NULL) { + mailbox = setup->mailbox; + val = MBADD(mailbox->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, MAILBAREG); } - if (map->mem2 != NULL) { - s = map->mem2; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMMAW2REG); + + if (setup->target_window1) { + window = setup->target_window1; + val = PMBA(window->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, PCIMBA1REG); + } + + if (setup->target_window2) { + window = setup->target_window2; + val = PMBA(window->base_address) | TYPE_32BITSPACE | + MSI_MEMORY | PREF_APPROVAL; + writel(val, PCIMBA2REG); } - if (map->io != NULL) { - s = map->io; - config = (s->internal_base & 0xff000000) | - ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | - ((s->pci_base & 0xff000000) >> 24); - writel(config, PCIMIOAWREG); + + val = readl(RETVALREG); + val &= ~RTYVAL_MASK; + val |= RTYVAL(setup->retry_limit); + writel(val, RETVALREG); + + val = readl(PCIAPCNTREG); + val &= ~(TKYGNT | PAPC); + + switch (setup->arbiter_priority_control) { + case PCI_ARBITRATION_MODE_ALTERNATE_0: + val |= PAPC_ALTERNATE_0; + break; + case PCI_ARBITRATION_MODE_ALTERNATE_B: + val |= PAPC_ALTERNATE_B; + break; + default: + val |= PAPC_FAIR; + break; } - /* Set target memory windows */ - writel(0x00081000, PCITAW1REG); - writel(0UL, PCITAW2REG); - pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL); - pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL); + if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE) + val |= TKYGNT_ENABLE; + + writel(val, PCIAPCNTREG); + + writel(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR, COMMANDREG); /* Clear bus error */ - n = readl(BUSERRADREG); + readl(BUSERRADREG); + + writel(CONFIG_DONE, PCIENREG); + + if (setup->mem_resource != NULL) + vr41xx_pci_controller.mem_resource = setup->mem_resource; - if (current_cpu_data.cputype == CPU_VR4122) { - writel(0UL, PCITRDYVREG); - pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804); + if (setup->io_resource != NULL) { + vr41xx_pci_controller.io_resource = setup->io_resource; } else { - writel(100UL, PCITRDYVREG); - pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004); + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; } - writel(CONFIG_DONE, PCIENREG); - pciu_write_config_dword(PCI_COMMAND, - PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + register_pci_controller(&vr41xx_pci_controller); + + return 0; } + +early_initcall(vr41xx_pciu_init); diff --git a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h index f0fca0c786a8..3a5f69bfb998 100644 --- a/arch/mips/pci/pci-vr41xx.h +++ b/arch/mips/pci/pci-vr41xx.h @@ -1,164 +1,151 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/pciu.h + * pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * Include file for PCI Control Unit of the NEC VR4100 series. + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Copyright 2002 MontaVista Software Inc. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __PCI_VR41XX_H +#define __PCI_VR41XX_H + +#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) +#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) +#define PCITAW1REG KSEG1ADDR(0x0f000c08) +#define PCITAW2REG KSEG1ADDR(0x0f000c0c) +#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) + #define IBA(addr) ((addr) & 0xff000000U) + #define MASTER_MSK(mask) (((mask) >> 11) & 0x000fe000U) + #define PCIA(addr) (((addr) >> 24) & 0x000000ffU) + #define TARGET_MSK(mask) (((mask) >> 8) & 0x000fe000U) + #define ITA(addr) (((addr) >> 24) & 0x000000ffU) + #define PCIIA(addr) (((addr) >> 24) & 0x000000ffU) + #define WINEN 0x1000U +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) +#define PCIMAILREG KSEG1ADDR(0x0f000c1c) +#define BUSERRADREG KSEG1ADDR(0x0f000c24) + #define EA(reg) ((reg) &0xfffffffc) + +#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) + #define MABTCLR 0x80000000U + #define TRDYCLR 0x40000000U + #define PARCLR 0x20000000U + #define MBCLR 0x10000000U + #define SERRCLR 0x08000000U + #define RTYCLR 0x04000000U + #define MABCLR 0x02000000U + #define TABCLR 0x01000000U + /* RFU */ + #define MABTMSK 0x00008000U + #define TRDYMSK 0x00004000U + #define PARMSK 0x00002000U + #define MBMSK 0x00001000U + #define SERRMSK 0x00000800U + #define RTYMSK 0x00000400U + #define MABMSK 0x00000200U + #define TABMSK 0x00000100U + #define IBAMABT 0x00000080U + #define TRDYRCH 0x00000040U + #define PAR 0x00000020U + #define MB 0x00000010U + #define PCISERR 0x00000008U + #define RTYRCH 0x00000004U + #define MABORT 0x00000002U + #define TABORT 0x00000001U + +#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) + #define UNLOCK 0x2U + #define EAREQ 0x1U +#define PCIRECONTREG KSEG1ADDR(0x0f000c30) + #define RTRYCNT(reg) ((reg) & 0x000000ffU) +#define PCIENREG KSEG1ADDR(0x0f000c34) + #define CONFIG_DONE 0x4U +#define PCICLKSELREG KSEG1ADDR(0x0f000c38) + #define EQUAL_VTCLOCK 0x2U + #define HALF_VTCLOCK 0x0U + #define ONE_THIRD_VTCLOCK 0x3U + #define QUARTER_VTCLOCK 0x1U +#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) + #define TRDYV(val) ((uint32_t)(val) & 0xffU) +#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) + +#define VENDORIDREG KSEG1ADDR(0x0f000d00) +#define DEVICEIDREG KSEG1ADDR(0x0f000d00) +#define COMMANDREG KSEG1ADDR(0x0f000d04) +#define STATUSREG KSEG1ADDR(0x0f000d04) +#define REVIDREG KSEG1ADDR(0x0f000d08) +#define CLASSREG KSEG1ADDR(0x0f000d08) +#define CACHELSREG KSEG1ADDR(0x0f000d0c) +#define LATTIMEREG KSEG1ADDR(0x0f000d0c) + #define MLTIM(val) (((uint32_t)(val) << 7) & 0xff00U) +#define MAILBAREG KSEG1ADDR(0x0f000d10) +#define PCIMBA1REG KSEG1ADDR(0x0f000d14) +#define PCIMBA2REG KSEG1ADDR(0x0f000d18) + #define MBADD(base) ((base) & 0xfffff800U) + #define PMBA(base) ((base) & 0xffe00000U) + #define PREF 0x8U + #define PREF_APPROVAL 0x8U + #define PREF_DISAPPROVAL 0x0U + #define TYPE 0x6U + #define TYPE_32BITSPACE 0x0U + #define MSI 0x1U + #define MSI_MEMORY 0x0U +#define INTLINEREG KSEG1ADDR(0x0f000d3c) +#define INTPINREG KSEG1ADDR(0x0f000d3c) +#define RETVALREG KSEG1ADDR(0x0f000d40) +#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) + #define TKYGNT 0x04000000U + #define TKYGNT_ENABLE 0x04000000U + #define TKYGNT_DISABLE 0x00000000U + #define PAPC 0x03000000U + #define PAPC_ALTERNATE_B 0x02000000U + #define PAPC_ALTERNATE_0 0x01000000U + #define PAPC_FAIR 0x00000000U + #define RTYVAL(val) (((uint32_t)(val) << 7) & 0xff00U) + #define RTYVAL_MASK 0xff00U + +#define PCI_CLOCK_MAX 33333333U + /* - * Changes: - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Default setup */ -#ifndef __VR41XX_PCIU_H -#define __VR41XX_PCIU_H - -#include -#include - -#define BIT(x) (1 << (x)) - -#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) -#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) -#define PCITAW1REG KSEG1ADDR(0x0f000c08) -#define PCITAW2REG KSEG1ADDR(0x0f000c0c) -#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) -#define INTERNAL_BUS_BASE_ADDRESS 0xff000000 -#define ADDRESS_MASK 0x000fe000 -#define PCI_ACCESS_ENABLE BIT(12) -#define PCI_ADDRESS_SETTING 0x000000ff - -#define PCICONFDREG KSEG1ADDR(0x0f000c14) -#define PCICONFAREG KSEG1ADDR(0x0f000c18) -#define PCIMAILREG KSEG1ADDR(0x0f000c1c) - -#define BUSERRADREG KSEG1ADDR(0x0f000c24) -#define ERROR_ADDRESS 0xfffffffc - -#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) -#define MABTCLR BIT(31) -#define TRDYCLR BIT(30) -#define PARCLR BIT(29) -#define MBCLR BIT(28) -#define SERRCLR BIT(27) - -#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) -#define UNLOCK BIT(1) -#define EAREQ BIT(0) - -#define PCIRECONTREG KSEG1ADDR(0x0f000c30) -#define RTRYCNT 0x000000ff - -#define PCIENREG KSEG1ADDR(0x0f000c34) -#define CONFIG_DONE BIT(2) - -#define PCICLKSELREG KSEG1ADDR(0x0f000c38) -#define EQUAL_VTCLOCK 0x00000002 -#define HALF_VTCLOCK 0x00000000 -#define QUARTER_VTCLOCK 0x00000001 - -#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) - -#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) - -#define PCIU_CONFIGREGS_BASE KSEG1ADDR(0x0f000d00) -#define VENDORIDREG KSEG1ADDR(0x0f000d00) -#define DEVICEIDREG KSEG1ADDR(0x0f000d00) -#define COMMANDREG KSEG1ADDR(0x0f000d04) -#define STATUSREG KSEG1ADDR(0x0f000d04) -#define REVIDREG KSEG1ADDR(0x0f000d08) -#define CLASSREG KSEG1ADDR(0x0f000d08) -#define CACHELSREG KSEG1ADDR(0x0f000d0c) -#define LATTIMEREG KSEG1ADDR(0x0f000d0c) -#define MAILBAREG KSEG1ADDR(0x0f000d10) -#define PCIMBA1REG KSEG1ADDR(0x0f000d14) -#define PCIMBA2REG KSEG1ADDR(0x0f000d18) -#define INTLINEREG KSEG1ADDR(0x0f000d3c) -#define INTPINREG KSEG1ADDR(0x0f000d3c) -#define RETVALREG KSEG1ADDR(0x0f000d40) -#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) - -#define MPCIINTREG KSEG1ADDR(0x0f0000b2) - -#define MAX_PCI_CLOCK 33333333 - -static inline int pciu_read_config_byte(int where, u8 * val) -{ - u32 data; - - data = readl(PCIU_CONFIGREGS_BASE + where); - *val = (u8) (data >> ((where & 3) << 3)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int pciu_read_config_word(int where, u16 * val) -{ - u32 data; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - data = readl(PCIU_CONFIGREGS_BASE + where); - *val = (u16) (data >> ((where & 2) << 3)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int pciu_read_config_dword(int where, u32 * val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - *val = readl(PCIU_CONFIGREGS_BASE + where); +#define PCI_MASTER_MEM1_BUS_BASE_ADDRESS 0x10000000U +#define PCI_MASTER_MEM1_ADDRESS_MASK 0x7c000000U +#define PCI_MASTER_MEM1_PCI_BASE_ADDRESS 0x10000000U - return PCIBIOS_SUCCESSFUL; -} +#define PCI_TARGET_MEM1_ADDRESS_MASK 0x08000000U +#define PCI_TARGET_MEM1_BUS_BASE_ADDRESS 0x00000000U -static inline int pciu_write_config_byte(int where, u8 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_MASTER_IO_BUS_BASE_ADDRESS 0x16000000U +#define PCI_MASTER_IO_ADDRESS_MASK 0x7e000000U +#define PCI_MASTER_IO_PCI_BASE_ADDRESS 0x00000000U - return 0; -} +#define PCI_MAILBOX_BASE_ADDRESS 0x00000000U -static inline int pciu_write_config_word(int where, u16 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_TARGET_WINDOW1_BASE_ADDRESS 0x00000000U - return 0; -} +#define IO_PORT_BASE KSEG1ADDR(PCI_MASTER_IO_BUS_BASE_ADDRESS) +#define IO_PORT_RESOURCE_START PCI_MASTER_IO_PCI_BASE_ADDRESS +#define IO_PORT_RESOURCE_END (~PCI_MASTER_IO_ADDRESS_MASK & PCI_MASTER_ADDRESS_MASK) -static inline int pciu_write_config_dword(int where, u32 val) -{ - writel(val, PCIU_CONFIGREGS_BASE + where); +#define PCI_IO_RESOURCE_START 0x01000000UL +#define PCI_IO_RESOURCE_END 0x01ffffffUL - return 0; -} +#define PCI_MEM_RESOURCE_START 0x11000000UL +#define PCI_MEM_RESOURCE_END 0x13ffffffUL -#endif /* __VR41XX_PCIU_H */ +#endif /* __PCI_VR41XX_H */ diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c new file mode 100644 index 000000000000..c1151f43c9af --- /dev/null +++ b/arch/mips/pci/pci-yosemite.c @@ -0,0 +1,37 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004 by Ralf Baechle + * + */ +#include +#include +#include +#include +#include +#include + +extern struct pci_ops titan_pci_ops; + +static struct resource py_mem_resource = { + "Titan PCI MEM", 0xe0000000UL, 0xe3ffffffUL, IORESOURCE_MEM +}; + +static struct resource py_io_resource = { + "Titan IO MEM", 0x00000000UL, 0x00ffffffUL, IORESOURCE_IO, +}; + +static struct pci_controller py_controller = { + .pci_ops = &titan_pci_ops, + .mem_resource = &py_mem_resource, + .mem_offset = 0x10000000UL, + .io_resource = &py_io_resource, + .io_offset = 0x00000000UL +}; + +static int __init pmc_yosemite_setup(void) +{ + register_pci_controller(&py_controller); +} diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index eacfcda3d282..9bee1e937ae6 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -231,7 +231,7 @@ static void __init pcibios_fixup_device_resources(struct pci_dev *dev, { /* Update device resources. */ struct pci_controller *hose = (struct pci_controller *)bus->sysdata; - unsigned long offset; + unsigned long offset = 0; int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile index 1537b6d36617..bc17586235a3 100644 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ b/arch/mips/pmc-sierra/yosemite/Makefile @@ -1,8 +1,7 @@ # -# Makefile for the PMC-Sierra Titan +# Makefile for the PMC-Sierra Titan # -obj-y += irq-handler.o irq.o prom.o setup.o +obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_HYPERTRANSPORT) += ht-irq.o ht.o +obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c new file mode 100644 index 000000000000..1ff8d95d0970 --- /dev/null +++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c @@ -0,0 +1,184 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Support for KGDB for the Yosemite board. We make use of single serial + * port to be used for KGDB as well as console. The second serial port + * seems to be having a problem. Single IRQ is allocated for both the + * ports. Hence, the interrupt routing code needs to figure out whether + * the interrupt came from channel A or B. + */ + +#include + +#if defined(CONFIG_KGDB) +#include + +/* + * Baud rate, Parity, Data and Stop bit settings for the + * serial port on the Yosemite. Note that the Early printk + * patch has been added. So, we should be all set to go + */ +#define YOSEMITE_BAUD_2400 2400 +#define YOSEMITE_BAUD_4800 4800 +#define YOSEMITE_BAUD_9600 9600 +#define YOSEMITE_BAUD_19200 19200 +#define YOSEMITE_BAUD_38400 38400 +#define YOSEMITE_BAUD_57600 57600 +#define YOSEMITE_BAUD_115200 115200 + +#define YOSEMITE_PARITY_NONE 0 +#define YOSEMITE_PARITY_ODD 0x08 +#define YOSEMITE_PARITY_EVEN 0x18 +#define YOSEMITE_PARITY_MARK 0x28 +#define YOSEMITE_PARITY_SPACE 0x38 + +#define YOSEMITE_DATA_5BIT 0x0 +#define YOSEMITE_DATA_6BIT 0x1 +#define YOSEMITE_DATA_7BIT 0x2 +#define YOSEMITE_DATA_8BIT 0x3 + +#define YOSEMITE_STOP_1BIT 0x0 +#define YOSEMITE_STOP_2BIT 0x4 + +/* This is crucial */ +#define SERIAL_REG_OFS 0x1 + +#define SERIAL_RCV_BUFFER 0x0 +#define SERIAL_TRANS_HOLD 0x0 +#define SERIAL_SEND_BUFFER 0x0 +#define SERIAL_INTR_ENABLE (1 * SERIAL_REG_OFS) +#define SERIAL_INTR_ID (2 * SERIAL_REG_OFS) +#define SERIAL_DATA_FORMAT (3 * SERIAL_REG_OFS) +#define SERIAL_LINE_CONTROL (3 * SERIAL_REG_OFS) +#define SERIAL_MODEM_CONTROL (4 * SERIAL_REG_OFS) +#define SERIAL_RS232_OUTPUT (4 * SERIAL_REG_OFS) +#define SERIAL_LINE_STATUS (5 * SERIAL_REG_OFS) +#define SERIAL_MODEM_STATUS (6 * SERIAL_REG_OFS) +#define SERIAL_RS232_INPUT (6 * SERIAL_REG_OFS) +#define SERIAL_SCRATCH_PAD (7 * SERIAL_REG_OFS) + +#define SERIAL_DIVISOR_LSB (0 * SERIAL_REG_OFS) +#define SERIAL_DIVISOR_MSB (1 * SERIAL_REG_OFS) + +/* + * Functions to READ and WRITE to serial port 0 + */ +#define SERIAL_READ(ofs) (*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE + ofs))) + +#define SERIAL_WRITE(ofs, val) ((*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE + ofs))) = val) + +/* + * Functions to READ and WRITE to serial port 1 + */ +#define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE_1 + ofs) + +#define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \ + (TITAN_SERIAL_BASE_1 + ofs))) = val) + +/* + * Second serial port initialization + */ +void init_second_port(void) +{ + /* Disable Interrupts */ + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0); + SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0); + + { + unsigned int divisor; + + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80); + divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200; + SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff); + + SERIAL_WRITE_1(SERIAL_DIVISOR_MSB, + (divisor & 0xff00) >> 8); + SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0); + } + + SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT | + YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT); + + /* Enable Interrupts */ + SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf); +} + +/* Initialize the serial port for KGDB debugging */ +void debugInit(unsigned int baud, unsigned char data, unsigned char parity, + unsigned char stop) +{ + /* Disable Interrupts */ + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0); + SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0); + + { + unsigned int divisor; + + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80); + + divisor = TITAN_SERIAL_BASE_BAUD / baud; + SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff); + + SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8); + SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0); + } + + SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +unsigned char getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(YOSEMITE_BAUD_115200, + YOSEMITE_DATA_8BIT, + YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT); + } + + while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0); + return SERIAL_READ(SERIAL_RCV_BUFFER); +} + +int putDebugChar(unsigned char byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(YOSEMITE_BAUD_115200, + YOSEMITE_DATA_8BIT, + YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT); + } + + while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0); + SERIAL_WRITE(SERIAL_SEND_BUFFER, byte); + + return 1; +} +#endif diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c new file mode 100644 index 000000000000..416da22b3bf4 --- /dev/null +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Detailed Description: + * + * This block implements the I2C interface to the slave devices like the + * Atmel 24C32 EEPROM and the MAX 1619 Sensors device. The I2C Master interface + * can be controlled by the SCMB block. And the SCMB block kicks in only when + * using the Ethernet Mode of operation and __not__ the SysAD mode + * + * The SCMB controls the two modes: MDIO and the I2C. The MDIO mode is used to + * communicate with the Quad-PHY from Marvel. The I2C is used to communicate + * with the I2C slave devices. It seems that the driver does not explicitly + * deal with the control of SDA and SCL serial lines. So, the driver will set + * the slave address, drive the command and then the data. The SCMB will then + * control the two serial lines as required. + * + * It seems the documents are very unclear abt this. Hence, I took some time + * out to write the desciption to have an idea of how the I2C can actually + * work. Currently, this Linux driver wont be integrated into the generic Linux + * I2C framework. And finally, the I2C interface is also known as the 2BI + * interface. 2BI means 2-bit interface referring to SDA and SCL serial lines + * respectively. + * + * - Manish Lachwani (12/09/2003) + */ + +#include "i2c-yosemite.h" + +/* + * Poll the I2C interface for the BUSY bit. + */ +static int titan_i2c_poll(void) +{ + int i = 0; + unsigned long val = 0; + + for (i = 0; i < TITAN_I2C_MAX_POLL; i++) { + val = TITAN_I2C_READ(TITAN_I2C_COMMAND); + + if (!(val & 0x8000)) + return 0; + } + + return TITAN_I2C_ERR_TIMEOUT; +} + +/* + * Execute the I2C command + */ +int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, + int size, unsigned int *addr) +{ + int loop = 0, bytes, i; + unsigned int *write_data, data, *read_data; + unsigned long reg_val, val; + + write_data = cmd->data; + read_data = addr; + + TITAN_I2C_WRITE(TITAN_I2C_SLAVE_ADDRESS, slave_addr); + + if (cmd->type == TITAN_I2C_CMD_WRITE) + loop = cmd->write_size; + else + loop = size; + + while (loop > 0) { + if ((cmd->type == TITAN_I2C_CMD_WRITE) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE)) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; + ++i, write_data += 2, reg_val += 4) { + if (bytes < cmd->write_size) { + data = write_data[0]; + ++data; + } + + if (bytes < cmd->write_size) { + data = write_data[1]; + ++data; + } + + TITAN_I2C_WRITE(reg_val, data); + } + } + + TITAN_I2C_WRITE(TITAN_I2C_COMMAND, + (unsigned int) (cmd->type << 13)); + if (titan_i2c_poll() != TITAN_I2C_ERR_OK) + return TITAN_I2C_ERR_TIMEOUT; + + if ((cmd->type == TITAN_I2C_CMD_READ) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE)) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; + ++i, read_data += 2, reg_val += 4) { + data = TITAN_I2C_READ(reg_val); + + if (bytes < size) { + read_data[0] = data & 0xff; + ++bytes; + } + + if (bytes < size) { + read_data[1] = + ((data >> 8) & 0xff); + ++bytes; + } + } + } + + loop -= (TITAN_I2C_MAX_WORDS_PER_RW * 2); + } + + /* + * Read the Interrupt status and then return the appropriate error code + */ + + val = TITAN_I2C_READ(TITAN_I2C_INTERRUPTS); + if (val & 0x0020) + return TITAN_I2C_ERR_ARB_LOST; + + if (val & 0x0040) + return TITAN_I2C_ERR_NO_RESP; + + if (val & 0x0080) + return TITAN_I2C_ERR_DATA_COLLISION; + + return TITAN_I2C_ERR_OK; +} + +/* + * Init the I2C subsystem of the PMC-Sierra Yosemite board + */ +int titan_i2c_init(titan_i2c_config * config) +{ + unsigned int val; + + /* + * Reset the SCMB and program into the I2C mode + */ + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0xA000); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0x2000); + + /* + * Configure the filtera and clka values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_A); + val |= ((val & ~(0xF000)) | ((config->filtera << 12) & 0xF000)); + val |= ((val & ~(0x03FF)) | (config->clka & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_A, val); + + /* + * Configure the filterb and clkb values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_B); + val |= ((val & ~(0xF000)) | ((config->filterb << 12) & 0xF000)); + val |= ((val & ~(0x03FF)) | (config->clkb & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_B, val); + + return TITAN_I2C_ERR_OK; +} diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h index 8b6e49c638d7..31c5523276fa 100644 --- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h @@ -31,7 +31,7 @@ /* Read and Write operations to the chip */ #define TITAN_I2C_BASE 0xbb000000 /* XXX Needs to change */ - + #define TITAN_I2C_WRITE(offset, data) \ *(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data @@ -48,14 +48,14 @@ #define TITAN_I2C_MAX_POLL 100 /* Registers used for I2C work */ -#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ -#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ -#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ -#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ -#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ +#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ +#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ +#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ +#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ +#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ #define TITAN_I2C_SLAVE_ADDRESS 0x01A8 /* I2C Slave Address */ -#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ -#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ +#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ +#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ /* Error */ #define TITAN_I2C_ERR_ARB_LOST (-9220) @@ -66,31 +66,31 @@ /* I2C Command Type */ typedef enum { - TITAN_I2C_CMD_WRITE = 0, - TITAN_I2C_CMD_READ = 1, - TITAN_I2C_CMD_READ_WRITE = 2 + TITAN_I2C_CMD_WRITE = 0, + TITAN_I2C_CMD_READ = 1, + TITAN_I2C_CMD_READ_WRITE = 2 } titan_i2c_cmd_type; /* I2C structures */ typedef struct { - int filtera; /* Register 0x0184, bits 15 - 12*/ - int clka; /* Register 0x0184, bits 9 - 0 */ - int filterb; /* Register 0x0188, bits 15 - 12 */ - int clkb; /* Register 0x0188, bits 9 - 0 */ + int filtera; /* Register 0x0184, bits 15 - 12 */ + int clka; /* Register 0x0184, bits 9 - 0 */ + int filterb; /* Register 0x0188, bits 15 - 12 */ + int clkb; /* Register 0x0188, bits 9 - 0 */ } titan_i2c_config; /* I2C command type */ typedef struct { - titan_i2c_cmd_type type; /* Type of command */ - int num_arb; /* Register 0x01a0, bits 15 - 12 */ - int num_nak; /* Register 0x01a0, bits 11 - 8 */ - int addr_size; /* Register 0x01a0, bit 7 */ - int mst_code; /* Register 0x01a0, bits 6 - 4 */ - int arb_en; /* Register 0x01a0, bit 1 */ - int speed; /* Register 0x01a0, bit 0 */ - int slave_addr; /* Register 0x01a8 */ - int write_size; /* Register 0x01a4, bits 10 - 8 */ - unsigned int *data; /* Register 0x01ac */ + titan_i2c_cmd_type type; /* Type of command */ + int num_arb; /* Register 0x01a0, bits 15 - 12 */ + int num_nak; /* Register 0x01a0, bits 11 - 8 */ + int addr_size; /* Register 0x01a0, bit 7 */ + int mst_code; /* Register 0x01a0, bits 6 - 4 */ + int arb_en; /* Register 0x01a0, bit 1 */ + int speed; /* Register 0x01a0, bit 0 */ + int slave_addr; /* Register 0x01a8 */ + int write_size; /* Register 0x01a4, bits 10 - 8 */ + unsigned int *data; /* Register 0x01ac */ } titan_i2c_command; -#endif /* __I2C_YOSEMITE_H */ +#endif /* __I2C_YOSEMITE_H */ diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S index a7caeec63be2..ebe2e64e275b 100644 --- a/arch/mips/pmc-sierra/yosemite/irq-handler.S +++ b/arch/mips/pmc-sierra/yosemite/irq-handler.S @@ -8,6 +8,10 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. + * + * Titan supports Hypertransport or PCI but not both. Hence, one interrupt + * line is shared between the PCI slot A and Hypertransport. This is the + * Processor INTB #0. */ #include @@ -17,109 +21,90 @@ #include #include -/* - * IRQ router for the Titan board - */ - .align 5 NESTED(titan_handle_int, PT_SIZE, sp) SAVE_ALL CLI .set at + .set noreorder mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 - - andi t1, t0, STATUSF_IP0 /* INTB0 hardware line */ + + andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ bnez t1, ll_pcia_irq /* 64-bit PCI */ - andi t1, t0, STATUSF_IP1 /* INTB1 hardware line */ + andi t1, t0, STATUSF_IP3 /* INTB1 hardware line */ bnez t1, ll_pcib_irq /* second 64-bit PCI slot */ - andi t1, t0, STATUSF_IP2 /* INTB2 hardware line */ + andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ bnez t1, ll_duart_irq /* UART */ - andi t1, t0, STATUSF_IP3 /* INTB3 hardware line*/ - bnez t1, ll_ht_smp_irq /* Hypertransport */ - andi t1, t0, STATUSF_IP5 /* INTB5 hardware line */ + andi t1, t0, STATUSF_IP5 /* SMP inter-core interrupts */ + bnez t1, ll_smp_irq + andi t1, t0, STATUSF_IP6 + bnez t1, ll_ht_irq /* Hypertransport */ + andi t1, t0, STATUSF_IP7 /* INTB5 hardware line */ bnez t1, ll_timer_irq /* Timer */ nop nop /* Extended interrupts */ - mfc0 t0, CPU_CAUSE - cfc0 t1, CP0_S1_INTCONTROL + mfc0 t0, CP0_CAUSE + cfc0 t1, CP0_S1_INTCONTROL - sll t2, t1, 8 - - and t0, t2 - srl t0, t0, 16 + sll t2, t1, 8 - - andi t1, t0, STATUSF_IP6 /* INTB6 hardware line */ - bnez t1, ll_phy0_irq /* Ethernet port 0 */ - andi t1, t0, STATUSF_IP7 /* INTB7 hardware line */ - bnez t1, ll_phy1_irq /* Ethernet port 1 */ - andi t1, t0, STATUSF_IP8 /* INTB8 hardware line */ - bnez t1, ll_phy2_irq /* Ethernet Port 2 */ - - nop - nop + and t0, t2 + srl t0, t0, 16 .set reorder - /* No handler */ j spurious_interrupt nop END(titan_handle_int) .align 5 -/* Individual Handlers */ - ll_pcia_irq: - li a0, 1 - move a2, sp + li a0, 2 + move a1, sp +#ifdef CONFIG_HYPERTRANSPORT + jal ll_ht_smp_irq_handler +#else jal do_IRQ +#endif j ret_from_irq ll_pcib_irq: - li a0, 2 - move a1, sp - jal do_IRQ - j ret_from_irq - -ll_duart_irq: li a0, 3 move a1, sp jal do_IRQ j ret_from_irq -ll_ht_irq: +ll_duart_irq: li a0, 4 move a1, sp - jal ll_ht_smp_irq_handler /* Detailed HT & SMP IRQ handling */ + jal do_IRQ j ret_from_irq -ll_timer_irq: +ll_smp_irq: li a0, 5 move a1, sp +#ifdef CONFIG_SMP + jal jaguar_mailbox_irq +#else jal do_IRQ +#endif j ret_from_irq -ll_phy0_irq: +ll_ht_irq: li a0, 6 move a1, sp - jal do_IRQ - j ret_from_irq - -ll_phy1_irq: - li a0, 7 - move a1, sp - jal do_IRQ + jal ll_ht_smp_irq_handler j ret_from_irq -ll_phy2_irq: - li a0, 8 +ll_timer_irq: + li a0, 7 move a1, sp jal do_IRQ j ret_from_irq diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c index 294290f8ae4c..e8b7ed63eaa0 100644 --- a/arch/mips/pmc-sierra/yosemite/irq.c +++ b/arch/mips/pmc-sierra/yosemite/irq.c @@ -41,207 +41,116 @@ #include #include #include +#include #include #include +#include /* Hypertransport specific */ -#define IRQ_STATUS_REG_CPU0 0xbb001b30 /* INT# 3 status register on CPU 0*/ -#define IRQ_STATUS_REG_CPU1 0xbb002b30 /* INT# 3 status register on CPU 1*/ -#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ -#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 0*/ -#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 1*/ +#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ -#define HYPERTRANSPORT_EOI 0xbb0006E0 /* End of Interrupt */ -#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ -#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ -#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ -#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ - -#define read_32bit_cp0_set1_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "cfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -#define write_32bit_cp0_set1_register(register,value) \ - __asm__ __volatile__( \ - "ctc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); - -static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; - -/* Function for careful CP0 interrupt mask access */ -static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) -{ - unsigned long status; - unsigned clr_mask; - unsigned set_mask; - - /* do the low 8 bits first */ - clr_mask = 0xff & clr_mask_in; - set_mask = 0xff & set_mask_in; - status = read_c0_status(); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8 | 0x0000FF00; - write_c0_status(status); - - /* do the high 8 bits */ - clr_mask = 0xff & (clr_mask_in >> 8); - set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); -} - -static inline void mask_irq(unsigned int irq) -{ - modify_cp0_intmask(irq, 0); -} - -static inline void unmask_irq(unsigned int irq) -{ - modify_cp0_intmask(0, irq); -} - -static void enable_rm9000_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - unmask_irq(1 << (irq-1)); - spin_unlock_irqrestore(&irq_lock, flags); -} - -static unsigned int startup_rm9000_irq(unsigned int irq) -{ - enable_rm9000_irq(irq); - - return 0; /* never anything pending */ -} - -static void disable_rm9000_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - mask_irq(1 << (irq-1)); - spin_unlock_irqrestore(&irq_lock, flags); -} - -#define shutdown_rm9000_irq disable_rm9000_irq - -static void mask_and_ack_rm9000_irq(unsigned int irq) -{ - mask_irq(1 << (irq-1)); -} - -static void end_rm9000_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_irq(1 << (irq-1)); -} - -static struct hw_interrupt_type rm9000_hpcdma_irq_type = { - "RM9000", - startup_rm9000_irq, - shutdown_rm9000_irq, - enable_rm9000_irq, - disable_rm9000_irq, - mask_and_ack_rm9000_irq, - end_rm9000_irq, - NULL -}; +#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ +#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ +#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ +#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ extern asmlinkage void titan_handle_int(void); extern void jaguar_mailbox_irq(struct pt_regs *); /* - * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. For interprocessor - * interrupts, the best thing to do is to use the INTMSG register. We use the same external - * interrupt line, i.e. INTB3 and monitor another status bit + * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. + * For interprocessor interrupts, the best thing to do is to use the INTMSG + * register. We use the same external interrupt line, i.e. INTB3 and monitor + * another status bit */ asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs) { - u32 status; - status = *(volatile uint32_t *)(IRQ_STATUS_REG_CPU0); + u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); /* Ack all the bits that correspond to the interrupt sources */ if (status != 0) - *(volatile uint32_t *)(IRQ_STATUS_REG_CPU0) = IRQ_ACK_BITS; + OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS); - status = *(volatile uint32_t *)(IRQ_STATUS_REG_CPU1); + status = OCD_READ(RM9000x2_OCD_INTP1STATUS4); if (status != 0) - *(volatile uint32_t *)(IRQ_STATUS_REG_CPU1) = IRQ_ACK_BITS; + OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS); -#ifdef CONFIG_SMP - if (status == 0x2) { - /* This is an SMP IPI sent from one core to another */ - jaguar_mailbox_irq(regs); - goto done; - } -#endif - #ifdef CONFIG_HT_LEVEL_TRIGGER - /* - * Level Trigger Mode only. Send the HT EOI message back to the source. - */ - switch (status) { - case 0x1000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; - break; - case 0x2000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; - break; - case 0x4000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; - break; - case 0x8000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; - break; - case 0x0000001: - /* PLX */ - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = 0x20; - *(volatile uint32_t *)(IRQ_CLEAR_REG) = IRQ_ACK_BITS; - break; - case 0xf000000: - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; - *(volatile uint32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; - break; - } + /* + * Level Trigger Mode only. Send the HT EOI message back to the source. + */ + switch (status) { + case 0x1000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); + break; + case 0x2000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); + break; + case 0x4000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); + break; + case 0x8000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); + break; + case 0x0000001: + /* PLX */ + OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20); + OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS); + break; + case 0xf000000: + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); + OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); + break; + } #endif /* CONFIG_HT_LEVEL_TRIGGER */ -done: - if (status != 0x2) - /* Not for SMP */ - do_IRQ(irq, regs); + do_IRQ(irq, regs); } +#ifdef CONFIG_KGDB +extern void init_second_port(void); +extern void breakpoint(void); +extern void set_debug_traps(void); +#endif + /* * Initialize the next level interrupt handler */ void __init init_IRQ(void) { - int i; - - clear_c0_status(ST0_IM | ST0_BEV); - __cli(); + clear_c0_status(ST0_IM); set_except_vector(0, titan_handle_int); init_generic_irq(); + mips_cpu_irq_init(0); + rm7k_cpu_irq_init(8); + +#ifdef CONFIG_KGDB + /* At this point, initialize the second serial port */ + init_second_port(); + printk("Start kgdb ... \n"); + set_debug_traps(); + breakpoint(); +#endif - for (i = 0; i < 13; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].handler = &rm9000_hpcdma_irq_type; - } +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif } +#ifdef CONFIG_KGDB +/* + * The 16550 DUART has two ports, but is allocated one IRQ + * for the serial console. Hence, a generic framework for + * serial IRQ routing in place. Currently, just calls the + * do_IRQ fuction. But, going in the future, need to check + * DUART registers for channel A and B, then decide the + * appropriate action + */ +asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs) +{ + do_IRQ(irq, regs); +} +#endif diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c index 70f68b7c0552..5b4ef33acf22 100644 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ b/arch/mips/pmc-sierra/yosemite/prom.c @@ -7,55 +7,44 @@ * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) */ - +#include #include #include +#include +#include + #include #include #include #include #include -#include -#include #include +#include #include "setup.h" -/* Call Vectors */ -struct callvectors { - int (*open) (char*, int, int); - int (*close) (int); - int (*read) (int, void*, int); - int (*write) (int, void*, int); - off_t (*lseek) (int, off_t, int); - int (*printf) (const char*, ...); - void (*cacheflush) (void); - char* (*gets) (char*); -}; - -struct callvectors* debug_vectors; +struct callvectors *debug_vectors; extern unsigned long yosemite_base; extern unsigned long cpu_clock; -unsigned char titan_ge_mac_addr_base[6]; const char *get_system_type(void) { - return "PMC-Sierra Yosemite"; + return "PMC-Sierra Yosemite"; } -static void prom_cpu0_exit(void) +static void prom_cpu0_exit(void *arg) { - void *nvram = YOSEMITE_NVRAM_BASE_ADDR; - + void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR; + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ - writeb(0x84, nvram + 0xff7); + writeb(0x84, nvram + 0xff7); - /* wait for the watchdog to go off */ - mdelay(100+(1000/16)); + /* wait for the watchdog to go off */ + mdelay(100 + (1000 / 16)); - /* if the watchdog fails for some reason, let people know */ - printk(KERN_NOTICE "Watchdog reset failed\n"); + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); } /* @@ -68,78 +57,73 @@ static void prom_exit(void) /* CPU 1 */ smp_call_function(prom_cpu0_exit, NULL, 1, 1); #endif - prom_cpu0_exit; -} - -/* - * Get the MAC address from the EEPROM using the I2C protocol - */ -void get_mac_address(char dest[6]) -{ - /* Use the I2C command code in the i2c-yosemite */ + prom_cpu0_exit(NULL); } /* - * Halt the system + * Halt the system */ static void prom_halt(void) { printk(KERN_NOTICE "\n** You can safely turn off the power\n"); while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); + __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); } /* * Init routine which accepts the variables from PMON */ -__init prom_init(int argc, char **arg, char **env, struct callvectors *cv) +void __init prom_init(void) { - int i = 0; + int argc = fw_arg0; + char **arg = (char **) fw_arg1; + char **env = (char **) fw_arg2; + struct callvectors *cv = (struct callvectors *) fw_arg3; + int i = 0; /* Callbacks for halt, restart */ - _machine_restart = (void (*)(char *))prom_exit; + _machine_restart = (void (*)(char *)) prom_exit; _machine_halt = prom_halt; _machine_power_off = prom_halt; -#ifdef CONFIG_MIPS64 - - /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ - -#else /* CONFIG_MIPS64 */ +#ifdef CONFIG_MIPS32 debug_vectors = cv; arcs_cmdline[0] = '\0'; /* Get the boot parameters */ for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline)) - break; + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= + sizeof(arcs_cmdline)) + break; strcat(arcs_cmdline, arg[i]); strcat(arcs_cmdline, " "); } while (*env) { - if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) - yosemite_base = simple_strtol(*env + strlen("ocd_base="), - NULL, 16); - - if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) - cpu_clock = simple_strtol(*env + strlen("cpuclock="), - NULL, 10); - + if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) + yosemite_base = + simple_strtol(*env + strlen("ocd_base="), NULL, + 16); + + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) + cpu_clock = + simple_strtol(*env + strlen("cpuclock="), NULL, + 10); + env++; } +#endif /* CONFIG_MIPS32 */ + +#ifdef CONFIG_MIPS64 + + /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ + #endif /* CONFIG_MIPS64 */ mips_machgroup = MACH_GROUP_TITAN; mips_machtype = MACH_TITAN_YOSEMITE; - - get_mac_address(titan_ge_mac_addr_base); - - debug_vectors->printf("Booting Linux kernel...\n"); } void __init prom_free_prom_memory(void) @@ -149,41 +133,3 @@ void __init prom_free_prom_memory(void) void __init prom_fixup_mem_map(unsigned long start, unsigned long end) { } - -extern void asmlinkage smp_bootstrap(void); - -/* - * SMP support - */ -int prom_setup_smp(void) -{ - int num_cpus = 2; - - /* - * We know that the RM9000 on the Jaguar ATX board has 2 cores. Hence, this - * can be hardcoded for now. - */ - return num_cpus; -} - -int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) -{ - /* Clear the semaphore */ - *(volatile uint32_t *)(0xbb000a68) = 0x80000000; - - return 1; -} - -void prom_init_secondary(void) -{ - clear_c0_config(CONF_CM_CMASK); - set_c0_config(0x2); - - clear_c0_status(ST0_IM); - set_c0_status(0x1ffff); -} - -void prom_smp_finish(void) -{ -} - diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c new file mode 100644 index 000000000000..22c336f9a596 --- /dev/null +++ b/arch/mips/pmc-sierra/yosemite/py-console.c @@ -0,0 +1,130 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001, 2002, 2004 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* SUPERIO uart register map */ +struct yo_uartregs { + union { + volatile u8 rbr; /* read only, DLAB == 0 */ + volatile u8 thr; /* write only, DLAB == 0 */ + volatile u8 dll; /* DLAB == 1 */ + } u1; + union { + volatile u8 ier; /* DLAB == 0 */ + volatile u8 dlm; /* DLAB == 1 */ + } u2; + union { + volatile u8 iir; /* read only */ + volatile u8 fcr; /* write only */ + } u3; + volatile u8 iu_lcr; + volatile u8 iu_mcr; + volatile u8 iu_lsr; + volatile u8 iu_msr; + volatile u8 iu_scr; +} yo_uregs_t; + +#define iu_rbr u1.rbr +#define iu_thr u1.thr +#define iu_dll u1.dll +#define iu_ier u2.ier +#define iu_dlm u2.dlm +#define iu_iir u3.iir +#define iu_fcr u3.fcr + +extern unsigned long uart_base; + +#define IO_BASE_64 0x9000000000000000ULL + +static unsigned char readb_outer_space(unsigned long phys) +{ + unsigned long long vaddr = IO_BASE_64 | phys; + unsigned char res; + unsigned int sr; + + sr = read_c0_status(); + write_c0_status((sr | ST0_KX) & ~ ST0_IE); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + __asm__ __volatile__ ( + " .set mips3 \n" + " ld %0, (%0) \n" + " lbu %0, (%0) \n" + " .set mips0 \n" + : "=r" (res) + : "0" (&vaddr)); + + write_c0_status(sr); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + return res; +} + +static void writeb_outer_space(unsigned long phys, unsigned char c) +{ + unsigned long long vaddr = IO_BASE_64 | phys; + unsigned long tmp; + unsigned int sr; + + sr = read_c0_status(); + write_c0_status((sr | ST0_KX) & ~ ST0_IE); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + + __asm__ __volatile__ ( + " .set mips3 \n" + " ld %0, (%1) \n" + " sb %2, (%0) \n" + " .set mips0 \n" + : "=r" (tmp) + : "r" (&vaddr), "r" (c)); + + write_c0_status(sr); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); + __asm__("sll $0, $0, 2\n"); +} + +static inline struct yo_uartregs *console_uart(void) +{ + return (struct yo_uartregs *) (uart_base + 8); +} + +void prom_putchar(char c) +{ + unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr); + unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr); + + while ((readb_outer_space(lsr) & 0x20) == 0); + writeb_outer_space(thr, c); +} + +char __init prom_getchar(void) +{ + return 0; +} diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index 43795a8415df..dfa9cd0ed557 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c @@ -1,6 +1,4 @@ /* - * arch/mips/pmc-sierra/yosemite/setup.c - * * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) * @@ -24,19 +22,18 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include #include #include -#include #include +#include #include #include #include #include -#include #include -#include + #include #include #include @@ -46,36 +43,46 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include "setup.h" +unsigned char titan_ge_mac_addr_base[6] = { + 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 +}; + unsigned long cpu_clock; unsigned long yosemite_base; -void __init bus_error_init(void) -{ - /* Do nothing */ +void __init bus_error_init(void) +{ + /* Do nothing */ } unsigned long m48t37y_get_time(void) { - unsigned char *rtc_base = YOSEMITE_RTC_BASE; - unsigned int year, month, day, hour, min, sec; + //unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; + unsigned char *rtc_base = (unsigned char *) 0xfc000000UL; + unsigned int year, month, day, hour, min, sec; +return; /* Stop the update to the time */ rtc_base[0x7ff8] = 0x40; - year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); - year += CONV_BCD_TO_BIN(rtc_base[0x7fff1]) * 100; + year = BCD2BIN(rtc_base[0x7fff]); + year += BCD2BIN(rtc_base[0x7fff1]) * 100; - month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); - day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); - hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); - min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); - sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + month = BCD2BIN(rtc_base[0x7ffe]); + day = BCD2BIN(rtc_base[0x7ffd]); + hour = BCD2BIN(rtc_base[0x7ffb]); + min = BCD2BIN(rtc_base[0x7ffa]); + sec = BCD2BIN(rtc_base[0x7ff9]); /* Start the update to the time again */ rtc_base[0x7ff8] = 0x00; @@ -85,83 +92,119 @@ unsigned long m48t37y_get_time(void) int m48t37y_set_time(unsigned long sec) { - unsigned char *rtc_base = YOSEMITE_RTC_BASE; - unsigned int year, month, day, hour, min, sec; - - struct rtc_time tm; + unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; + struct rtc_time tm; +return; - /* convert to a more useful format -- note months count from 0 */ - to_tm(sec, &tm); - tm.tm_mon += 1; + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; - /* enable writing */ - rtc_base[0x7ff8] = 0x80; + /* enable writing */ + rtc_base[0x7ff8] = 0x80; - /* year */ - rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); - rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + /* year */ + rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); - /* month */ - rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + /* month */ + rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); - /* day */ - rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + /* day */ + rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); - /* hour/min/sec */ - rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); - rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); - rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + /* hour/min/sec */ + rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); + rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); + rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); - /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); - /* disable writing */ - rtc_base[0x7ff8] = 0x00; + /* disable writing */ + rtc_base[0x7ff8] = 0x00; - return 0; + return 0; } void yosemite_timer_setup(struct irqaction *irq) { - setup_irq(6, irq); + setup_irq(7, irq); } void yosemite_time_init(void) { - mips_counter_frequency = cpu_clock / 2; board_timer_setup = yosemite_timer_setup; + mips_hpt_frequency = cpu_clock / 2; rtc_get_time = m48t37y_get_time; rtc_set_time = m48t37y_set_time; } +unsigned long uart_base = 0xfd000000L; + +/* No other usable initialization hook than this ... */ +extern void (*late_time_init)(void); + +unsigned long ocd_base; + +EXPORT_SYMBOL(ocd_base); + +/* + * Common setup before any secondaries are started + */ + +#define TITAN_UART_CLK 3686400 +#define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16) +#define TITAN_SERIAL_IRQ 4 +#define TITAN_SERIAL_BASE 0xfd000008UL + +static void __init py_map_ocd(void) +{ + struct uart_port up; + + /* + * Not specifically interrupt stuff but in case of SMP core_send_ipi + * needs this first so I'm mapping it here ... + */ + ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); + if (!ocd_base) + panic("Mapping OCD failed - game over. Your score is 0."); + + /* + * Register to interrupt zero because we share the interrupt with + * the serial driver which we don't properly support yet. + */ + memset(&up, 0, sizeof(up)); + up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8); + up.irq = TITAN_SERIAL_IRQ; + up.uartclk = TITAN_UART_CLK; + up.regshift = 0; + up.iotype = UPIO_MEM; + up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + up.line = 0; + + if (early_serial_setup(&up)) + printk(KERN_ERR "Early serial init of port 0 failed\n"); +} + static int __init pmc_yosemite_setup(void) { - unsigned long val = 0; + extern void pmon_smp_bootstrap(void); - printk("PMC-Sierra Yosemite Board Setup \n"); board_time_init = yosemite_time_init; + late_time_init = py_map_ocd; /* Add memory regions */ add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); - add_memory_region(0x10000000, 0x10000000, BOOT_MEM_RAM); - - /* Setup the HT controller */ - val = *(volatile uint32_t *)(HYPERTRANSPORT_CONFIG_REG); - val |= HYPERTRANSPORT_ENABLE; - *(volatile uint32_t *)(HYPERTRANSPORT_CONFIG_REG) = val; - - /* Set the BAR. Shifted mode */ - *(volatile uint32_t *)(HYPERTRANSPORT_BAR0_REG) = HYPERTRANSPORT_BAR0_ADDR; - *(volatile uint32_t *)(HYPERTRANSPORT_SIZE0_REG) = HYPERTRANSPORT_SIZE0; -#ifdef CONFIG_PCI - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; +#if 0 /* XXX Crash ... */ + OCD_WRITE(RM9000x2_OCD_HTSC, + OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE); - pci_scan_bus(0, &titan_pci_ops, NULL); + /* Set the BAR. Shifted mode */ + OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR); + OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0); #endif return 0; diff --git a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h index d8193e11b69f..b3e24b4e6c12 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.h +++ b/arch/mips/pmc-sierra/yosemite/setup.h @@ -9,27 +9,13 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ - #ifndef __SETUP_H__ #define __SETUP_H__ -/* Real Time Clock base */ -#define YOSEMITE_RTC_BASE -#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) -#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) - /* NVRAM Base */ #define YOSEMITE_NVRAM_BASE_ADDR 0xbb000678 /* XXX Need change */ #define YOSEMITE_RTC_BASE 0xbb000679 /* XXX Need change */ -/* - * Hypertransport Specific - */ -#define HYPERTRANSPORT_CONFIG_REG 0xbb000604 -#define HYPERTRANSPORT_BAR0_REG 0xbb000610 -#define HYPERTRANSPORT_SIZE0_REG 0xbb000688 -#define HYPERTRANSPORT_BAR0_ATTR_REG 0xbb000680 - #define HYPERTRANSPORT_BAR0_ADDR 0x00000006 #define HYPERTRANSPORT_SIZE0 0x0fffffff #define HYPERTRANSPORT_BAR0_ATTR 0x00002000 @@ -37,11 +23,9 @@ #define HYPERTRANSPORT_ENABLE 0x6 /* - * EEPROM Size + * EEPROM Size */ #define TITAN_ATMEL_24C32_SIZE 32768 #define TITAN_ATMEL_24C64_SIZE 65536 - #endif /* __SETUP_H__ */ - diff --git a/arch/mips/ramdisk/Makefile b/arch/mips/ramdisk/Makefile index 5c75968273f2..66cce75c5845 100644 --- a/arch/mips/ramdisk/Makefile +++ b/arch/mips/ramdisk/Makefile @@ -12,7 +12,7 @@ img := $(subst $(src)//,/,$(src)/$(img)) quiet_cmd_ramdisk = LD $@ define cmd_ramdisk - $(LD) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) + $(LD) $(LDFLAGS) -T $(src)/ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) endef $(obj)/ramdisk.o: $(img) $(src)/ld.script diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index 352a8495cc23..fe7f546d3283 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,8 @@ void ip22_do_break(void) ArcEnterInteractiveMode(); } +EXPORT_SYMBOL(ip22_do_break); + extern void ip22_be_init(void) __init; extern void ip22_time_init(void) __init; diff --git a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c index 2601296e2773..3613999a189a 100644 --- a/arch/mips/vr41xx/common/bcu.c +++ b/arch/mips/vr41xx/common/bcu.c @@ -1,34 +1,23 @@ /* - * FILE NAME - * arch/mips/vr41xx/common/bcu.c + * bcu.c, Bus Control Unit routines for the NEC VR4100 series. * - * BRIEF MODULE DESCRIPTION - * Bus Control Unit routines for the NEC VR4100 series. + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Copyright 2002 MontaVista Software Inc. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Changes: @@ -40,12 +29,16 @@ * - Added support for NEC VR4133. */ #include +#include #include #include #include #include +#define IO_MEM_RESOURCE_START 0UL +#define IO_MEM_RESOURCE_END 0x1fffffffUL + #define CLKSPEEDREG_TYPE1 KSEG1ADDR(0x0b000014) #define CLKSPEEDREG_TYPE2 KSEG1ADDR(0x0f000014) #define CLKSP(x) ((x) & 0x001f) @@ -213,7 +206,7 @@ static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pc return tclock; } -void __init vr41xx_bcu_init(void) +static int __init vr41xx_bcu_init(void) { unsigned long pclock; uint16_t clkspeed; @@ -223,4 +216,11 @@ void __init vr41xx_bcu_init(void) pclock = calculate_pclock(clkspeed); vr41xx_vtclock = calculate_vtclock(clkspeed, pclock); vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock); + + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + + return 0; } + +early_initcall(vr41xx_bcu_init); diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c index f3665b404aed..fd33d005f463 100644 --- a/arch/mips/vr41xx/common/cmu.c +++ b/arch/mips/vr41xx/common/cmu.c @@ -200,7 +200,7 @@ void vr41xx_mask_clock(vr41xx_clock_t clock) spin_unlock_irq(&cmu_lock); } -void __init vr41xx_cmu_init(void) +static int __init vr41xx_cmu_init(void) { switch (current_cpu_data.cputype) { case CPU_VR4111: @@ -223,4 +223,8 @@ void __init vr41xx_cmu_init(void) cmuclkmsk = read_cmuclkmsk(); spin_lock_init(&cmu_lock); + + return 0; } + +early_initcall(vr41xx_cmu_init); diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c index 6ee189968e8b..bd2978fd510b 100644 --- a/arch/mips/vr41xx/common/giu.c +++ b/arch/mips/vr41xx/common/giu.c @@ -28,10 +28,12 @@ * - Added support for NEC VR4133. * - Removed board_irq_init. */ +#include #include #include #include #include +#include #include #include @@ -64,6 +66,8 @@ static uint32_t giu_base; #define read_giuint(offset) readw(giu_base + (offset)) #define write_giuint(val, offset) writew((val), giu_base + (offset)) +#define GIUINT_HIGH_OFFSET 16 + static inline uint16_t set_giuint(uint8_t offset, uint16_t set) { uint16_t res; @@ -86,35 +90,121 @@ static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear) return res; } -void vr41xx_enable_giuint(int pin) +static unsigned int startup_giuint_low_irq(unsigned int irq) { - if (pin < 16) - set_giuint(GIUINTENL, (uint16_t)1 << pin); - else - set_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); + set_giuint(GIUINTENL, (uint16_t)1 << pin); + + return 0; } -void vr41xx_disable_giuint(int pin) +static void shutdown_giuint_low_irq(unsigned int irq) { - if (pin < 16) - clear_giuint(GIUINTENL, (uint16_t)1 << pin); - else - clear_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); + clear_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); } -void vr41xx_clear_giuint(int pin) +static void enable_giuint_low_irq(unsigned int irq) { - if (pin < 16) - write_giuint((uint16_t)1 << pin, GIUINTSTATL); - else - write_giuint((uint16_t)1 << (pin - 16), GIUINTSTATH); + set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); +} + +#define disable_giuint_low_irq shutdown_giuint_low_irq + +static void ack_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq); + clear_giuint(GIUINTENL, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); +} + +static void end_giuint_low_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq)); +} + +static struct hw_interrupt_type giuint_low_irq_type = { + .typename = "GIUINTL", + .startup = startup_giuint_low_irq, + .shutdown = shutdown_giuint_low_irq, + .enable = enable_giuint_low_irq, + .disable = disable_giuint_low_irq, + .ack = ack_giuint_low_irq, + .end = end_giuint_low_irq, +}; + +static unsigned int startup_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); + set_giuint(GIUINTENH, (uint16_t)1 << pin); + + return 0; +} + +static void shutdown_giuint_high_irq(unsigned int irq) +{ + clear_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +static void enable_giuint_high_irq(unsigned int irq) +{ + set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +#define disable_giuint_high_irq shutdown_giuint_high_irq + +static void ack_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET); + clear_giuint(GIUINTENH, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); +} + +static void end_giuint_high_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET)); +} + +static struct hw_interrupt_type giuint_high_irq_type = { + .typename = "GIUINTH", + .startup = startup_giuint_high_irq, + .shutdown = shutdown_giuint_high_irq, + .enable = enable_giuint_high_irq, + .disable = disable_giuint_high_irq, + .ack = ack_giuint_high_irq, + .end = end_giuint_high_irq, +}; + +void __init init_vr41xx_giuint_irq(void) +{ + int i; + + for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + if (i < (GIU_IRQ_BASE + GIUINT_HIGH_OFFSET)) + irq_desc[i].handler = &giuint_low_irq_type; + else + irq_desc[i].handler = &giuint_high_irq_type; + } + + setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade); } void vr41xx_set_irq_trigger(int pin, int trigger, int hold) { uint16_t mask; - if (pin < 16) { + if (pin < GIUINT_HIGH_OFFSET) { mask = (uint16_t)1 << pin; if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPL, mask); @@ -142,8 +232,9 @@ void vr41xx_set_irq_trigger(int pin, int trigger, int hold) clear_giuint(GIUINTTYPL, mask); clear_giuint(GIUINTHTSELL, mask); } + write_giuint(mask, GIUINTSTATL); } else { - mask = (uint16_t)1 << (pin - 16); + mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPH, mask); if (hold == SIGNAL_HOLD) @@ -170,32 +261,35 @@ void vr41xx_set_irq_trigger(int pin, int trigger, int hold) clear_giuint(GIUINTTYPH, mask); clear_giuint(GIUINTHTSELH, mask); } + write_giuint(mask, GIUINTSTATH); } - - vr41xx_clear_giuint(pin); } +EXPORT_SYMBOL(vr41xx_set_irq_trigger); + void vr41xx_set_irq_level(int pin, int level) { uint16_t mask; - if (pin < 16) { + if (pin < GIUINT_HIGH_OFFSET) { mask = (uint16_t)1 << pin; if (level == LEVEL_HIGH) set_giuint(GIUINTALSELL, mask); else clear_giuint(GIUINTALSELL, mask); + write_giuint(mask, GIUINTSTATL); } else { - mask = (uint16_t)1 << (pin - 16); + mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET); if (level == LEVEL_HIGH) set_giuint(GIUINTALSELH, mask); else clear_giuint(GIUINTALSELH, mask); + write_giuint(mask, GIUINTSTATH); } - - vr41xx_clear_giuint(pin); } +EXPORT_SYMBOL(vr41xx_set_irq_level); + #define GIUINT_NR_IRQS 32 enum { @@ -232,7 +326,7 @@ int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)) giuint_cascade[pin].get_irq_number = get_irq_number; retval = setup_irq(irq, &giu_cascade); - if (retval) { + if (retval != 0) { giuint_cascade[pin].flag = GIUINT_NO_CASCADE; giuint_cascade[pin].get_irq_number = no_irq_number; } @@ -240,29 +334,89 @@ int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)) return retval; } -unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs) +EXPORT_SYMBOL(vr41xx_cascade_irq); + +static inline int get_irq_pin_number(void) +{ + uint16_t pendl, pendh, maskl, maskh; + int i; + + pendl = read_giuint(GIUINTSTATL); + pendh = read_giuint(GIUINTSTATH); + maskl = read_giuint(GIUINTENL); + maskh = read_giuint(GIUINTENH); + + maskl &= pendl; + maskh &= pendh; + + if (maskl) { + for (i = 0; i < 16; i++) { + if (maskl & ((uint16_t)1 << i)) + return i; + } + } else if (maskh) { + for (i = 0; i < 16; i++) { + if (maskh & ((uint16_t)1 << i)) + return i + GIUINT_HIGH_OFFSET; + } + } + + printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", + maskl, pendl, maskh, pendh); + + atomic_inc(&irq_err_count); + + return -1; +} + +static inline void ack_giuint_irq(int pin) +{ + if (pin < GIUINT_HIGH_OFFSET) { + clear_giuint(GIUINTENL, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); + } else { + pin -= GIUINT_HIGH_OFFSET; + clear_giuint(GIUINTENH, (uint16_t)1 << pin); + write_giuint((uint16_t)1 << pin, GIUINTSTATH); + } +} + +static inline void end_giuint_irq(int pin) +{ + if (pin < GIUINT_HIGH_OFFSET) + set_giuint(GIUINTENL, (uint16_t)1 << pin); + else + set_giuint(GIUINTENH, (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET)); +} + +void giuint_irq_dispatch(struct pt_regs *regs) { struct vr41xx_giuint_cascade *cascade; - unsigned int retval = 0; - int giuint_irq, cascade_irq; + unsigned int giuint_irq; + int pin; + + pin = get_irq_pin_number(); + if (pin < 0) + return; disable_irq(GIUINT_CASCADE_IRQ); + cascade = &giuint_cascade[pin]; giuint_irq = GIU_IRQ(pin); if (cascade->flag == GIUINT_CASCADE) { - cascade_irq = cascade->get_irq_number(giuint_irq); - disable_irq(giuint_irq); - if (cascade_irq > 0) - retval = do_IRQ(cascade_irq, regs); - enable_irq(giuint_irq); - } else - retval = do_IRQ(giuint_irq, regs); - enable_irq(GIUINT_CASCADE_IRQ); + int irq = cascade->get_irq_number(giuint_irq); + ack_giuint_irq(pin); + if (irq >= 0) + do_IRQ(irq, regs); + end_giuint_irq(pin); + } else { + do_IRQ(giuint_irq, regs); + } - return retval; + enable_irq(GIUINT_CASCADE_IRQ); } -void __init vr41xx_giuint_init(void) +static int __init vr41xx_giu_init(void) { int i; @@ -277,16 +431,20 @@ void __init vr41xx_giuint_init(void) giu_base = GIUIOSELL_TYPE2; break; default: - panic("GIU: Unexpected CPU of NEC VR4100 series"); - break; + printk(KERN_ERR "GIU: Unexpected CPU of NEC VR4100 series\n"); + return -EINVAL; } for (i = 0; i < GIUINT_NR_IRQS; i++) { - vr41xx_disable_giuint(i); + if (i < GIUINT_HIGH_OFFSET) + clear_giuint(GIUINTENL, (uint16_t)1 << i); + else + clear_giuint(GIUINTENH, (uint16_t)1 << (i - GIUINT_HIGH_OFFSET)); giuint_cascade[i].flag = GIUINT_NO_CASCADE; giuint_cascade[i].get_irq_number = no_irq_number; } - if (setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade)) - printk("GIUINT: Can not cascade IRQ %d.\n", GIUINT_CASCADE_IRQ); + return 0; } + +early_initcall(vr41xx_giu_init); diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 1f223d70e4e6..4fd195bc9ad2 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -28,10 +28,12 @@ * Yoichi Yuasa * - Coped with INTASSIGN of NEC VR4133. */ +#include #include #include #include #include +#include #include #include @@ -43,11 +45,8 @@ extern asmlinkage void vr41xx_handle_interrupt(void); -extern void vr41xx_giuint_init(void); -extern void vr41xx_enable_giuint(int pin); -extern void vr41xx_disable_giuint(int pin); -extern void vr41xx_clear_giuint(int pin); -extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); +extern void init_vr41xx_giuint_irq(void); +extern void giuint_irq_dispatch(struct pt_regs *regs); static uint32_t icu1_base; static uint32_t icu2_base; @@ -64,11 +63,17 @@ static unsigned char sysint2_assign[16] = { #define SYSINT2REG_TYPE2 KSEG1ADDR(0x0f0000a0) #define SYSINT1REG 0x00 +#define PIUINTREG 0x02 #define INTASSIGN0 0x04 #define INTASSIGN1 0x06 #define GIUINTLREG 0x08 +#define DSIUINTREG 0x0a #define MSYSINT1REG 0x0c +#define MPIUINTREG 0x0e +#define MAIUINTREG 0x10 +#define MKIUINTREG 0x12 #define MGIUINTLREG 0x14 +#define MDSIUINTREG 0x16 #define NMIREG 0x18 #define SOFTREG 0x1a #define INTASSIGN2 0x1c @@ -76,11 +81,21 @@ static unsigned char sysint2_assign[16] = { #define SYSINT2REG 0x00 #define GIUINTHREG 0x02 +#define FIRINTREG 0x04 #define MSYSINT2REG 0x06 #define MGIUINTHREG 0x08 - -#define MDSIUINTREG KSEG1ADDR(0x0f000096) - #define INTDSIU 0x0800 +#define MFIRINTREG 0x0a +#define PCIINTREG 0x0c + #define PCIINT0 0x0001 +#define SCUINTREG 0x0e + #define SCUINT0 0x0001 +#define CSIINTREG 0x10 +#define MPCIINTREG 0x12 +#define MSCUINTREG 0x14 +#define MCSIINTREG 0x16 +#define BCUINTREG 0x18 + #define BCUINTR 0x0001 +#define MBCUINTREG 0x1a #define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */ #define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */ @@ -140,212 +155,298 @@ static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear) /*=======================================================================*/ -void vr41xx_enable_dsiuint(void) +void vr41xx_enable_piuint(uint16_t mask) { - writew(INTDSIU, MDSIUINTREG); + irq_desc_t *desc = irq_desc + PIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MPIUINTREG); + val |= mask; + write_icu1(val, MPIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -void vr41xx_disable_dsiuint(void) +void vr41xx_disable_piuint(uint16_t mask) { - writew(0, MDSIUINTREG); + irq_desc_t *desc = irq_desc + PIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MPIUINTREG); + val &= ~mask; + write_icu1(val, MPIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -/*=======================================================================*/ - -static void enable_sysint1_irq(unsigned int irq) +void vr41xx_enable_aiuint(uint16_t mask) { - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + AIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MAIUINTREG); + val |= mask; + write_icu1(val, MAIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_sysint1_irq(unsigned int irq) +void vr41xx_disable_aiuint(uint16_t mask) { - clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + AIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MAIUINTREG); + val &= ~mask; + write_icu1(val, MAIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_sysint1_irq(unsigned int irq) +void vr41xx_enable_kiuint(uint16_t mask) { - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); - - return 0; /* never anything pending */ + irq_desc_t *desc = irq_desc + KIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MKIUINTREG); + val |= mask; + write_icu1(val, MKIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -#define shutdown_sysint1_irq disable_sysint1_irq -#define ack_sysint1_irq disable_sysint1_irq - -static void end_sysint1_irq(unsigned int irq) +void vr41xx_disable_kiuint(uint16_t mask) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + KIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MKIUINTREG); + val &= ~mask; + write_icu1(val, MKIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static struct hw_interrupt_type sysint1_irq_type = { - .typename = "SYSINT1", - .startup = startup_sysint1_irq, - .shutdown = shutdown_sysint1_irq, - .enable = enable_sysint1_irq, - .disable = disable_sysint1_irq, - .ack = ack_sysint1_irq, - .end = end_sysint1_irq, -}; +void vr41xx_enable_dsiuint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + DSIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MDSIUINTREG); + val |= mask; + write_icu1(val, MDSIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -/*=======================================================================*/ +void vr41xx_disable_dsiuint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + DSIU_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu1(MDSIUINTREG); + val &= ~mask; + write_icu1(val, MDSIUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -static void enable_sysint2_irq(unsigned int irq) +void vr41xx_enable_firint(uint16_t mask) { - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + FIR_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MFIRINTREG); + val |= mask; + write_icu2(val, MFIRINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_sysint2_irq(unsigned int irq) +void vr41xx_disable_firint(uint16_t mask) { - clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + FIR_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MFIRINTREG); + val &= ~mask; + write_icu2(val, MFIRINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_sysint2_irq(unsigned int irq) +void vr41xx_enable_pciint(void) { - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + PCI_IRQ; + unsigned long flags; - return 0; /* never anything pending */ + spin_lock_irqsave(&desc->lock, flags); + write_icu2(PCIINT0, MPCIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -#define shutdown_sysint2_irq disable_sysint2_irq -#define ack_sysint2_irq disable_sysint2_irq +void vr41xx_disable_pciint(void) +{ + irq_desc_t *desc = irq_desc + PCI_IRQ; + unsigned long flags; -static void end_sysint2_irq(unsigned int irq) + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MPCIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +void vr41xx_enable_scuint(void) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + SCU_IRQ; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + write_icu2(SCUINT0, MSCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static struct hw_interrupt_type sysint2_irq_type = { - .typename = "SYSINT2", - .startup = startup_sysint2_irq, - .shutdown = shutdown_sysint2_irq, - .enable = enable_sysint2_irq, - .disable = disable_sysint2_irq, - .ack = ack_sysint2_irq, - .end = end_sysint2_irq, -}; +void vr41xx_disable_scuint(void) +{ + irq_desc_t *desc = irq_desc + SCU_IRQ; + unsigned long flags; -/*=======================================================================*/ + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MSCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} -static void enable_giuint_irq(unsigned int irq) +void vr41xx_enable_csiint(uint16_t mask) { - int pin; + irq_desc_t *desc = irq_desc + CSI_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MCSIINTREG); + val |= mask; + write_icu2(val, MCSIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} - pin = GIU_IRQ_TO_PIN(irq); - if (pin < 16) - set_icu1(MGIUINTLREG, (uint16_t)1 << pin); - else - set_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); - vr41xx_enable_giuint(pin); +void vr41xx_disable_csiint(uint16_t mask) +{ + irq_desc_t *desc = irq_desc + CSI_IRQ; + unsigned long flags; + uint16_t val; + + spin_lock_irqsave(&desc->lock, flags); + val = read_icu2(MCSIINTREG); + val &= ~mask; + write_icu2(val, MCSIINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static void disable_giuint_irq(unsigned int irq) +void vr41xx_enable_bcuint(void) { - int pin; + irq_desc_t *desc = irq_desc + BCU_IRQ; + unsigned long flags; - pin = GIU_IRQ_TO_PIN(irq); - vr41xx_disable_giuint(pin); - if (pin < 16) - clear_icu1(MGIUINTLREG, (uint16_t)1 << pin); - else - clear_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); + spin_lock_irqsave(&desc->lock, flags); + write_icu2(BCUINTR, MBCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); } -static unsigned int startup_giuint_irq(unsigned int irq) +void vr41xx_disable_bcuint(void) { - vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); + irq_desc_t *desc = irq_desc + BCU_IRQ; + unsigned long flags; - enable_giuint_irq(irq); + spin_lock_irqsave(&desc->lock, flags); + write_icu2(0, MBCUINTREG); + spin_unlock_irqrestore(&desc->lock, flags); +} + +/*=======================================================================*/ + +static unsigned int startup_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } -#define shutdown_giuint_irq disable_giuint_irq - -static void ack_giuint_irq(unsigned int irq) +static void shutdown_sysint1_irq(unsigned int irq) { - disable_giuint_irq(irq); + clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); +} - vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); +static void enable_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } -static void end_giuint_irq(unsigned int irq) +#define disable_sysint1_irq shutdown_sysint1_irq +#define ack_sysint1_irq shutdown_sysint1_irq + +static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_giuint_irq(irq); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } -static struct hw_interrupt_type giuint_irq_type = { - .typename = "GIUINT", - .startup = startup_giuint_irq, - .shutdown = shutdown_giuint_irq, - .enable = enable_giuint_irq, - .disable = disable_giuint_irq, - .ack = ack_giuint_irq, - .end = end_giuint_irq, +static struct hw_interrupt_type sysint1_irq_type = { + .typename = "SYSINT1", + .startup = startup_sysint1_irq, + .shutdown = shutdown_sysint1_irq, + .enable = enable_sysint1_irq, + .disable = disable_sysint1_irq, + .ack = ack_sysint1_irq, + .end = end_sysint1_irq, }; /*=======================================================================*/ -static struct irqaction icu_cascade = {no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; - -static void __init vr41xx_icu_init(void) +static unsigned int startup_sysint2_irq(unsigned int irq) { - int i; - - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - icu1_base = SYSINT1REG_TYPE1; - icu2_base = SYSINT2REG_TYPE1; - break; - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4133: - icu1_base = SYSINT1REG_TYPE2; - icu2_base = SYSINT2REG_TYPE2; - break; - default: - panic("Unexpected CPU of NEC VR4100 series"); - break; - } - - write_icu1(0, MSYSINT1REG); - write_icu1(0, MGIUINTLREG); - - write_icu2(0, MSYSINT2REG); - write_icu2(0, MGIUINTHREG); - - for (i = SYSINT1_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { - if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST) - irq_desc[i].handler = &sysint1_irq_type; - else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST) - irq_desc[i].handler = &sysint2_irq_type; - else if (i >= GIU_IRQ_BASE && i <= GIU_IRQ_LAST) - irq_desc[i].handler = &giuint_irq_type; - } + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); - setup_irq(INT0_CASCADE_IRQ, &icu_cascade); - setup_irq(INT1_CASCADE_IRQ, &icu_cascade); - setup_irq(INT2_CASCADE_IRQ, &icu_cascade); - setup_irq(INT3_CASCADE_IRQ, &icu_cascade); - setup_irq(INT4_CASCADE_IRQ, &icu_cascade); + return 0; /* never anything pending */ } -void __init init_IRQ(void) +static void shutdown_sysint2_irq(unsigned int irq) { - memset(irq_desc, 0, sizeof(irq_desc)); + clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); +} - init_generic_irq(); - mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); - vr41xx_icu_init(); +static void enable_sysint2_irq(unsigned int irq) +{ + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); +} - vr41xx_giuint_init(); +#define disable_sysint2_irq shutdown_sysint2_irq +#define ack_sysint2_irq shutdown_sysint2_irq - set_except_vector(0, vr41xx_handle_interrupt); +static void end_sysint2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } +static struct hw_interrupt_type sysint2_irq_type = { + .typename = "SYSINT2", + .startup = startup_sysint2_irq, + .shutdown = shutdown_sysint2_irq, + .enable = enable_sysint2_irq, + .disable = disable_sysint2_irq, + .ack = ack_sysint2_irq, + .end = end_sysint2_irq, +}; + /*=======================================================================*/ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) @@ -492,34 +593,14 @@ int vr41xx_set_intassign(unsigned int irq, unsigned char intassign) return retval; } -/*=======================================================================*/ +EXPORT_SYMBOL(vr41xx_set_intassign); -static inline void giuint_irq_dispatch(uint16_t pendl, uint16_t pendh, - struct pt_regs *regs) -{ - int i; - - if (pendl) { - for (i = 0; i < 16; i++) { - if (pendl & ((uint16_t)1 << i)) { - giuint_do_IRQ(i, regs); - return; - } - } - } else { - for (i = 0; i < 16; i++) { - if (pendh & ((uint16_t)1 << i)) { - giuint_do_IRQ(i + 16, regs); - return; - } - } - } -} +/*=======================================================================*/ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) { - uint16_t pend1, pend2, pendl, pendh; - uint16_t mask1, mask2, maskl, maskh; + uint16_t pend1, pend2; + uint16_t mask1, mask2; int i; pend1 = read_icu1(SYSINT1REG); @@ -528,28 +609,18 @@ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) pend2 = read_icu2(SYSINT2REG); mask2 = read_icu2(MSYSINT2REG); - pendl = read_icu1(GIUINTLREG); - maskl = read_icu1(MGIUINTLREG); - - pendh = read_icu2(GIUINTHREG); - maskh = read_icu2(MGIUINTHREG); - mask1 &= pend1; mask2 &= pend2; - maskl &= pendl; - maskh &= pendh; if (mask1) { for (i = 0; i < 16; i++) { if (intnum == sysint1_assign[i] && (mask1 & ((uint16_t)1 << i))) { - if (i == 8 && (maskl | maskh)) { - giuint_irq_dispatch(maskl, maskh, regs); - return; - } else { + if (i == 8) + giuint_irq_dispatch(regs); + else do_IRQ(SYSINT1_IRQ(i), regs); - return; - } + return; } } } @@ -564,6 +635,72 @@ asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) } } - printk(KERN_ERR "spurious interrupt: %04x,%04x,%04x,%04x\n", pend1, pend2, pendl, pendh); + printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); + atomic_inc(&irq_err_count); } + +/*=======================================================================*/ + +static int __init vr41xx_icu_init(void) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + icu1_base = SYSINT1REG_TYPE1; + icu2_base = SYSINT2REG_TYPE1; + break; + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: + icu1_base = SYSINT1REG_TYPE2; + icu2_base = SYSINT2REG_TYPE2; + break; + default: + printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n"); + return -EINVAL; + } + + write_icu1(0, MSYSINT1REG); + write_icu1(0xffff, MGIUINTLREG); + + write_icu2(0, MSYSINT2REG); + write_icu2(0xffff, MGIUINTHREG); + + return 0; +} + +early_initcall(vr41xx_icu_init); + +/*=======================================================================*/ + +static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; + +static inline void init_vr41xx_icu_irq(void) +{ + int i; + + for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) + irq_desc[i].handler = &sysint1_irq_type; + + for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) + irq_desc[i].handler = &sysint2_irq_type; + + setup_irq(INT0_CASCADE_IRQ, &icu_cascade); + setup_irq(INT1_CASCADE_IRQ, &icu_cascade); + setup_irq(INT2_CASCADE_IRQ, &icu_cascade); + setup_irq(INT3_CASCADE_IRQ, &icu_cascade); + setup_irq(INT4_CASCADE_IRQ, &icu_cascade); +} + +void __init init_IRQ(void) +{ + memset(irq_desc, 0, sizeof(irq_desc)); + + init_generic_irq(); + mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); + init_vr41xx_icu_irq(); + init_vr41xx_giuint_irq(); + + set_except_vector(0, vr41xx_handle_interrupt); +} diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c index 6590850b312f..ffc8e1c36b67 100644 --- a/arch/mips/vr41xx/common/init.c +++ b/arch/mips/vr41xx/common/init.c @@ -18,16 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include #include -#include - -extern void vr41xx_bcu_init(void); -extern void vr41xx_cmu_init(void); -extern void vr41xx_pmu_init(void); -extern void vr41xx_rtc_init(void); void __init prom_init(void) { @@ -42,14 +35,6 @@ void __init prom_init(void) if (i < (argc - 1)) strcat(arcs_cmdline, " "); } - - iomem_resource.start = IO_MEM_RESOURCE_START; - iomem_resource.end = IO_MEM_RESOURCE_END; - - vr41xx_bcu_init(); - vr41xx_cmu_init(); - vr41xx_pmu_init(); - vr41xx_rtc_init(); } unsigned long __init prom_free_prom_memory (void) diff --git a/arch/mips/vr41xx/common/ksyms.c b/arch/mips/vr41xx/common/ksyms.c index ea5231de0916..cfaa0ecd1786 100644 --- a/arch/mips/vr41xx/common/ksyms.c +++ b/arch/mips/vr41xx/common/ksyms.c @@ -25,8 +25,6 @@ EXPORT_SYMBOL(vr41xx_get_vtclock_frequency); EXPORT_SYMBOL(vr41xx_get_tclock_frequency); -EXPORT_SYMBOL(vr41xx_set_intassign); - EXPORT_SYMBOL(vr41xx_set_rtclong1_cycle); EXPORT_SYMBOL(vr41xx_read_rtclong1_counter); EXPORT_SYMBOL(vr41xx_set_rtclong2_cycle); diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index 9b5a82e63442..3e1079dfb6c1 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c @@ -1,7 +1,7 @@ /* * pmu.c, Power Management Unit routines for NEC VR4100 series. * - * Copyright (C) 2003 Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -68,9 +68,13 @@ static void vr41xx_power_off(void) while (1) ; } -void __init vr41xx_pmu_init(void) +static int __init vr41xx_pmu_init(void) { _machine_restart = vr41xx_restart; _machine_halt = vr41xx_halt; _machine_power_off = vr41xx_power_off; + + return 0; } + +early_initcall(vr41xx_pmu_init); diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c index 6fa5fdc28f4b..07173afe1faf 100644 --- a/arch/mips/vr41xx/common/rtc.c +++ b/arch/mips/vr41xx/common/rtc.c @@ -1,7 +1,7 @@ /* * rtc.c, RTC(has only timer function) routines for NEC VR4100 series. * - * Copyright (C) 2003 Yoichi Yuasa + * Copyright (C) 2003-2004 Yoichi Yuasa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -310,8 +310,12 @@ static void __init vr41xx_timer_setup(struct irqaction *irq) setup_irq(ELAPSEDTIME_IRQ, irq); } -void __init vr41xx_rtc_init(void) +static int __init vr41xx_rtc_init(void) { board_time_init = vr41xx_time_init; board_timer_setup = vr41xx_timer_setup; + + return 0; } + +early_initcall(vr41xx_rtc_init); diff --git a/arch/mips/vr41xx/common/serial.c b/arch/mips/vr41xx/common/serial.c index b052a9548f39..cc445eeff22e 100644 --- a/arch/mips/vr41xx/common/serial.c +++ b/arch/mips/vr41xx/common/serial.c @@ -168,7 +168,7 @@ void __init vr41xx_dsiu_init(void) if (port.membase != NULL) { if (early_serial_setup(&port) == 0) { vr41xx_supply_clock(DSIU_CLOCK); - vr41xx_enable_dsiuint(); + vr41xx_enable_dsiuint(DSIUINT_ALL); vr41xx_serial_ports++; return; } diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c index cce22c1594cf..3b006358c5c1 100644 --- a/arch/mips/vr41xx/common/vrc4173.c +++ b/arch/mips/vr41xx/common/vrc4173.c @@ -1,143 +1,336 @@ /* - * FILE NAME - * drivers/char/vrc4173.c - * - * BRIEF MODULE DESCRIPTION - * NEC VRC4173 driver for NEC VR4122/VR4131. + * vrc4173.c, NEC VRC4173 base driver for NEC VR4122/VR4131. * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * Copyright (C) 2001-2003 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * Copyright 2001,2002 MontaVista Software Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include #include #include +#include #include #include #include -MODULE_DESCRIPTION("NEC VRC4173 driver for NEC VR4122/4131"); +MODULE_DESCRIPTION("NEC VRC4173 base driver for NEC VR4122/4131"); MODULE_AUTHOR("Yoichi Yuasa "); MODULE_LICENSE("GPL"); #define VRC4173_CMUCLKMSK 0x040 + #define MSKPIU 0x0001 + #define MSKKIU 0x0002 + #define MSKAIU 0x0004 + #define MSKPS2CH1 0x0008 + #define MSKPS2CH2 0x0010 + #define MSKUSB 0x0020 + #define MSKCARD1 0x0040 + #define MSKCARD2 0x0080 + #define MSKAC97 0x0100 + #define MSK48MUSB 0x0400 + #define MSK48MPIN 0x0800 + #define MSK48MOSC 0x1000 #define VRC4173_CMUSRST 0x042 - -#define VRC4173_SELECTREG 0x09e + #define USBRST 0x0001 + #define CARD1RST 0x0002 + #define CARD2RST 0x0004 + #define AC97RST 0x0008 #define VRC4173_SYSINT1REG 0x060 #define VRC4173_MSYSINT1REG 0x06c -static struct pci_device_id vrc4173_table[] = { - {PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0, } +#define VRC4173_SELECTREG 0x09e + #define SEL3 0x0008 + #define SEL2 0x0004 + #define SEL1 0x0002 + #define SEL0 0x0001 + +static struct pci_device_id vrc4173_id_table[] __devinitdata = { + { .vendor = PCI_VENDOR_ID_NEC, + .device = PCI_DEVICE_ID_NEC_VRC4173, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, + { .vendor = 0, }, }; unsigned long vrc4173_io_offset = 0; EXPORT_SYMBOL(vrc4173_io_offset); -static u16 vrc4173_cmuclkmsk; static int vrc4173_initialized; +static uint16_t vrc4173_cmuclkmsk; +static uint16_t vrc4173_selectreg; +static spinlock_t vrc4173_cmu_lock; +static spinlock_t vrc4173_giu_lock; -void vrc4173_clock_supply(u16 mask) +static inline void set_cmusrst(uint16_t val) +{ + uint16_t cmusrst; + + cmusrst = vrc4173_inw(VRC4173_CMUSRST); + cmusrst |= val; + vrc4173_outw(cmusrst, VRC4173_CMUSRST); +} + +static inline void clear_cmusrst(uint16_t val) +{ + uint16_t cmusrst; + + cmusrst = vrc4173_inw(VRC4173_CMUSRST); + cmusrst &= ~val; + vrc4173_outw(cmusrst, VRC4173_CMUSRST); +} + +void vrc4173_supply_clock(vrc4173_clock_t clock) { if (vrc4173_initialized) { - vrc4173_cmuclkmsk |= mask; + spin_lock_irq(&vrc4173_cmu_lock); + + switch (clock) { + case VRC4173_PIU_CLOCK: + vrc4173_cmuclkmsk |= MSKPIU; + break; + case VRC4173_KIU_CLOCK: + vrc4173_cmuclkmsk |= MSKKIU; + break; + case VRC4173_AIU_CLOCK: + vrc4173_cmuclkmsk |= MSKAIU; + break; + case VRC4173_PS2_CH1_CLOCK: + vrc4173_cmuclkmsk |= MSKPS2CH1; + break; + case VRC4173_PS2_CH2_CLOCK: + vrc4173_cmuclkmsk |= MSKPS2CH2; + break; + case VRC4173_USBU_PCI_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk |= MSKUSB; + break; + case VRC4173_CARDU1_PCI_CLOCK: + set_cmusrst(CARD1RST); + vrc4173_cmuclkmsk |= MSKCARD1; + break; + case VRC4173_CARDU2_PCI_CLOCK: + set_cmusrst(CARD2RST); + vrc4173_cmuclkmsk |= MSKCARD2; + break; + case VRC4173_AC97U_PCI_CLOCK: + set_cmusrst(AC97RST); + vrc4173_cmuclkmsk |= MSKAC97; + break; + case VRC4173_USBU_48MHz_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk |= MSK48MUSB; + break; + case VRC4173_EXT_48MHz_CLOCK: + if (vrc4173_cmuclkmsk & MSK48MOSC) + vrc4173_cmuclkmsk |= MSK48MPIN; + else + printk(KERN_WARNING + "vrc4173_supply_clock: " + "Please supply VRC4173_48MHz_CLOCK first " + "rather than VRC4173_EXT_48MHz_CLOCK.\n"); + break; + case VRC4173_48MHz_CLOCK: + vrc4173_cmuclkmsk |= MSK48MOSC; + break; + default: + printk(KERN_WARNING + "vrc4173_supply_clock: Invalid CLOCK value %u\n", clock); + break; + } + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + + switch (clock) { + case VRC4173_USBU_PCI_CLOCK: + case VRC4173_USBU_48MHz_CLOCK: + clear_cmusrst(USBRST); + break; + case VRC4173_CARDU1_PCI_CLOCK: + clear_cmusrst(CARD1RST); + break; + case VRC4173_CARDU2_PCI_CLOCK: + clear_cmusrst(CARD2RST); + break; + case VRC4173_AC97U_PCI_CLOCK: + clear_cmusrst(AC97RST); + break; + default: + break; + } + + spin_unlock_irq(&vrc4173_cmu_lock); } } -void vrc4173_clock_mask(u16 mask) +EXPORT_SYMBOL(vrc4173_supply_clock); + +void vrc4173_mask_clock(vrc4173_clock_t clock) { if (vrc4173_initialized) { - vrc4173_cmuclkmsk &= ~mask; + spin_lock_irq(&vrc4173_cmu_lock); + + switch (clock) { + case VRC4173_PIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPIU; + break; + case VRC4173_KIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKKIU; + break; + case VRC4173_AIU_CLOCK: + vrc4173_cmuclkmsk &= ~MSKAIU; + break; + case VRC4173_PS2_CH1_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPS2CH1; + break; + case VRC4173_PS2_CH2_CLOCK: + vrc4173_cmuclkmsk &= ~MSKPS2CH2; + break; + case VRC4173_USBU_PCI_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk &= ~MSKUSB; + break; + case VRC4173_CARDU1_PCI_CLOCK: + set_cmusrst(CARD1RST); + vrc4173_cmuclkmsk &= ~MSKCARD1; + break; + case VRC4173_CARDU2_PCI_CLOCK: + set_cmusrst(CARD2RST); + vrc4173_cmuclkmsk &= ~MSKCARD2; + break; + case VRC4173_AC97U_PCI_CLOCK: + set_cmusrst(AC97RST); + vrc4173_cmuclkmsk &= ~MSKAC97; + break; + case VRC4173_USBU_48MHz_CLOCK: + set_cmusrst(USBRST); + vrc4173_cmuclkmsk &= ~MSK48MUSB; + break; + case VRC4173_EXT_48MHz_CLOCK: + vrc4173_cmuclkmsk &= ~MSK48MPIN; + break; + case VRC4173_48MHz_CLOCK: + vrc4173_cmuclkmsk &= ~MSK48MOSC; + break; + default: + printk(KERN_WARNING "vrc4173_mask_clock: Invalid CLOCK value %u\n", clock); + break; + } + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + + switch (clock) { + case VRC4173_USBU_PCI_CLOCK: + case VRC4173_USBU_48MHz_CLOCK: + clear_cmusrst(USBRST); + break; + case VRC4173_CARDU1_PCI_CLOCK: + clear_cmusrst(CARD1RST); + break; + case VRC4173_CARDU2_PCI_CLOCK: + clear_cmusrst(CARD2RST); + break; + case VRC4173_AC97U_PCI_CLOCK: + clear_cmusrst(AC97RST); + break; + default: + break; + } + + spin_unlock_irq(&vrc4173_cmu_lock); } } +EXPORT_SYMBOL(vrc4173_mask_clock); + static inline void vrc4173_cmu_init(void) { vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK); -} -EXPORT_SYMBOL(vrc4173_clock_supply); -EXPORT_SYMBOL(vrc4173_clock_mask); + spin_lock_init(&vrc4173_cmu_lock); +} -void vrc4173_select_function(int func) +void vrc4173_select_function(vrc4173_function_t function) { - u16 val; - if (vrc4173_initialized) { - val = vrc4173_inw(VRC4173_SELECTREG); - switch(func) { - case PS2CH1_SELECT: - val |= 0x0004; + spin_lock_irq(&vrc4173_giu_lock); + + switch(function) { + case PS2_CHANNEL1: + vrc4173_selectreg |= SEL2; break; - case PS2CH2_SELECT: - val |= 0x0002; + case PS2_CHANNEL2: + vrc4173_selectreg |= SEL1; break; - case TOUCHPANEL_SELECT: - val &= 0x0007; + case TOUCHPANEL: + vrc4173_selectreg &= SEL2 | SEL1 | SEL0; break; - case KIU8_SELECT: - val &= 0x000e; + case KEYBOARD_8SCANLINES: + vrc4173_selectreg &= SEL3 | SEL2 | SEL1; break; - case KIU10_SELECT: - val &= 0x000c; + case KEYBOARD_10SCANLINES: + vrc4173_selectreg &= SEL3 | SEL2; break; - case KIU12_SELECT: - val &= 0x0008; + case KEYBOARD_12SCANLINES: + vrc4173_selectreg &= SEL3; break; - case GPIO_SELECT: - val |= 0x0008; + case GPIO_0_15PINS: + vrc4173_selectreg |= SEL0; + break; + case GPIO_16_20PINS: + vrc4173_selectreg |= SEL3; break; } - vrc4173_outw(val, VRC4173_SELECTREG); + + vrc4173_outw(vrc4173_selectreg, VRC4173_SELECTREG); + + spin_unlock_irq(&vrc4173_giu_lock); } } EXPORT_SYMBOL(vrc4173_select_function); +static inline void vrc4173_giu_init(void) +{ + vrc4173_selectreg = vrc4173_inw(VRC4173_SELECTREG); + + spin_lock_init(&vrc4173_giu_lock); +} + static void enable_vrc4173_irq(unsigned int irq) { - u16 val; + uint16_t val; val = vrc4173_inw(VRC4173_MSYSINT1REG); - val |= (u16)1 << (irq - VRC4173_IRQ_BASE); + val |= (uint16_t)1 << (irq - VRC4173_IRQ_BASE); vrc4173_outw(val, VRC4173_MSYSINT1REG); } static void disable_vrc4173_irq(unsigned int irq) { - u16 val; + uint16_t val; val = vrc4173_inw(VRC4173_MSYSINT1REG); - val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE)); + val &= ~((uint16_t)1 << (irq - VRC4173_IRQ_BASE)); vrc4173_outw(val, VRC4173_MSYSINT1REG); } @@ -157,19 +350,18 @@ static void end_vrc4173_irq(unsigned int irq) } static struct hw_interrupt_type vrc4173_irq_type = { - "VRC4173", - startup_vrc4173_irq, - shutdown_vrc4173_irq, - enable_vrc4173_irq, - disable_vrc4173_irq, - ack_vrc4173_irq, - end_vrc4173_irq, - NULL + .typename = "VRC4173", + .startup = startup_vrc4173_irq, + .shutdown = shutdown_vrc4173_irq, + .enable = enable_vrc4173_irq, + .disable = disable_vrc4173_irq, + .ack = ack_vrc4173_irq, + .end = end_vrc4173_irq, }; static int vrc4173_get_irq_number(int irq) { - u16 status, mask; + uint16_t status, mask; int i; status = vrc4173_inw(VRC4173_SYSINT1REG); @@ -179,18 +371,18 @@ static int vrc4173_get_irq_number(int irq) if (status) { for (i = 0; i < 16; i++) if (status & (0x0001 << i)) - return VRC4173_IRQ_BASE + i; + return VRC4173_IRQ(i); } return -EINVAL; } -static inline void vrc4173_icu_init(int cascade_irq) +static inline int vrc4173_icu_init(int cascade_irq) { int i; if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15)) - return; + return -EINVAL; vrc4173_outw(0, VRC4173_MSYSINT1REG); @@ -199,33 +391,38 @@ static inline void vrc4173_icu_init(int cascade_irq) for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) irq_desc[i].handler = &vrc4173_irq_type; + + return 0; } -static int __devinit vrc4173_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit vrc4173_probe(struct pci_dev *dev, + const struct pci_device_id *id) { unsigned long start, flags; int err; - if ((err = pci_enable_device(pdev)) < 0) { - printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err); + err = pci_enable_device(dev); + if (err < 0) { + printk(KERN_ERR "vrc4173: Failed to enable PCI device, aborting\n"); return err; } - pci_set_master(pdev); + pci_set_master(dev); - start = pci_resource_start(pdev, 0); - if (!start) { - printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n"); - return -ENODEV; + start = pci_resource_start(dev, 0); + if (start == 0) { + printk(KERN_ERR "vrc4173:No such PCI I/O resource, aborting\n"); + return -ENXIO; } - if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) { - printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n"); - return -ENODEV; + flags = pci_resource_flags(dev, 0); + if ((flags & IORESOURCE_IO) == 0) { + printk(KERN_ERR "vrc4173: No such PCI I/O resource, aborting\n"); + return -ENXIO; } - if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) { + err = pci_request_regions(dev, "NEC VRC4173"); + if (err < 0) { printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n"); return err; } @@ -233,33 +430,46 @@ static int __devinit vrc4173_probe(struct pci_dev *pdev, set_vrc4173_io_offset(start); vrc4173_cmu_init(); + vrc4173_giu_init(); - vrc4173_icu_init(pdev->irq); + err = vrc4173_icu_init(dev->irq); + if (err < 0) { + printk(KERN_ERR "vrc4173: Invalid IRQ %d, aborting\n", dev->irq); + return err; + } - if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) { - printk(KERN_ERR - "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq); + err = vr41xx_cascade_irq(dev->irq, vrc4173_get_irq_number); + if (err < 0) { + printk(KERN_ERR "vrc4173: IRQ resource %d is busy, aborting\n", dev->irq); return err; } printk(KERN_INFO - "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq); + "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, dev->irq); return 0; } +static void vrc4173_remove(struct pci_dev *dev) +{ + free_irq(dev->irq, NULL); + + pci_release_regions(dev); +} + static struct pci_driver vrc4173_driver = { .name = "NEC VRC4173", .probe = vrc4173_probe, - .remove = NULL, - .id_table = vrc4173_table, + .remove = vrc4173_remove, + .id_table = vrc4173_id_table, }; static int __devinit vrc4173_init(void) { int err; - if ((err = pci_module_init(&vrc4173_driver)) < 0) + err = pci_module_init(&vrc4173_driver); + if (err < 0) return err; vrc4173_initialized = 1; diff --git a/arch/mips/vr41xx/tanbac-tb0226/setup.c b/arch/mips/vr41xx/tanbac-tb0226/setup.c index 995a578e25f6..752c0e736920 100644 --- a/arch/mips/vr41xx/tanbac-tb0226/setup.c +++ b/arch/mips/vr41xx/tanbac-tb0226/setup.c @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - .name = "PCI I/O space", - .start = VR41XX_PCI_IO_START, - .end = VR41XX_PCI_IO_END, - .flags = IORESOURCE_IO, -}; - -static struct resource vr41xx_pci_mem_resource = { - .name = "PCI memory space", - .start = VR41XX_PCI_MEM_START, - .end = VR41XX_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller[] = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - .internal_base = VR41XX_PCI_MEM1_BASE, - .address_mask = VR41XX_PCI_MEM1_MASK, - .pci_base = IO_MEM1_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - .internal_base = VR41XX_PCI_MEM2_BASE, - .address_mask = VR41XX_PCI_MEM2_MASK, - .pci_base = IO_MEM2_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - .internal_base = VR41XX_PCI_IO_BASE, - .address_mask = VR41XX_PCI_IO_MASK, - .pci_base = IO_PORT_RESOURCE_START, -}; - -static struct vr41xx_pci_address_map pci_address_map = { - .mem1 = &vr41xx_pci_mem1, - .mem2 = &vr41xx_pci_mem2, - .io = &vr41xx_pci_io, -}; -#endif +#include const char *get_system_type(void) { @@ -79,19 +28,11 @@ const char *get_system_type(void) static int tanbac_tb0226_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - return 0; } diff --git a/arch/mips/vr41xx/tanbac-tb0229/Makefile b/arch/mips/vr41xx/tanbac-tb0229/Makefile index ff7429e8174a..dd085394a876 100644 --- a/arch/mips/vr41xx/tanbac-tb0229/Makefile +++ b/arch/mips/vr41xx/tanbac-tb0229/Makefile @@ -4,4 +4,4 @@ obj-y := setup.o -obj-$(CONFIG_TANBAC_TB0219) += reboot.o +obj-$(CONFIG_TANBAC_TB0219) += tb0219.o diff --git a/arch/mips/vr41xx/tanbac-tb0229/reboot.c b/arch/mips/vr41xx/tanbac-tb0229/reboot.c deleted file mode 100644 index 02e837879b1c..000000000000 --- a/arch/mips/vr41xx/tanbac-tb0229/reboot.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/tanbac-tb0229/reboot.c - * - * BRIEF MODULE DESCRIPTION - * Depending on TANBAC TB0229(VR4131DIMM) of reboot system call. - * - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#define tb0229_hard_reset() writew(0, TB0219_RESET_REGS) - -void tanbac_tb0229_restart(char *command) -{ - local_irq_disable(); - tb0229_hard_reset(); - while (1); -} diff --git a/arch/mips/vr41xx/tanbac-tb0229/setup.c b/arch/mips/vr41xx/tanbac-tb0229/setup.c index 971473e617a8..9209e3dc6db6 100644 --- a/arch/mips/vr41xx/tanbac-tb0229/setup.c +++ b/arch/mips/vr41xx/tanbac-tb0229/setup.c @@ -21,60 +21,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - .name = "PCI I/O space", - .start = VR41XX_PCI_IO_START, - .end = VR41XX_PCI_IO_END, - .flags = IORESOURCE_IO, -}; - -static struct resource vr41xx_pci_mem_resource = { - .name = "PCI memory space", - .start = VR41XX_PCI_MEM_START, - .end = VR41XX_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - .internal_base = VR41XX_PCI_MEM1_BASE, - .address_mask = VR41XX_PCI_MEM1_MASK, - .pci_base = IO_MEM1_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - .internal_base = VR41XX_PCI_MEM2_BASE, - .address_mask = VR41XX_PCI_MEM2_MASK, - .pci_base = IO_MEM2_RESOURCE_START, -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - .internal_base = VR41XX_PCI_IO_BASE, - .address_mask = VR41XX_PCI_IO_MASK, - .pci_base = IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - .mem1 = &vr41xx_pci_mem1, - .mem2 = &vr41xx_pci_mem2, - .io = &vr41xx_pci_io, -}; -#endif +#include const char *get_system_type(void) { @@ -83,24 +31,12 @@ const char *get_system_type(void) static int tanbac_tb0229_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); vr41xx_dsiu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - -#ifdef CONFIG_TANBAC_TB0219 - _machine_restart = tanbac_tb0229_restart; -#endif - return 0; } diff --git a/arch/mips/vr41xx/tanbac-tb0229/tb0219.c b/arch/mips/vr41xx/tanbac-tb0229/tb0219.c new file mode 100644 index 000000000000..a07d9fa454ab --- /dev/null +++ b/arch/mips/vr41xx/tanbac-tb0229/tb0219.c @@ -0,0 +1,44 @@ +/* + * tb0219.c, Setup for the TANBAC TB0219 + * + * Copyright (C) 2003 Megasolution Inc. + * Copyright (C) 2004 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include + +#include +#include + +#define TB0219_RESET_REGS KSEG1ADDR(0x0a00000e) + +#define tb0219_hard_reset() writew(0, TB0219_RESET_REGS) + +static void tanbac_tb0219_restart(char *command) +{ + local_irq_disable(); + tb0219_hard_reset(); + while (1); +} + +static int __init tanbac_tb0219_setup(void) +{ + _machine_restart = tanbac_tb0219_restart; + + return 0; +} + +early_initcall(tanbac_tb0219_setup); diff --git a/arch/mips/vr41xx/victor-mpc30x/setup.c b/arch/mips/vr41xx/victor-mpc30x/setup.c index 5fc2084962c4..169ac00a1531 100644 --- a/arch/mips/vr41xx/victor-mpc30x/setup.c +++ b/arch/mips/vr41xx/victor-mpc30x/setup.c @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - "PCI I/O space", - VR41XX_PCI_IO_START, - VR41XX_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource vr41xx_pci_mem_resource = { - "PCI memory space", - VR41XX_PCI_MEM_START, - VR41XX_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller[] = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - VR41XX_PCI_MEM1_BASE, - VR41XX_PCI_MEM1_MASK, - IO_MEM1_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - VR41XX_PCI_MEM2_BASE, - VR41XX_PCI_MEM2_MASK, - IO_MEM2_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - VR41XX_PCI_IO_BASE, - VR41XX_PCI_IO_MASK, - IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - &vr41xx_pci_mem1, - &vr41xx_pci_mem2, - &vr41xx_pci_io -}; -#endif +#include const char *get_system_type(void) { @@ -79,19 +28,11 @@ const char *get_system_type(void) static int victor_mpc30x_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - return 0; } diff --git a/arch/mips/vr41xx/zao-capcella/setup.c b/arch/mips/vr41xx/zao-capcella/setup.c index 8b1e178ae9df..35b3a0a92f3d 100644 --- a/arch/mips/vr41xx/zao-capcella/setup.c +++ b/arch/mips/vr41xx/zao-capcella/setup.c @@ -18,59 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include -#include -#include -#include - -#ifdef CONFIG_PCI -static struct resource vr41xx_pci_io_resource = { - "PCI I/O space", - VR41XX_PCI_IO_START, - VR41XX_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource vr41xx_pci_mem_resource = { - "PCI memory space", - VR41XX_PCI_MEM_START, - VR41XX_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops vr41xx_pci_ops; - -struct pci_controller vr41xx_controller = { - .pci_ops = &vr41xx_pci_ops, - .io_resource = &vr41xx_pci_io_resource, - .mem_resource = &vr41xx_pci_mem_resource, -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem1 = { - VR41XX_PCI_MEM1_BASE, - VR41XX_PCI_MEM1_MASK, - IO_MEM1_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_mem2 = { - VR41XX_PCI_MEM2_BASE, - VR41XX_PCI_MEM2_MASK, - IO_MEM2_RESOURCE_START -}; - -struct vr41xx_pci_address_space vr41xx_pci_io = { - VR41XX_PCI_IO_BASE, - VR41XX_PCI_IO_MASK, - IO_PORT_RESOURCE_START -}; - -static struct vr41xx_pci_address_map pci_address_map = { - &vr41xx_pci_mem1, - &vr41xx_pci_mem2, - &vr41xx_pci_io -}; -#endif +#include const char *get_system_type(void) { @@ -79,20 +28,12 @@ const char *get_system_type(void) static int zao_capcella_setup(void) { - set_io_port_base(IO_PORT_BASE); - ioport_resource.start = IO_PORT_RESOURCE_START; - ioport_resource.end = IO_PORT_RESOURCE_END; - #ifdef CONFIG_SERIAL_8250 vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE); vr41xx_siu_init(); vr41xx_dsiu_init(); #endif -#ifdef CONFIG_PCI - vr41xx_pciu_init(&pci_address_map); -#endif - return 0; } diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h index c70f00d83364..37a460aa0378 100644 --- a/include/asm-mips/asmmacro.h +++ b/include/asm-mips/asmmacro.h @@ -9,6 +9,7 @@ #define _ASM_ASMMACRO_H #include +#include #ifdef CONFIG_MIPS32 #include @@ -21,6 +22,7 @@ mfc0 \reg, CP0_STATUS ori \reg, \reg, 1 mtc0 \reg, CP0_STATUS + irq_enable_hazard .endm .macro local_irq_disable reg=t0 @@ -28,7 +30,7 @@ ori \reg, \reg, 1 xori \reg, \reg, 1 mtc0 \reg, CP0_STATUS - SSNOP; SSNOP; SSNOP + irq_disable_hazard .endm #ifdef CONFIG_CPU_SB1 diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 1262c6eafb95..c8c6a5a8c5aa 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h @@ -9,7 +9,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 97, 99, 2000, 03 by Ralf Baechle + * Copyright (C) 1996, 97, 99, 2000, 03, 04 by Ralf Baechle */ /* @@ -127,6 +127,32 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) return result; } +/* + * atomic_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) +{ + unsigned long temp, result; + + __asm__ __volatile__( + "1: ll %1, %2 # atomic_sub_if_positive\n" + " subu %0, %1, %3 \n" + " bltz %0, 1f \n" + " sc %0, %2 \n" + " beqz %0, 1b \n" + " sync \n" + "1: \n" + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); + + return result; +} + #else /* @@ -192,6 +218,28 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) return temp; } +/* + * atomic_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) +{ + unsigned long flags; + int temp; + + spin_lock_irqsave(&atomic_lock, flags); + temp = v->counter; + temp -= i; + if (temp >= 0) + v->counter = temp; + spin_unlock_irqrestore(&atomic_lock, flags); + + return temp; +} + #endif /* CONFIG_CPU_HAS_LLSC */ #define atomic_dec_return(v) atomic_sub_return(1,(v)) @@ -228,6 +276,12 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) */ #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) +/* + * atomic_dec_if_positive - decrement by 1 if old value positive + * @v: pointer of type atomic_t + */ +#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) + /* * atomic_inc - increment atomic variable * @v: pointer of type atomic_t @@ -284,7 +338,7 @@ typedef struct { volatile __s64 counter; } atomic64_t; * * Atomically adds @i to @v. */ -static __inline__ void atomic64_add(int i, atomic64_t * v) +static __inline__ void atomic64_add(long i, atomic64_t * v) { unsigned long temp; @@ -304,7 +358,7 @@ static __inline__ void atomic64_add(int i, atomic64_t * v) * * Atomically subtracts @i from @v. */ -static __inline__ void atomic64_sub(int i, atomic64_t * v) +static __inline__ void atomic64_sub(long i, atomic64_t * v) { unsigned long temp; @@ -320,7 +374,7 @@ static __inline__ void atomic64_sub(int i, atomic64_t * v) /* * Same as above, but return the result value */ -static __inline__ int atomic64_add_return(int i, atomic64_t * v) +static __inline__ long atomic64_add_return(long i, atomic64_t * v) { unsigned long temp, result; @@ -338,7 +392,7 @@ static __inline__ int atomic64_add_return(int i, atomic64_t * v) return result; } -static __inline__ int atomic64_sub_return(int i, atomic64_t * v) +static __inline__ long atomic64_sub_return(long i, atomic64_t * v) { unsigned long temp, result; @@ -356,6 +410,32 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) return result; } +/* + * atomic64_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic64_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) +{ + unsigned long temp, result; + + __asm__ __volatile__( + "1: lld %1, %2 # atomic64_sub_if_positive\n" + " dsubu %0, %1, %3 \n" + " bltz %0, 1f \n" + " scd %0, %2 \n" + " beqz %0, 1b \n" + " sync \n" + "1: \n" + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); + + return result; +} + #else /* @@ -368,7 +448,7 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) * * Atomically adds @i to @v. */ -static __inline__ void atomic64_add(int i, atomic64_t * v) +static __inline__ void atomic64_add(long i, atomic64_t * v) { unsigned long flags; @@ -384,7 +464,7 @@ static __inline__ void atomic64_add(int i, atomic64_t * v) * * Atomically subtracts @i from @v. */ -static __inline__ void atomic64_sub(int i, atomic64_t * v) +static __inline__ void atomic64_sub(long i, atomic64_t * v) { unsigned long flags; @@ -393,10 +473,10 @@ static __inline__ void atomic64_sub(int i, atomic64_t * v) spin_unlock_irqrestore(&atomic_lock, flags); } -static __inline__ int atomic64_add_return(int i, atomic64_t * v) +static __inline__ long atomic64_add_return(long i, atomic64_t * v) { unsigned long flags; - int temp; + long temp; spin_lock_irqsave(&atomic_lock, flags); temp = v->counter; @@ -407,10 +487,10 @@ static __inline__ int atomic64_add_return(int i, atomic64_t * v) return temp; } -static __inline__ int atomic64_sub_return(int i, atomic64_t * v) +static __inline__ long atomic64_sub_return(long i, atomic64_t * v) { unsigned long flags; - int temp; + long temp; spin_lock_irqsave(&atomic_lock, flags); temp = v->counter; @@ -421,6 +501,28 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) return temp; } +/* + * atomic64_sub_if_positive - add integer to atomic variable + * @v: pointer of type atomic64_t + * + * Atomically test @v and decrement if it is greater than 0. + * The function returns the old value of @v minus 1. + */ +static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) +{ + unsigned long flags; + long temp; + + spin_lock_irqsave(&atomic_lock, flags); + temp = v->counter; + temp -= i; + if (temp >= 0) + v->counter = temp; + spin_unlock_irqrestore(&atomic_lock, flags); + + return temp; +} + #endif /* CONFIG_CPU_HAS_LLDSCD */ #define atomic64_dec_return(v) atomic64_sub_return(1,(v)) @@ -457,6 +559,12 @@ static __inline__ int atomic64_sub_return(int i, atomic64_t * v) */ #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0) +/* + * atomic64_dec_if_positive - decrement by 1 if old value positive + * @v: pointer of type atomic64_t + */ +#define atomic64_dec_if_positive(v) atomic64_sub_if_positive(1, v) + /* * atomic64_inc - increment atomic variable * @v: pointer of type atomic64_t diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h index fda57132db2c..4517bdf20953 100644 --- a/include/asm-mips/cache.h +++ b/include/asm-mips/cache.h @@ -18,4 +18,6 @@ #define SMP_CACHE_SHIFT L1_CACHE_SHIFT #define SMP_CACHE_BYTES L1_CACHE_BYTES +#define ARCH_KMALLOC_MINALIGN 8 + #endif /* _ASM_CACHE_H */ diff --git a/include/asm-mips/gt64240.h b/include/asm-mips/gt64240.h new file mode 100644 index 000000000000..12964c2c3e34 --- /dev/null +++ b/include/asm-mips/gt64240.h @@ -0,0 +1,1264 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright - Galileo technology. + * Copyright (C) 2004 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MV64240_H +#define __ASM_MIPS_MV64240_H + +#include +#include + +/* + * CPU Control Registers + */ + +#define CPU_CONFIGURATION 0x000 +#define CPU_MODE 0x120 +#define CPU_READ_RESPONSE_CROSSBAR_LOW 0x170 +#define CPU_READ_RESPONSE_CROSSBAR_HIGH 0x178 + +/* + * Processor Address Space + */ + +/* Sdram's BAR'S */ +#define SCS_0_LOW_DECODE_ADDRESS 0x008 +#define SCS_0_HIGH_DECODE_ADDRESS 0x010 +#define SCS_1_LOW_DECODE_ADDRESS 0x208 +#define SCS_1_HIGH_DECODE_ADDRESS 0x210 +#define SCS_2_LOW_DECODE_ADDRESS 0x018 +#define SCS_2_HIGH_DECODE_ADDRESS 0x020 +#define SCS_3_LOW_DECODE_ADDRESS 0x218 +#define SCS_3_HIGH_DECODE_ADDRESS 0x220 +/* Devices BAR'S */ +#define CS_0_LOW_DECODE_ADDRESS 0x028 +#define CS_0_HIGH_DECODE_ADDRESS 0x030 +#define CS_1_LOW_DECODE_ADDRESS 0x228 +#define CS_1_HIGH_DECODE_ADDRESS 0x230 +#define CS_2_LOW_DECODE_ADDRESS 0x248 +#define CS_2_HIGH_DECODE_ADDRESS 0x250 +#define CS_3_LOW_DECODE_ADDRESS 0x038 +#define CS_3_HIGH_DECODE_ADDRESS 0x040 +#define BOOTCS_LOW_DECODE_ADDRESS 0x238 +#define BOOTCS_HIGH_DECODE_ADDRESS 0x240 + +#define PCI_0I_O_LOW_DECODE_ADDRESS 0x048 +#define PCI_0I_O_HIGH_DECODE_ADDRESS 0x050 +#define PCI_0MEMORY0_LOW_DECODE_ADDRESS 0x058 +#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS 0x060 +#define PCI_0MEMORY1_LOW_DECODE_ADDRESS 0x080 +#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS 0x088 +#define PCI_0MEMORY2_LOW_DECODE_ADDRESS 0x258 +#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS 0x260 +#define PCI_0MEMORY3_LOW_DECODE_ADDRESS 0x280 +#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS 0x288 + +#define PCI_1I_O_LOW_DECODE_ADDRESS 0x090 +#define PCI_1I_O_HIGH_DECODE_ADDRESS 0x098 +#define PCI_1MEMORY0_LOW_DECODE_ADDRESS 0x0a0 +#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS 0x0a8 +#define PCI_1MEMORY1_LOW_DECODE_ADDRESS 0x0b0 +#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS 0x0b8 +#define PCI_1MEMORY2_LOW_DECODE_ADDRESS 0x2a0 +#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS 0x2a8 +#define PCI_1MEMORY3_LOW_DECODE_ADDRESS 0x2b0 +#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS 0x2b8 + +#define INTERNAL_SPACE_DECODE 0x068 + +#define CPU_0_LOW_DECODE_ADDRESS 0x290 +#define CPU_0_HIGH_DECODE_ADDRESS 0x298 +#define CPU_1_LOW_DECODE_ADDRESS 0x2c0 +#define CPU_1_HIGH_DECODE_ADDRESS 0x2c8 + +#define PCI_0I_O_ADDRESS_REMAP 0x0f0 +#define PCI_0MEMORY0_ADDRESS_REMAP 0x0f8 +#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP 0x320 +#define PCI_0MEMORY1_ADDRESS_REMAP 0x100 +#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP 0x328 +#define PCI_0MEMORY2_ADDRESS_REMAP 0x2f8 +#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP 0x330 +#define PCI_0MEMORY3_ADDRESS_REMAP 0x300 +#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP 0x338 + +#define PCI_1I_O_ADDRESS_REMAP 0x108 +#define PCI_1MEMORY0_ADDRESS_REMAP 0x110 +#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP 0x340 +#define PCI_1MEMORY1_ADDRESS_REMAP 0x118 +#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP 0x348 +#define PCI_1MEMORY2_ADDRESS_REMAP 0x310 +#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP 0x350 +#define PCI_1MEMORY3_ADDRESS_REMAP 0x318 +#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP 0x358 + +/* + * CPU Sync Barrier + */ + +#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER 0x0c0 +#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER 0x0c8 + + +/* + * CPU Access Protect + */ + +#define CPU_LOW_PROTECT_ADDRESS_0 0X180 +#define CPU_HIGH_PROTECT_ADDRESS_0 0X188 +#define CPU_LOW_PROTECT_ADDRESS_1 0X190 +#define CPU_HIGH_PROTECT_ADDRESS_1 0X198 +#define CPU_LOW_PROTECT_ADDRESS_2 0X1a0 +#define CPU_HIGH_PROTECT_ADDRESS_2 0X1a8 +#define CPU_LOW_PROTECT_ADDRESS_3 0X1b0 +#define CPU_HIGH_PROTECT_ADDRESS_3 0X1b8 +#define CPU_LOW_PROTECT_ADDRESS_4 0X1c0 +#define CPU_HIGH_PROTECT_ADDRESS_4 0X1c8 +#define CPU_LOW_PROTECT_ADDRESS_5 0X1d0 +#define CPU_HIGH_PROTECT_ADDRESS_5 0X1d8 +#define CPU_LOW_PROTECT_ADDRESS_6 0X1e0 +#define CPU_HIGH_PROTECT_ADDRESS_6 0X1e8 +#define CPU_LOW_PROTECT_ADDRESS_7 0X1f0 +#define CPU_HIGH_PROTECT_ADDRESS_7 0X1f8 + + +/* + * Snoop Control + */ + +#define SNOOP_BASE_ADDRESS_0 0x380 +#define SNOOP_TOP_ADDRESS_0 0x388 +#define SNOOP_BASE_ADDRESS_1 0x390 +#define SNOOP_TOP_ADDRESS_1 0x398 +#define SNOOP_BASE_ADDRESS_2 0x3a0 +#define SNOOP_TOP_ADDRESS_2 0x3a8 +#define SNOOP_BASE_ADDRESS_3 0x3b0 +#define SNOOP_TOP_ADDRESS_3 0x3b8 + +/* + * CPU Error Report + */ + +#define CPU_ERROR_ADDRESS_LOW 0x070 +#define CPU_ERROR_ADDRESS_HIGH 0x078 +#define CPU_ERROR_DATA_LOW 0x128 +#define CPU_ERROR_DATA_HIGH 0x130 +#define CPU_ERROR_PARITY 0x138 +#define CPU_ERROR_CAUSE 0x140 +#define CPU_ERROR_MASK 0x148 + +/* + * Pslave Debug + */ + +#define X_0_ADDRESS 0x360 +#define X_0_COMMAND_ID 0x368 +#define X_1_ADDRESS 0x370 +#define X_1_COMMAND_ID 0x378 +#define WRITE_DATA_LOW 0x3c0 +#define WRITE_DATA_HIGH 0x3c8 +#define WRITE_BYTE_ENABLE 0X3e0 +#define READ_DATA_LOW 0x3d0 +#define READ_DATA_HIGH 0x3d8 +#define READ_ID 0x3e8 + + +/* + * SDRAM and Device Address Space + */ + + +/* + * SDRAM Configuration + */ + +#define SDRAM_CONFIGURATION 0x448 +#define SDRAM_OPERATION_MODE 0x474 +#define SDRAM_ADDRESS_DECODE 0x47C +#define SDRAM_TIMING_PARAMETERS 0x4b4 +#define SDRAM_UMA_CONTROL 0x4a4 +#define SDRAM_CROSS_BAR_CONTROL_LOW 0x4a8 +#define SDRAM_CROSS_BAR_CONTROL_HIGH 0x4ac +#define SDRAM_CROSS_BAR_TIMEOUT 0x4b0 + + +/* + * SDRAM Parameters + */ + +#define SDRAM_BANK0PARAMETERS 0x44C +#define SDRAM_BANK1PARAMETERS 0x450 +#define SDRAM_BANK2PARAMETERS 0x454 +#define SDRAM_BANK3PARAMETERS 0x458 + + +/* + * SDRAM Error Report + */ + +#define SDRAM_ERROR_DATA_LOW 0x484 +#define SDRAM_ERROR_DATA_HIGH 0x480 +#define SDRAM_AND_DEVICE_ERROR_ADDRESS 0x490 +#define SDRAM_RECEIVED_ECC 0x488 +#define SDRAM_CALCULATED_ECC 0x48c +#define SDRAM_ECC_CONTROL 0x494 +#define SDRAM_ECC_ERROR_COUNTER 0x498 + + +/* + * SDunit Debug (for internal use) + */ + +#define X0_ADDRESS 0x500 +#define X0_COMMAND_AND_ID 0x504 +#define X0_WRITE_DATA_LOW 0x508 +#define X0_WRITE_DATA_HIGH 0x50c +#define X0_WRITE_BYTE_ENABLE 0x518 +#define X0_READ_DATA_LOW 0x510 +#define X0_READ_DATA_HIGH 0x514 +#define X0_READ_ID 0x51c +#define X1_ADDRESS 0x520 +#define X1_COMMAND_AND_ID 0x524 +#define X1_WRITE_DATA_LOW 0x528 +#define X1_WRITE_DATA_HIGH 0x52c +#define X1_WRITE_BYTE_ENABLE 0x538 +#define X1_READ_DATA_LOW 0x530 +#define X1_READ_DATA_HIGH 0x534 +#define X1_READ_ID 0x53c +#define X0_SNOOP_ADDRESS 0x540 +#define X0_SNOOP_COMMAND 0x544 +#define X1_SNOOP_ADDRESS 0x548 +#define X1_SNOOP_COMMAND 0x54c + + +/* + * Device Parameters + */ + +#define DEVICE_BANK0PARAMETERS 0x45c +#define DEVICE_BANK1PARAMETERS 0x460 +#define DEVICE_BANK2PARAMETERS 0x464 +#define DEVICE_BANK3PARAMETERS 0x468 +#define DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define DEVICE_CONTROL 0x4c0 +#define DEVICE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define DEVICE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define DEVICE_CROSS_BAR_TIMEOUT 0x4c4 + + +/* + * Device Interrupt + */ + +#define DEVICE_INTERRUPT_CAUSE 0x4d0 +#define DEVICE_INTERRUPT_MASK 0x4d4 +#define DEVICE_ERROR_ADDRESS 0x4d8 + +/* + * DMA Record + */ + +#define CHANNEL0_DMA_BYTE_COUNT 0x800 +#define CHANNEL1_DMA_BYTE_COUNT 0x804 +#define CHANNEL2_DMA_BYTE_COUNT 0x808 +#define CHANNEL3_DMA_BYTE_COUNT 0x80C +#define CHANNEL4_DMA_BYTE_COUNT 0x900 +#define CHANNEL5_DMA_BYTE_COUNT 0x904 +#define CHANNEL6_DMA_BYTE_COUNT 0x908 +#define CHANNEL7_DMA_BYTE_COUNT 0x90C +#define CHANNEL0_DMA_SOURCE_ADDRESS 0x810 +#define CHANNEL1_DMA_SOURCE_ADDRESS 0x814 +#define CHANNEL2_DMA_SOURCE_ADDRESS 0x818 +#define CHANNEL3_DMA_SOURCE_ADDRESS 0x81C +#define CHANNEL4_DMA_SOURCE_ADDRESS 0x910 +#define CHANNEL5_DMA_SOURCE_ADDRESS 0x914 +#define CHANNEL6_DMA_SOURCE_ADDRESS 0x918 +#define CHANNEL7_DMA_SOURCE_ADDRESS 0x91C +#define CHANNEL0_DMA_DESTINATION_ADDRESS 0x820 +#define CHANNEL1_DMA_DESTINATION_ADDRESS 0x824 +#define CHANNEL2_DMA_DESTINATION_ADDRESS 0x828 +#define CHANNEL3_DMA_DESTINATION_ADDRESS 0x82C +#define CHANNEL4_DMA_DESTINATION_ADDRESS 0x920 +#define CHANNEL5_DMA_DESTINATION_ADDRESS 0x924 +#define CHANNEL6_DMA_DESTINATION_ADDRESS 0x928 +#define CHANNEL7_DMA_DESTINATION_ADDRESS 0x92C +#define CHANNEL0NEXT_RECORD_POINTER 0x830 +#define CHANNEL1NEXT_RECORD_POINTER 0x834 +#define CHANNEL2NEXT_RECORD_POINTER 0x838 +#define CHANNEL3NEXT_RECORD_POINTER 0x83C +#define CHANNEL4NEXT_RECORD_POINTER 0x930 +#define CHANNEL5NEXT_RECORD_POINTER 0x934 +#define CHANNEL6NEXT_RECORD_POINTER 0x938 +#define CHANNEL7NEXT_RECORD_POINTER 0x93C +#define CHANNEL0CURRENT_DESCRIPTOR_POINTER 0x870 +#define CHANNEL1CURRENT_DESCRIPTOR_POINTER 0x874 +#define CHANNEL2CURRENT_DESCRIPTOR_POINTER 0x878 +#define CHANNEL3CURRENT_DESCRIPTOR_POINTER 0x87C +#define CHANNEL4CURRENT_DESCRIPTOR_POINTER 0x970 +#define CHANNEL5CURRENT_DESCRIPTOR_POINTER 0x974 +#define CHANNEL6CURRENT_DESCRIPTOR_POINTER 0x978 +#define CHANNEL7CURRENT_DESCRIPTOR_POINTER 0x97C +#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS 0x890 +#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS 0x894 +#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS 0x898 +#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS 0x89c +#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS 0x990 +#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS 0x994 +#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS 0x998 +#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS 0x99c +#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a0 +#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a4 +#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a8 +#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8ac +#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a0 +#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a4 +#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a8 +#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9ac +#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b0 +#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b4 +#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b8 +#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8bc +#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b0 +#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b4 +#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b8 +#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9bc + +/* + * DMA Channel Control + */ + +#define CHANNEL0CONTROL 0x840 +#define CHANNEL0CONTROL_HIGH 0x880 + +#define CHANNEL1CONTROL 0x844 +#define CHANNEL1CONTROL_HIGH 0x884 + +#define CHANNEL2CONTROL 0x848 +#define CHANNEL2CONTROL_HIGH 0x888 + +#define CHANNEL3CONTROL 0x84C +#define CHANNEL3CONTROL_HIGH 0x88C + +#define CHANNEL4CONTROL 0x940 +#define CHANNEL4CONTROL_HIGH 0x980 + +#define CHANNEL5CONTROL 0x944 +#define CHANNEL5CONTROL_HIGH 0x984 + +#define CHANNEL6CONTROL 0x948 +#define CHANNEL6CONTROL_HIGH 0x988 + +#define CHANNEL7CONTROL 0x94C +#define CHANNEL7CONTROL_HIGH 0x98C + + +/* + * DMA Arbiter + */ + +#define ARBITER_CONTROL_0_3 0x860 +#define ARBITER_CONTROL_4_7 0x960 + + +/* + * DMA Interrupt + */ + +#define CHANELS0_3_INTERRUPT_CAUSE 0x8c0 +#define CHANELS0_3_INTERRUPT_MASK 0x8c4 +#define CHANELS0_3_ERROR_ADDRESS 0x8c8 +#define CHANELS0_3_ERROR_SELECT 0x8cc +#define CHANELS4_7_INTERRUPT_CAUSE 0x9c0 +#define CHANELS4_7_INTERRUPT_MASK 0x9c4 +#define CHANELS4_7_ERROR_ADDRESS 0x9c8 +#define CHANELS4_7_ERROR_SELECT 0x9cc + + +/* + * DMA Debug (for internal use) + */ + +#define DMA_X0_ADDRESS 0x8e0 +#define DMA_X0_COMMAND_AND_ID 0x8e4 +#define DMA_X0_WRITE_DATA_LOW 0x8e8 +#define DMA_X0_WRITE_DATA_HIGH 0x8ec +#define DMA_X0_WRITE_BYTE_ENABLE 0x8f8 +#define DMA_X0_READ_DATA_LOW 0x8f0 +#define DMA_X0_READ_DATA_HIGH 0x8f4 +#define DMA_X0_READ_ID 0x8fc +#define DMA_X1_ADDRESS 0x9e0 +#define DMA_X1_COMMAND_AND_ID 0x9e4 +#define DMA_X1_WRITE_DATA_LOW 0x9e8 +#define DMA_X1_WRITE_DATA_HIGH 0x9ec +#define DMA_X1_WRITE_BYTE_ENABLE 0x9f8 +#define DMA_X1_READ_DATA_LOW 0x9f0 +#define DMA_X1_READ_DATA_HIGH 0x9f4 +#define DMA_X1_READ_ID 0x9fc + +/* + * Timer_Counter + */ + +#define TIMER_COUNTER0 0x850 +#define TIMER_COUNTER1 0x854 +#define TIMER_COUNTER2 0x858 +#define TIMER_COUNTER3 0x85C +#define TIMER_COUNTER_0_3_CONTROL 0x864 +#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c +#define TIMER_COUNTER4 0x950 +#define TIMER_COUNTER5 0x954 +#define TIMER_COUNTER6 0x958 +#define TIMER_COUNTER7 0x95C +#define TIMER_COUNTER_4_7_CONTROL 0x964 +#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE 0x968 +#define TIMER_COUNTER_4_7_INTERRUPT_MASK 0x96c + +/* + * PCI Slave Address Decoding + */ + +#define PCI_0SCS_0_BANK_SIZE 0xc08 +#define PCI_1SCS_0_BANK_SIZE 0xc88 +#define PCI_0SCS_1_BANK_SIZE 0xd08 +#define PCI_1SCS_1_BANK_SIZE 0xd88 +#define PCI_0SCS_2_BANK_SIZE 0xc0c +#define PCI_1SCS_2_BANK_SIZE 0xc8c +#define PCI_0SCS_3_BANK_SIZE 0xd0c +#define PCI_1SCS_3_BANK_SIZE 0xd8c +#define PCI_0CS_0_BANK_SIZE 0xc10 +#define PCI_1CS_0_BANK_SIZE 0xc90 +#define PCI_0CS_1_BANK_SIZE 0xd10 +#define PCI_1CS_1_BANK_SIZE 0xd90 +#define PCI_0CS_2_BANK_SIZE 0xd18 +#define PCI_1CS_2_BANK_SIZE 0xd98 +#define PCI_0CS_3_BANK_SIZE 0xc14 +#define PCI_1CS_3_BANK_SIZE 0xc94 +#define PCI_0CS_BOOT_BANK_SIZE 0xd14 +#define PCI_1CS_BOOT_BANK_SIZE 0xd94 +#define PCI_0P2P_MEM0_BAR_SIZE 0xd1c +#define PCI_1P2P_MEM0_BAR_SIZE 0xd9c +#define PCI_0P2P_MEM1_BAR_SIZE 0xd20 +#define PCI_1P2P_MEM1_BAR_SIZE 0xda0 +#define PCI_0P2P_I_O_BAR_SIZE 0xd24 +#define PCI_1P2P_I_O_BAR_SIZE 0xda4 +#define PCI_0CPU_BAR_SIZE 0xd28 +#define PCI_1CPU_BAR_SIZE 0xda8 +#define PCI_0DAC_SCS_0_BANK_SIZE 0xe00 +#define PCI_1DAC_SCS_0_BANK_SIZE 0xe80 +#define PCI_0DAC_SCS_1_BANK_SIZE 0xe04 +#define PCI_1DAC_SCS_1_BANK_SIZE 0xe84 +#define PCI_0DAC_SCS_2_BANK_SIZE 0xe08 +#define PCI_1DAC_SCS_2_BANK_SIZE 0xe88 +#define PCI_0DAC_SCS_3_BANK_SIZE 0xe0c +#define PCI_1DAC_SCS_3_BANK_SIZE 0xe8c +#define PCI_0DAC_CS_0_BANK_SIZE 0xe10 +#define PCI_1DAC_CS_0_BANK_SIZE 0xe90 +#define PCI_0DAC_CS_1_BANK_SIZE 0xe14 +#define PCI_1DAC_CS_1_BANK_SIZE 0xe94 +#define PCI_0DAC_CS_2_BANK_SIZE 0xe18 +#define PCI_1DAC_CS_2_BANK_SIZE 0xe98 +#define PCI_0DAC_CS_3_BANK_SIZE 0xe1c +#define PCI_1DAC_CS_3_BANK_SIZE 0xe9c +#define PCI_0DAC_BOOTCS_BANK_SIZE 0xe20 +#define PCI_1DAC_BOOTCS_BANK_SIZE 0xea0 +#define PCI_0DAC_P2P_MEM0_BAR_SIZE 0xe24 +#define PCI_1DAC_P2P_MEM0_BAR_SIZE 0xea4 +#define PCI_0DAC_P2P_MEM1_BAR_SIZE 0xe28 +#define PCI_1DAC_P2P_MEM1_BAR_SIZE 0xea8 +#define PCI_0DAC_CPU_BAR_SIZE 0xe2c +#define PCI_1DAC_CPU_BAR_SIZE 0xeac +#define PCI_0EXPANSION_ROM_BAR_SIZE 0xd2c +#define PCI_1EXPANSION_ROM_BAR_SIZE 0xdac +#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 0xc3c +#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 0xcbc +#define PCI_0SCS_0_BASE_ADDRESS_REMAP 0xc48 +#define PCI_1SCS_0_BASE_ADDRESS_REMAP 0xcc8 +#define PCI_0SCS_1_BASE_ADDRESS_REMAP 0xd48 +#define PCI_1SCS_1_BASE_ADDRESS_REMAP 0xdc8 +#define PCI_0SCS_2_BASE_ADDRESS_REMAP 0xc4c +#define PCI_1SCS_2_BASE_ADDRESS_REMAP 0xccc +#define PCI_0SCS_3_BASE_ADDRESS_REMAP 0xd4c +#define PCI_1SCS_3_BASE_ADDRESS_REMAP 0xdcc +#define PCI_0CS_0_BASE_ADDRESS_REMAP 0xc50 +#define PCI_1CS_0_BASE_ADDRESS_REMAP 0xcd0 +#define PCI_0CS_1_BASE_ADDRESS_REMAP 0xd50 +#define PCI_1CS_1_BASE_ADDRESS_REMAP 0xdd0 +#define PCI_0CS_2_BASE_ADDRESS_REMAP 0xd58 +#define PCI_1CS_2_BASE_ADDRESS_REMAP 0xdd8 +#define PCI_0CS_3_BASE_ADDRESS_REMAP 0xc54 +#define PCI_1CS_3_BASE_ADDRESS_REMAP 0xcd4 +#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP 0xd54 +#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP 0xdd4 +#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xd5c +#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xddc +#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xd60 +#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xde0 +#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xd64 +#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xde4 +#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xd68 +#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xde8 +#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP 0xd6c +#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP 0xdec +#define PCI_0CPU_BASE_ADDRESS_REMAP 0xd70 +#define PCI_1CPU_BASE_ADDRESS_REMAP 0xdf0 +#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP 0xf00 +#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP 0xff0 +#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP 0xf04 +#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP 0xf84 +#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP 0xf08 +#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP 0xf88 +#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP 0xf0c +#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP 0xf8c +#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP 0xf10 +#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP 0xf90 +#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP 0xf14 +#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP 0xf94 +#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP 0xf18 +#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP 0xf98 +#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP 0xf1c +#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP 0xf9c +#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP 0xf20 +#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP 0xfa0 +#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xf24 +#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xfa4 +#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xf28 +#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xfa8 +#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xf2c +#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xfac +#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xf30 +#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xfb0 +#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP 0xf34 +#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP 0xfb4 +#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP 0xf38 +#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP 0xfb8 +#define PCI_0ADDRESS_DECODE_CONTROL 0xd3c +#define PCI_1ADDRESS_DECODE_CONTROL 0xdbc + +/* + * PCI Control + */ + +#define PCI_0COMMAND 0xc00 +#define PCI_1COMMAND 0xc80 +#define PCI_0MODE 0xd00 +#define PCI_1MODE 0xd80 +#define PCI_0TIMEOUT_RETRY 0xc04 +#define PCI_1TIMEOUT_RETRY 0xc84 +#define PCI_0READ_BUFFER_DISCARD_TIMER 0xd04 +#define PCI_1READ_BUFFER_DISCARD_TIMER 0xd84 +#define MSI_0TRIGGER_TIMER 0xc38 +#define MSI_1TRIGGER_TIMER 0xcb8 +#define PCI_0ARBITER_CONTROL 0x1d00 +#define PCI_1ARBITER_CONTROL 0x1d80 +/* changing untill here */ +#define PCI_0CROSS_BAR_CONTROL_LOW 0x1d08 +#define PCI_0CROSS_BAR_CONTROL_HIGH 0x1d0c +#define PCI_0CROSS_BAR_TIMEOUT 0x1d04 +#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d18 +#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d1c +#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER 0x1d10 +#define PCI_0P2P_CONFIGURATION 0x1d14 +#define PCI_0ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define PCI_0ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define PCI_0ACCESS_CONTROL_TOP_0 0x1e08 +#define PCI_0ACCESS_CONTROL_BASE_1_LOW 0c1e10 +#define PCI_0ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define PCI_0ACCESS_CONTROL_TOP_1 0x1e18 +#define PCI_0ACCESS_CONTROL_BASE_2_LOW 0c1e20 +#define PCI_0ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define PCI_0ACCESS_CONTROL_TOP_2 0x1e28 +#define PCI_0ACCESS_CONTROL_BASE_3_LOW 0c1e30 +#define PCI_0ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define PCI_0ACCESS_CONTROL_TOP_3 0x1e38 +#define PCI_0ACCESS_CONTROL_BASE_4_LOW 0c1e40 +#define PCI_0ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define PCI_0ACCESS_CONTROL_TOP_4 0x1e48 +#define PCI_0ACCESS_CONTROL_BASE_5_LOW 0c1e50 +#define PCI_0ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define PCI_0ACCESS_CONTROL_TOP_5 0x1e58 +#define PCI_0ACCESS_CONTROL_BASE_6_LOW 0c1e60 +#define PCI_0ACCESS_CONTROL_BASE_6_HIGH 0x1e64 +#define PCI_0ACCESS_CONTROL_TOP_6 0x1e68 +#define PCI_0ACCESS_CONTROL_BASE_7_LOW 0c1e70 +#define PCI_0ACCESS_CONTROL_BASE_7_HIGH 0x1e74 +#define PCI_0ACCESS_CONTROL_TOP_7 0x1e78 +#define PCI_1CROSS_BAR_CONTROL_LOW 0x1d88 +#define PCI_1CROSS_BAR_CONTROL_HIGH 0x1d8c +#define PCI_1CROSS_BAR_TIMEOUT 0x1d84 +#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d98 +#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d9c +#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER 0x1d90 +#define PCI_1P2P_CONFIGURATION 0x1d94 +#define PCI_1ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define PCI_1ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define PCI_1ACCESS_CONTROL_TOP_0 0x1e88 +#define PCI_1ACCESS_CONTROL_BASE_1_LOW 0c1e90 +#define PCI_1ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define PCI_1ACCESS_CONTROL_TOP_1 0x1e98 +#define PCI_1ACCESS_CONTROL_BASE_2_LOW 0c1ea0 +#define PCI_1ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define PCI_1ACCESS_CONTROL_TOP_2 0x1ea8 +#define PCI_1ACCESS_CONTROL_BASE_3_LOW 0c1eb0 +#define PCI_1ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define PCI_1ACCESS_CONTROL_TOP_3 0x1eb8 +#define PCI_1ACCESS_CONTROL_BASE_4_LOW 0c1ec0 +#define PCI_1ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define PCI_1ACCESS_CONTROL_TOP_4 0x1ec8 +#define PCI_1ACCESS_CONTROL_BASE_5_LOW 0c1ed0 +#define PCI_1ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define PCI_1ACCESS_CONTROL_TOP_5 0x1ed8 +#define PCI_1ACCESS_CONTROL_BASE_6_LOW 0c1ee0 +#define PCI_1ACCESS_CONTROL_BASE_6_HIGH 0x1ee4 +#define PCI_1ACCESS_CONTROL_TOP_6 0x1ee8 +#define PCI_1ACCESS_CONTROL_BASE_7_LOW 0c1ef0 +#define PCI_1ACCESS_CONTROL_BASE_7_HIGH 0x1ef4 +#define PCI_1ACCESS_CONTROL_TOP_7 0x1ef8 + +/* + * PCI Snoop Control + */ + +#define PCI_0SNOOP_CONTROL_BASE_0_LOW 0x1f00 +#define PCI_0SNOOP_CONTROL_BASE_0_HIGH 0x1f04 +#define PCI_0SNOOP_CONTROL_TOP_0 0x1f08 +#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW 0x1f10 +#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH 0x1f14 +#define PCI_0SNOOP_CONTROL_TOP_1 0x1f18 +#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW 0x1f20 +#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH 0x1f24 +#define PCI_0SNOOP_CONTROL_TOP_2 0x1f28 +#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW 0x1f30 +#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH 0x1f34 +#define PCI_0SNOOP_CONTROL_TOP_3 0x1f38 +#define PCI_1SNOOP_CONTROL_BASE_0_LOW 0x1f80 +#define PCI_1SNOOP_CONTROL_BASE_0_HIGH 0x1f84 +#define PCI_1SNOOP_CONTROL_TOP_0 0x1f88 +#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW 0x1f90 +#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH 0x1f94 +#define PCI_1SNOOP_CONTROL_TOP_1 0x1f98 +#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW 0x1fa0 +#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH 0x1fa4 +#define PCI_1SNOOP_CONTROL_TOP_2 0x1fa8 +#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW 0x1fb0 +#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH 0x1fb4 +#define PCI_1SNOOP_CONTROL_TOP_3 0x1fb8 + +/* + * PCI Configuration Address + */ + +#define PCI_0CONFIGURATION_ADDRESS 0xcf8 +#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER 0xcfc +#define PCI_1CONFIGURATION_ADDRESS 0xc78 +#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 0xc7c +#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xc34 +#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xcb4 + +/* + * PCI Error Report + */ + +#define PCI_0SERR_MASK 0xc28 +#define PCI_0ERROR_ADDRESS_LOW 0x1d40 +#define PCI_0ERROR_ADDRESS_HIGH 0x1d44 +#define PCI_0ERROR_DATA_LOW 0x1d48 +#define PCI_0ERROR_DATA_HIGH 0x1d4c +#define PCI_0ERROR_COMMAND 0x1d50 +#define PCI_0ERROR_CAUSE 0x1d58 +#define PCI_0ERROR_MASK 0x1d5c + +#define PCI_1SERR_MASK 0xca8 +#define PCI_1ERROR_ADDRESS_LOW 0x1dc0 +#define PCI_1ERROR_ADDRESS_HIGH 0x1dc4 +#define PCI_1ERROR_DATA_LOW 0x1dc8 +#define PCI_1ERROR_DATA_HIGH 0x1dcc +#define PCI_1ERROR_COMMAND 0x1dd0 +#define PCI_1ERROR_CAUSE 0x1dd8 +#define PCI_1ERROR_MASK 0x1ddc + + +/* + * Lslave Debug (for internal use) + */ + +#define L_SLAVE_X0_ADDRESS 0x1d20 +#define L_SLAVE_X0_COMMAND_AND_ID 0x1d24 +#define L_SLAVE_X1_ADDRESS 0x1d28 +#define L_SLAVE_X1_COMMAND_AND_ID 0x1d2c +#define L_SLAVE_WRITE_DATA_LOW 0x1d30 +#define L_SLAVE_WRITE_DATA_HIGH 0x1d34 +#define L_SLAVE_WRITE_BYTE_ENABLE 0x1d60 +#define L_SLAVE_READ_DATA_LOW 0x1d38 +#define L_SLAVE_READ_DATA_HIGH 0x1d3c +#define L_SLAVE_READ_ID 0x1d64 + +#if 0 /* Disabled because PCI_* namespace belongs to PCI subsystem ... */ + +/* + * PCI Configuration Function 0 + */ + +#define PCI_DEVICE_AND_VENDOR_ID 0x000 +#define PCI_STATUS_AND_COMMAND 0x004 +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C +#define PCI_SCS_0_BASE_ADDRESS 0x010 +#define PCI_SCS_1_BASE_ADDRESS 0x014 +#define PCI_SCS_2_BASE_ADDRESS 0x018 +#define PCI_SCS_3_BASE_ADDRESS 0x01C +#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS 0x020 +#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS 0x024 +#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02C +#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER 0x030 +#define PCI_CAPABILTY_LIST_POINTER 0x034 +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C +#define PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define PCI_VPD_ADDRESS 0x048 +#define PCI_VPD_DATA 0X04c +#define PCI_MSI_MESSAGE_CONTROL 0x050 +#define PCI_MSI_MESSAGE_ADDRESS 0x054 +#define PCI_MSI_MESSAGE_UPPER_ADDRESS 0x058 +#define PCI_MSI_MESSAGE_DATA 0x05c +#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY 0x058 + +/* + * PCI Configuration Function 1 + */ + +#define PCI_CS_0_BASE_ADDRESS 0x110 +#define PCI_CS_1_BASE_ADDRESS 0x114 +#define PCI_CS_2_BASE_ADDRESS 0x118 +#define PCI_CS_3_BASE_ADDRESS 0x11c +#define PCI_BOOTCS_BASE_ADDRESS 0x120 + +/* + * PCI Configuration Function 2 + */ + +#define PCI_P2P_MEM0_BASE_ADDRESS 0x210 +#define PCI_P2P_MEM1_BASE_ADDRESS 0x214 +#define PCI_P2P_I_O_BASE_ADDRESS 0x218 +#define PCI_CPU_BASE_ADDRESS 0x21c + +/* + * PCI Configuration Function 4 + */ + +#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 0x410 +#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH 0x414 +#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW 0x418 +#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH 0x41c +#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW 0x420 +#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH 0x424 + + +/* + * PCI Configuration Function 5 + */ + +#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 0x510 +#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH 0x514 +#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW 0x518 +#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH 0x51c +#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW 0x520 +#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH 0x524 + + +/* + * PCI Configuration Function 6 + */ + +#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 0x610 +#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH 0x614 +#define PCI_DAC_CS_1_BASE_ADDRESS_LOW 0x618 +#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH 0x61c +#define PCI_DAC_CS_2_BASE_ADDRESS_LOW 0x620 +#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH 0x624 + +/* + * PCI Configuration Function 7 + */ + +#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 0x710 +#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH 0x714 +#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW 0x718 +#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH 0x71c +#define PCI_DAC_CPU_BASE_ADDRESS_LOW 0x720 +#define PCI_DAC_CPU_BASE_ADDRESS_HIGH 0x724 +#endif + +/* + * Interrupts + */ + +#define LOW_INTERRUPT_CAUSE_REGISTER 0xc18 +#define HIGH_INTERRUPT_CAUSE_REGISTER 0xc68 +#define CPU_INTERRUPT_MASK_REGISTER_LOW 0xc1c +#define CPU_INTERRUPT_MASK_REGISTER_HIGH 0xc6c +#define CPU_SELECT_CAUSE_REGISTER 0xc70 +#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xc24 +#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xc64 +#define PCI_0SELECT_CAUSE 0xc74 +#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xca4 +#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xce4 +#define PCI_1SELECT_CAUSE 0xcf4 +#define CPU_INT_0_MASK 0xe60 +#define CPU_INT_1_MASK 0xe64 +#define CPU_INT_2_MASK 0xe68 +#define CPU_INT_3_MASK 0xe6c + +/* + * I20 Support registers + */ + +#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x010 +#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x014 +#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x018 +#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x01C +#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x020 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x024 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x028 +#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x02C +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x030 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x034 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x040 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x044 +#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 0x050 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 0x054 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x060 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x064 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x068 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x06C +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x070 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x074 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x0F8 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x0FC + +#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x090 +#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x094 +#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x098 +#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x09C +#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0A0 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0A4 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0A8 +#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0AC +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0B0 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0B4 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C0 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C4 +#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 0x0D0 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 0x0D4 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E0 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0E4 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E8 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0EC +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0F0 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0F4 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x078 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x07C + +#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C10 +#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C14 +#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C18 +#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C1C +#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C20 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C24 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C28 +#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C2C +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C30 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C34 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C40 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C44 +#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 0X1C50 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 0X1C54 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C60 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C64 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C68 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C6C +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C70 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C74 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1CF8 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1CFC + +#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C90 +#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C94 +#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C98 +#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C9C +#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CA0 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CA4 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CA8 +#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CAC +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CB0 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CB4 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC0 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC4 +#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 0X1CD0 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 0X1CD4 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE0 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CE4 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE8 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CEC +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CF0 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CF4 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1C78 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1C7C + +/* + * Communication Unit Registers + */ + +#define ETHERNET_0_ADDRESS_CONTROL_LOW +#define ETHERNET_0_ADDRESS_CONTROL_HIGH 0xf204 +#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf208 +#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf20c +#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf210 +#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf214 +#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS 0xf218 +#define ETHERNET_1_ADDRESS_CONTROL_LOW 0xf220 +#define ETHERNET_1_ADDRESS_CONTROL_HIGH 0xf224 +#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf228 +#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf22c +#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf230 +#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf234 +#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS 0xf238 +#define ETHERNET_2_ADDRESS_CONTROL_LOW 0xf240 +#define ETHERNET_2_ADDRESS_CONTROL_HIGH 0xf244 +#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf248 +#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf24c +#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf250 +#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf254 +#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS 0xf258 +#define MPSC_0_ADDRESS_CONTROL_LOW 0xf280 +#define MPSC_0_ADDRESS_CONTROL_HIGH 0xf284 +#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf288 +#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf28c +#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf290 +#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf294 +#define MPSC_1_ADDRESS_CONTROL_LOW 0xf2a0 +#define MPSC_1_ADDRESS_CONTROL_HIGH 0xf2a4 +#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2a8 +#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2ac +#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b0 +#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b4 +#define MPSC_2_ADDRESS_CONTROL_LOW 0xf2c0 +#define MPSC_2_ADDRESS_CONTROL_HIGH 0xf2c4 +#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2c8 +#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2cc +#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d0 +#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d4 +#define SERIAL_INIT_PCI_HIGH_ADDRESS 0xf320 +#define SERIAL_INIT_LAST_DATA 0xf324 +#define SERIAL_INIT_STATUS_AND_CONTROL 0xf328 +#define COMM_UNIT_ARBITER_CONTROL 0xf300 +#define COMM_UNIT_CROSS_BAR_TIMEOUT 0xf304 +#define COMM_UNIT_INTERRUPT_CAUSE 0xf310 +#define COMM_UNIT_INTERRUPT_MASK 0xf314 +#define COMM_UNIT_ERROR_ADDRESS 0xf314 + +/* + * Cunit Debug (for internal use) + */ + +#define CUNIT_ADDRESS 0xf340 +#define CUNIT_COMMAND_AND_ID 0xf344 +#define CUNIT_WRITE_DATA_LOW 0xf348 +#define CUNIT_WRITE_DATA_HIGH 0xf34c +#define CUNIT_WRITE_BYTE_ENABLE 0xf358 +#define CUNIT_READ_DATA_LOW 0xf350 +#define CUNIT_READ_DATA_HIGH 0xf354 +#define CUNIT_READ_ID 0xf35c + +/* + * Fast Ethernet Unit Registers + */ + +/* Ethernet */ + +#define ETHERNET_PHY_ADDRESS_REGISTER 0x2000 +#define ETHERNET_SMI_REGISTER 0x2010 + +/* Ethernet 0 */ + +#define ETHERNET0_PORT_CONFIGURATION_REGISTER 0x2400 +#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER 0x2408 +#define ETHERNET0_PORT_COMMAND_REGISTER 0x2410 +#define ETHERNET0_PORT_STATUS_REGISTER 0x2418 +#define ETHERNET0_SERIAL_PARAMETRS_REGISTER 0x2420 +#define ETHERNET0_HASH_TABLE_POINTER_REGISTER 0x2428 +#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2430 +#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2438 +#define ETHERNET0_SDMA_CONFIGURATION_REGISTER 0x2440 +#define ETHERNET0_SDMA_COMMAND_REGISTER 0x2448 +#define ETHERNET0_INTERRUPT_CAUSE_REGISTER 0x2450 +#define ETHERNET0_INTERRUPT_MASK_REGISTER 0x2458 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 0x2480 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1 0x2484 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2 0x2488 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3 0x248c +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 0x24a0 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1 0x24a4 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2 0x24a8 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3 0x24ac +#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 0x24e0 +#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 0x24e4 +#define ETHERNET0_MIB_COUNTER_BASE 0x2500 + +/* Ethernet 1 */ + +#define ETHERNET1_PORT_CONFIGURATION_REGISTER 0x2800 +#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER 0x2808 +#define ETHERNET1_PORT_COMMAND_REGISTER 0x2810 +#define ETHERNET1_PORT_STATUS_REGISTER 0x2818 +#define ETHERNET1_SERIAL_PARAMETRS_REGISTER 0x2820 +#define ETHERNET1_HASH_TABLE_POINTER_REGISTER 0x2828 +#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2830 +#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2838 +#define ETHERNET1_SDMA_CONFIGURATION_REGISTER 0x2840 +#define ETHERNET1_SDMA_COMMAND_REGISTER 0x2848 +#define ETHERNET1_INTERRUPT_CAUSE_REGISTER 0x2850 +#define ETHERNET1_INTERRUPT_MASK_REGISTER 0x2858 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0 0x2880 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1 0x2884 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2 0x2888 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3 0x288c +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0 0x28a0 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1 0x28a4 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2 0x28a8 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3 0x28ac +#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0 0x28e0 +#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1 0x28e4 +#define ETHERNET1_MIB_COUNTER_BASE 0x2900 + +/* Ethernet 2 */ + +#define ETHERNET2_PORT_CONFIGURATION_REGISTER 0x2c00 +#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER 0x2c08 +#define ETHERNET2_PORT_COMMAND_REGISTER 0x2c10 +#define ETHERNET2_PORT_STATUS_REGISTER 0x2c18 +#define ETHERNET2_SERIAL_PARAMETRS_REGISTER 0x2c20 +#define ETHERNET2_HASH_TABLE_POINTER_REGISTER 0x2c28 +#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2c30 +#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2c38 +#define ETHERNET2_SDMA_CONFIGURATION_REGISTER 0x2c40 +#define ETHERNET2_SDMA_COMMAND_REGISTER 0x2c48 +#define ETHERNET2_INTERRUPT_CAUSE_REGISTER 0x2c50 +#define ETHERNET2_INTERRUPT_MASK_REGISTER 0x2c58 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0 0x2c80 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1 0x2c84 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2 0x2c88 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3 0x2c8c +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0 0x2ca0 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1 0x2ca4 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2 0x2ca8 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3 0x2cac +#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0 0x2ce0 +#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1 0x2ce4 +#define ETHERNET2_MIB_COUNTER_BASE 0x2d00 + +/* + * SDMA Registers + */ + +#define SDMA_GROUP_CONFIGURATION_REGISTER 0xb1f0 +#define CHANNEL0_CONFIGURATION_REGISTER 0x4000 +#define CHANNEL0_COMMAND_REGISTER 0x4008 +#define CHANNEL0_RX_CMD_STATUS 0x4800 +#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES 0x4804 +#define CHANNEL0_RX_BUFFER_POINTER 0x4808 +#define CHANNEL0_RX_NEXT_POINTER 0x480c +#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER 0x4810 +#define CHANNEL0_TX_CMD_STATUS 0x4C00 +#define CHANNEL0_TX_PACKET_SIZE 0x4C04 +#define CHANNEL0_TX_BUFFER_POINTER 0x4C08 +#define CHANNEL0_TX_NEXT_POINTER 0x4C0c +#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER 0x4c10 +#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER 0x4c14 +#define CHANNEL1_CONFIGURATION_REGISTER 0x6000 +#define CHANNEL1_COMMAND_REGISTER 0x6008 +#define CHANNEL1_RX_CMD_STATUS 0x6800 +#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES 0x6804 +#define CHANNEL1_RX_BUFFER_POINTER 0x6808 +#define CHANNEL1_RX_NEXT_POINTER 0x680c +#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 +#define CHANNEL1_TX_CMD_STATUS 0x6C00 +#define CHANNEL1_TX_PACKET_SIZE 0x6C04 +#define CHANNEL1_TX_BUFFER_POINTER 0x6C08 +#define CHANNEL1_TX_NEXT_POINTER 0x6C0c +#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 +#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER 0x6c10 +#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER 0x6c14 + +/* SDMA Interrupt */ + +#define SDMA_CAUSE 0xb820 +#define SDMA_MASK 0xb8a0 + + +/* + * Baude Rate Generators Registers + */ + +/* BRG 0 */ + +#define BRG0_CONFIGURATION_REGISTER 0xb200 +#define BRG0_BAUDE_TUNING_REGISTER 0xb204 + +/* BRG 1 */ + +#define BRG1_CONFIGURATION_REGISTER 0xb208 +#define BRG1_BAUDE_TUNING_REGISTER 0xb20c + +/* BRG 2 */ + +#define BRG2_CONFIGURATION_REGISTER 0xb210 +#define BRG2_BAUDE_TUNING_REGISTER 0xb214 + +/* BRG Interrupts */ + +#define BRG_CAUSE_REGISTER 0xb834 +#define BRG_MASK_REGISTER 0xb8b4 + +/* MISC */ + +#define MAIN_ROUTING_REGISTER 0xb400 +#define RECEIVE_CLOCK_ROUTING_REGISTER 0xb404 +#define TRANSMIT_CLOCK_ROUTING_REGISTER 0xb408 +#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER 0xb40c +#define WATCHDOG_CONFIGURATION_REGISTER 0xb410 +#define WATCHDOG_VALUE_REGISTER 0xb414 + + +/* + * Flex TDM Registers + */ + +/* FTDM Port */ + +#define FLEXTDM_TRANSMIT_READ_POINTER 0xa800 +#define FLEXTDM_RECEIVE_READ_POINTER 0xa804 +#define FLEXTDM_CONFIGURATION_REGISTER 0xa808 +#define FLEXTDM_AUX_CHANNELA_TX_REGISTER 0xa80c +#define FLEXTDM_AUX_CHANNELA_RX_REGISTER 0xa810 +#define FLEXTDM_AUX_CHANNELB_TX_REGISTER 0xa814 +#define FLEXTDM_AUX_CHANNELB_RX_REGISTER 0xa818 + +/* FTDM Interrupts */ + +#define FTDM_CAUSE_REGISTER 0xb830 +#define FTDM_MASK_REGISTER 0xb8b0 + + +/* + * GPP Interface Registers + */ + +#define GPP_IO_CONTROL 0xf100 +#define GPP_LEVEL_CONTROL 0xf110 +#define GPP_VALUE 0xf104 +#define GPP_INTERRUPT_CAUSE 0xf108 +#define GPP_INTERRUPT_MASK 0xf10c + +#define MPP_CONTROL0 0xf000 +#define MPP_CONTROL1 0xf004 +#define MPP_CONTROL2 0xf008 +#define MPP_CONTROL3 0xf00c +#define DEBUG_PORT_MULTIPLEX 0xf014 +#define SERIAL_PORT_MULTIPLEX 0xf010 + +/* + * I2C Registers + */ + +#define I2C_SLAVE_ADDRESS 0xc000 +#define I2C_EXTENDED_SLAVE_ADDRESS 0xc040 +#define I2C_DATA 0xc004 +#define I2C_CONTROL 0xc008 +#define I2C_STATUS_BAUDE_RATE 0xc00C +#define I2C_SOFT_RESET 0xc01c + +/* + * MPSC Registers + */ + +/* + * MPSC0 + */ + +#define MPSC0_MAIN_CONFIGURATION_LOW 0x8000 +#define MPSC0_MAIN_CONFIGURATION_HIGH 0x8004 +#define MPSC0_PROTOCOL_CONFIGURATION 0x8008 +#define CHANNEL0_REGISTER1 0x800c +#define CHANNEL0_REGISTER2 0x8010 +#define CHANNEL0_REGISTER3 0x8014 +#define CHANNEL0_REGISTER4 0x8018 +#define CHANNEL0_REGISTER5 0x801c +#define CHANNEL0_REGISTER6 0x8020 +#define CHANNEL0_REGISTER7 0x8024 +#define CHANNEL0_REGISTER8 0x8028 +#define CHANNEL0_REGISTER9 0x802c +#define CHANNEL0_REGISTER10 0x8030 +#define CHANNEL0_REGISTER11 0x8034 + +/* + * MPSC1 + */ + +#define MPSC1_MAIN_CONFIGURATION_LOW 0x9000 +#define MPSC1_MAIN_CONFIGURATION_HIGH 0x9004 +#define MPSC1_PROTOCOL_CONFIGURATION 0x9008 +#define CHANNEL1_REGISTER1 0x900c +#define CHANNEL1_REGISTER2 0x9010 +#define CHANNEL1_REGISTER3 0x9014 +#define CHANNEL1_REGISTER4 0x9018 +#define CHANNEL1_REGISTER5 0x901c +#define CHANNEL1_REGISTER6 0x9020 +#define CHANNEL1_REGISTER7 0x9024 +#define CHANNEL1_REGISTER8 0x9028 +#define CHANNEL1_REGISTER9 0x902c +#define CHANNEL1_REGISTER10 0x9030 +#define CHANNEL1_REGISTER11 0x9034 + +/* + * MPSCs Interupts + */ + +#define MPSC0_CAUSE 0xb804 +#define MPSC0_MASK 0xb884 +#define MPSC1_CAUSE 0xb80c +#define MPSC1_MASK 0xb88c + +extern unsigned long gt64240_base; + +#define GT64240_BASE (gt64240_base) + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ +#define __GT_READ(ofs) \ + (*(volatile u32 *)(GT64240_BASE+(ofs))) +#define __GT_WRITE(ofs, data) \ + do { *(volatile u32 *)(GT64240_BASE+(ofs)) = (data); } while (0) + +#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs)) +#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data)) + +#define GT_READ_16(ofs, data) \ + le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs))) +#define GT_WRITE_16(ofs, data) \ + *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data) + +#define GT_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(GT64240_BASE+(ofs)) +#define GT_WRITE_8(ofs, data) \ + *(volatile u8 *)(GT64240_BASE+(ofs)) = data + +extern struct pci_ops gt_bus0_pci_ops; +extern struct pci_ops gt_bus1_pci_ops; + +#endif /* __ASM_MIPS_MV64240_H */ diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index 4a024fa727cc..f70b9362aa9f 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h @@ -12,22 +12,27 @@ #ifdef __ASSEMBLY__ + .macro _ssnop + sll $0, $2, 1 + .endm + /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use * for data translations should not occur for 3 cpu cycles. */ #ifdef CONFIG_CPU_RM9000 + #define mtc0_tlbw_hazard \ .set push; \ .set mips32; \ - ssnop; ssnop; ssnop; ssnop; \ + _ssnop; _ssnop; _ssnop; _ssnop; \ .set pop #define tlbw_eret_hazard \ .set push; \ .set mips32; \ - ssnop; ssnop; ssnop; ssnop; \ + _ssnop; _ssnop; _ssnop; _ssnop; \ .set pop #else @@ -43,6 +48,33 @@ #define tlbw_eret_hazard #endif +/* + * mtc0->mfc0 hazard + * The 24K has a 2 cycle mtc0/mfc0 execution hazard. + * It is a MIPS32R2 processor so ehb will clear the hazard. + */ + +#ifdef CONFIG_CPU_MIPSR2 +/* + * Use a macro for ehb unless explicit support for MIPSR2 is enabled + */ + .macro ehb + sll $0, $0, 3 + .endm + +#define irq_enable_hazard \ + ehb # irq_enable_hazard + +#define irq_disable_hazard \ + ehb # irq_disable_hazard + +#else + +#define irq_enable_hazard +#define irq_disable_hazard + +#endif + #else /* __ASSEMBLY__ */ /* @@ -55,13 +87,13 @@ #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ ".set\tmips32\n\t" \ - "ssnop; ssnop; ssnop; ssnop\n\t" \ + "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ ".set\tmips0") #define tlbw_use_hazard() \ __asm__ __volatile__( \ ".set\tmips32\n\t" \ - "ssnop; ssnop; ssnop; ssnop\n\t" \ + "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ ".set\tmips0") #else @@ -82,6 +114,83 @@ #endif +/* + * mtc0->mfc0 hazard + * The 24K has a 2 cycle mtc0/mfc0 execution hazard. + * It is a MIPS32R2 processor so ehb will clear the hazard. + */ + +#ifdef CONFIG_CPU_MIPSR2 +/* + * Use a macro for ehb unless explicit support for MIPSR2 is enabled + */ +__asm__( + " .macro ehb \n\t" + " sll $0, $0, 3 \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_enable_hazard \n\t" + " ehb \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_disable_hazard \n\t" + " ehb \n\t" + " .endm"); + +#define irq_enable_hazard() \ + __asm__ __volatile__( \ + "ehb\t\t\t\t# irq_enable_hazard") + +#define irq_disable_hazard() \ + __asm__ __volatile__( \ + "ehb\t\t\t\t# irq_disable_hazard") + +#elif defined(CONFIG_CPU_R10000) + +/* + * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. + */ + +__asm__( + " .macro\tirq_enable_hazard \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_disable_hazard \n\t" + " .endm"); + +#define irq_enable_hazard() do { } while (0) +#define irq_disable_hazard() do { } while (0) + +#else + +/* + * Default for classic MIPS processors. Assume worst case hazards but don't + * care about the irq_enable_hazard - sooner or later the hardware will + * enable it and we don't care when exactly. + */ + +__asm__( + " .macro _ssnop \n\t" + " sll $0, $2, 1 \n\t" + " .endm \n\t" + " \n\t" + " # \n\t" + " # There is a hazard but we do not care \n\t" + " # \n\t" + " .macro\tirq_enable_hazard \n\t" + " .endm \n\t" + " \n\t" + " .macro\tirq_disable_hazard \n\t" + " _ssnop; _ssnop; _ssnop \n\t" + " .endm"); + +#define irq_enable_hazard() do { } while (0) +#define irq_disable_hazard() \ + __asm__ __volatile__( \ + "_ssnop; _ssnop; _ssnop;\t\t# irq_disable_hazard") + +#endif + #endif /* __ASSEMBLY__ */ #endif /* _ASM_HAZARDS_H */ diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h new file mode 100644 index 000000000000..1de5c32a5884 --- /dev/null +++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h @@ -0,0 +1,38 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003, 2004 Ralf Baechle + */ +#ifndef __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H + +/* + * Momentum Jaguar ATX always has the RM9000 processor. + */ +#define cpu_has_watch 1 +#define cpu_has_mips16 0 +#define cpu_has_divec 0 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_prefetch 1 +#define cpu_has_mcheck 0 +#define cpu_has_ejtag 0 + +#define cpu_has_llsc 1 +#define cpu_has_vtag_icache 0 +#define cpu_has_dc_aliases 0 +#define cpu_has_ic_fills_f_dc 0 + +#define cpu_has_nofpuex 0 +#define cpu_has_64bits 1 + +#define cpu_has_subset_pcaches 0 + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 32 + +#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 8bdab9794feb..71198779fcd6 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -632,7 +632,7 @@ do { \ } while (0) /* - * On The RM7000 these are use to access cop0 set 1 registers + * On RM7000/RM9000 these are uses to access cop0 set 1 registers */ #define __read_32bit_c0_ctrl_register(source) \ ({ int __res; \ diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index e42794180211..dd7591b48ee1 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -45,12 +45,17 @@ extern unsigned long pgd_current[]; #define ASID_INC 0x40 #define ASID_MASK 0xfc0 +#elif defined(CONFIG_CPU_R8000) + +#define ASID_INC 0x10 +#define ASID_MASK 0xff0 + #elif defined(CONFIG_CPU_RM9000) #define ASID_INC 0x1 #define ASID_MASK 0xfff -#else /* FIXME: not correct for R6000, R8000 */ +#else /* FIXME: not correct for R6000 */ #define ASID_INC 0x1 #define ASID_MASK 0xff @@ -78,9 +83,8 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) unsigned long asid = asid_cache(cpu); if (! ((asid += ASID_INC) & ASID_MASK) ) { -#ifdef CONFIG_VTAG_ICACHE - flush_icache_all(); -#endif + if (cpu_has_vtag_icache) + flush_icache_all(); local_flush_tlb_all(); /* start new asid cycle */ if (!asid) /* fix version if needed */ asid = ASID_FIRST_VERSION; diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h index 99635e6b610e..90ee24aad955 100644 --- a/include/asm-mips/module.h +++ b/include/asm-mips/module.h @@ -2,11 +2,14 @@ #define _ASM_MODULE_H #include +#include +#include struct mod_arch_specific { /* Data Bus Error exception tables */ - const struct exception_table_entry *dbe_table_start; - const struct exception_table_entry *dbe_table_end; + struct list_head dbe_list; + const struct exception_table_entry *dbe_start; + const struct exception_table_entry *dbe_end; }; typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ @@ -38,4 +41,16 @@ typedef struct #endif +#ifdef CONFIG_MODULES +/* Given an address, look for it in the exception tables. */ +const struct exception_table_entry*search_module_dbetables(unsigned long addr); +#else +/* Given an address, look for it in the exception tables. */ +static inline const struct exception_table_entry * +search_module_dbetables(unsigned long addr) +{ + return NULL; +} +#endif + #endif /* _ASM_MODULE_H */ diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 37de18f63b43..47ca67f25e54 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -10,16 +10,20 @@ #define _ASM_PAGE_H #include -#include #ifdef __KERNEL__ +#include + /* * PAGE_SHIFT determines the page size */ #ifdef CONFIG_PAGE_SIZE_4KB #define PAGE_SHIFT 12 #endif +#ifdef CONFIG_PAGE_SIZE_8KB +#define PAGE_SHIFT 13 +#endif #ifdef CONFIG_PAGE_SIZE_16KB #define PAGE_SHIFT 14 #endif diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index ba29750e4f1c..1af4e5b600c6 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -87,6 +87,9 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction); +extern void pcibios_resource_to_bus(struct pci_dev *dev, + struct pci_bus_region *region, struct resource *res); + #endif /* __KERNEL__ */ /* implement the pci_ DMA API in terms of the generic device dma_ one */ diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index 51326d10b880..65bee143ebe3 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -141,35 +141,8 @@ static inline void pgd_clear(pgd_t *pgdp) { } #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #endif -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - -/* - * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset - * into this range: - */ -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) - -#else - -/* - * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset - * into this range: - */ -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) - -#endif - #define __pgd_offset(address) pgd_index(address) -#define __pmd_offset(address) \ - (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) +#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -200,17 +173,46 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) #define pte_unmap(pte) ((void)(pte)) #define pte_unmap_nested(pte) ((void)(pte)) -/* Swap entries must have VALID and GLOBAL bits cleared. */ #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define __swp_type(x) (((x).val >> 1) & 0x7f) -#define __swp_offset(x) ((x).val >> 10) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) }) +/* Swap entries must have VALID bit cleared. */ +#define __swp_type(x) (((x).val >> 10) & 0x1f) +#define __swp_offset(x) ((x).val >> 15) +#define __swp_entry(type,offset) \ + ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) + +/* + * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 27 + +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) + #else -#define __swp_type(x) (((x).val >> 1) & 0x1f) -#define __swp_offset(x) ((x).val >> 8) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) +/* Swap entries must have VALID and GLOBAL bits cleared. */ +#define __swp_type(x) (((x).val >> 8) & 0x1f) +#define __swp_offset(x) ((x).val >> 13) +#define __swp_entry(type,offset) \ + ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) + +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 27 + +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) + #endif #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h index eba84a79efc9..333d9a8f585f 100644 --- a/include/asm-mips/pgtable-64.h +++ b/include/asm-mips/pgtable-64.h @@ -53,7 +53,11 @@ * We used to implement 41 bits by having an order 1 pmd level but that seemed * rather pointless. * - * For 16kB page size we use a 2 level page tree which permit a total of + * For 8kB page size we use a 3 level page tree which permits a total of + * 8TB of address space. Alternatively a 33-bit / 8GB organization using + * two levels would be easy to implement. + * + * For 16kB page size we use a 2 level page tree which permits a total of * 36 bits of virtual address space. We could add a third leve. but it seems * like at the moment there's no need for this. * @@ -65,6 +69,11 @@ #define PMD_ORDER 1 #define PTE_ORDER 0 #endif +#ifdef CONFIG_PAGE_SIZE_8KB +#define PGD_ORDER 0 +#define PMD_ORDER 0 +#define PTE_ORDER 0 +#endif #ifdef CONFIG_PAGE_SIZE_16KB #define PGD_ORDER 0 #define PMD_ORDER 0 @@ -148,16 +157,6 @@ static inline void pgd_clear(pgd_t *pgdp) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #endif -/* - * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset - * into this range: - */ -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) - #define __pgd_offset(address) pgd_index(address) #define page_pte(page) page_pte_prot(page, __pgprot(0)) @@ -214,6 +213,18 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 32 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 32 + +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) + /* * Used for the b0rked handling of kernel pagetables on the 64-bit kernel. */ diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h index 22d19833a4b4..76c1ae1c7dee 100644 --- a/include/asm-mips/pgtable-bits.h +++ b/include/asm-mips/pgtable-bits.h @@ -60,7 +60,7 @@ #define _PAGE_SILENT_WRITE (1<<8) #define _CACHE_MASK (7<<9) -#if defined(CONFIG_CPU_SB1) +#ifdef CONFIG_CPU_SB1 /* No penalty for being coherent on the SB1, so just use it for "noncoherent" spaces, too. Shouldn't hurt. */ @@ -70,6 +70,20 @@ #define _CACHE_CACHABLE_NONCOHERENT (5<<9) #define _CACHE_UNCACHED_ACCELERATED (7<<9) +#elif defined(CONFIG_CPU_RM9000) + +#define _CACHE_WT (0 << 9) +#define _CACHE_WTWA (1 << 9) +#define _CACHE_UC_B (2 << 9) +#define _CACHE_WB (3 << 9) +#define _CACHE_CWBEA (4 << 9) +#define _CACHE_CWB (5 << 9) +#define _CACHE_UCNB (6 << 9) +#define _CACHE_FPC (7 << 9) + +#define _CACHE_UNCACHED _CACHE_UC_B +#define _CACHE_CACHABLE_NONCOHERENT _CACHE_UC_B + #else #define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ @@ -93,6 +107,8 @@ #define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED #elif defined(CONFIG_DMA_NONCOHERENT) #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT +#elif defined(CONFIG_CPU_RM9000) +#define PAGE_CACHABLE_DEFAULT _CACHE_CWBEA #else #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW #endif diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 5b2aa070cfa2..9d5a8fad0949 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -125,8 +125,6 @@ static inline void pte_clear(pte_t *ptep) extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -#define PTE_FILE_MAX_BITS 27 - /* * The following only work if pte_present() is true. * Undefined behaviour if not.. diff --git a/include/asm-mips/pmon.h b/include/asm-mips/pmon.h index 0162517854d4..7b4f990e152a 100644 --- a/include/asm-mips/pmon.h +++ b/include/asm-mips/pmon.h @@ -17,6 +17,9 @@ struct callvectors { int (*printf) (const char*, ...); /* 20 */ void (*cacheflush) (void); /* 24 */ char* (*gets) (char*); /* 28 */ + int (*cpustart) (int, void *, int, int); /* 32 */ }; +extern struct callvectors *debug_vectors; + #endif /* _ASM_PMON_H */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 70534af2a59c..8e38389a9915 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -280,15 +280,6 @@ unsigned long get_wchan(struct task_struct *p); */ #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);}) -/* - * For now. The 32-bit cycle counter is screwed up so solving this nicely takes a little - * brainwork ... - */ -static inline unsigned long long sched_clock(void) -{ - return 0ULL; -} - #ifdef CONFIG_CPU_HAS_PREFETCH #define ARCH_HAS_PREFETCH diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index bab913a90644..ed9a3d774c6a 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h @@ -4,61 +4,70 @@ * for more details. * * Copyright (C) 1996 Linus Torvalds - * Copyright (C) 1998, 99, 2000, 01 Ralf Baechle + * Copyright (C) 1998, 99, 2000, 01, 04 Ralf Baechle * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. * Copyright (C) 2000, 01 MIPS Technologies, Inc. + * + * In all honesty, little of the old MIPS code left - the PPC64 variant was + * just looking nice and portable so I ripped it. Credits to whoever wrote + * it. */ -#ifndef _ASM_SEMAPHORE_H -#define _ASM_SEMAPHORE_H +#ifndef __ASM_SEMAPHORE_H +#define __ASM_SEMAPHORE_H + +/* + * Remove spinlock-based RW semaphores; RW semaphore definitions are + * now in rwsem.h and we use the generic lib/rwsem.c implementation. + * Rework semaphores to use atomic_dec_if_positive. + * -- Paul Mackerras (paulus@samba.org) + */ + +#ifdef __KERNEL__ -#include -#include -#include +#include +#include #include #include -#include struct semaphore { -#ifdef __MIPSEB__ - atomic_t count; - atomic_t waking; -#else - atomic_t waking; + /* + * Note that any negative value of count is equivalent to 0, + * but additionally indicates that some process(es) might be + * sleeping on `wait'. + */ atomic_t count; -#endif wait_queue_head_t wait; -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG long __magic; #endif -} __attribute__((aligned(8))); +}; -#if WAITQUEUE_DEBUG -# define __SEM_DEBUG_INIT(name) , .__magic = (long)&(name).__magic +#ifdef WAITQUEUE_DEBUG +# define __SEM_DEBUG_INIT(name) \ + , (long)&(name).__magic #else # define __SEM_DEBUG_INIT(name) #endif -#define __SEMAPHORE_INITIALIZER(name,_count) { \ - .count = ATOMIC_INIT(_count), \ - .waking = ATOMIC_INIT(0), \ - .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ - __SEM_DEBUG_INIT(name) \ -} +#define __SEMAPHORE_INITIALIZER(name, count) \ + { ATOMIC_INIT(count), \ + __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } -#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INITIALIZER(name, 1) +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name, 1) -#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ - struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) +#define __DECLARE_SEMAPHORE_GENERIC(name, count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) -#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) -#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) static inline void sema_init (struct semaphore *sem, int val) { atomic_set(&sem->count, val); - atomic_set(&sem->waking, 0); init_waitqueue_head(&sem->wait); -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG sem->__magic = (long)&sem->__magic; #endif } @@ -73,211 +82,57 @@ static inline void init_MUTEX_LOCKED (struct semaphore *sem) sema_init(sem, 0); } -#ifndef CONFIG_CPU_HAS_LLDSCD -/* - * On machines without lld/scd we need a spinlock to make the manipulation of - * sem->count and sem->waking atomic. - */ -extern spinlock_t semaphore_lock; -#endif - -extern void __down_failed(struct semaphore * sem); -extern int __down_failed_interruptible(struct semaphore * sem); -extern void __up_wakeup(struct semaphore * sem); +extern void __down(struct semaphore * sem); +extern int __down_interruptible(struct semaphore * sem); +extern void __up(struct semaphore * sem); static inline void down(struct semaphore * sem) { - int count; - -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif might_sleep(); - count = atomic_dec_return(&sem->count); - if (unlikely(count < 0)) - __down_failed(sem); + + /* + * Try to get the semaphore, take the slow path if we fail. + */ + if (unlikely(atomic_dec_return(&sem->count) < 0)) + __down(sem); } -/* - * Interruptible try to acquire a semaphore. If we obtained - * it, return zero. If we were interrupted, returns -EINTR - */ static inline int down_interruptible(struct semaphore * sem) { - int count; + int ret = 0; -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif might_sleep(); - count = atomic_dec_return(&sem->count); - if (unlikely(count < 0)) - return __down_failed_interruptible(sem); - - return 0; -} - -#ifdef CONFIG_CPU_HAS_LLDSCD - -/* - * down_trylock returns 0 on success, 1 if we failed to get the lock. - * - * We must manipulate count and waking simultaneously and atomically. - * Here, we do this by using lld/scd on the pair of 32-bit words. - * - * Pseudocode: - * - * Decrement(sem->count) - * If(sem->count >=0) { - * Return(SUCCESS) // resource is free - * } else { - * If(sem->waking <= 0) { // if no wakeup pending - * Increment(sem->count) // undo decrement - * Return(FAILURE) - * } else { - * Decrement(sem->waking) // otherwise "steal" wakeup - * Return(SUCCESS) - * } - * } - */ -static inline int down_trylock(struct semaphore * sem) -{ - long ret, tmp, tmp2, sub; - -#if WAITQUEUE_DEBUG - CHECK_MAGIC(sem->__magic); -#endif - - __asm__ __volatile__( - " .set mips3 # down_trylock \n" - "0: lld %1, %4 \n" - " dli %3, 0x0000000100000000 # count -= 1 \n" - " dsubu %1, %3 \n" - " li %0, 0 # ret = 0 \n" - " bgez %1, 2f # if count >= 0 \n" - " sll %2, %1, 0 # extract waking \n" - " blez %2, 1f # if waking < 0 -> 1f \n" - " daddiu %1, %1, -1 # waking -= 1 \n" - " b 2f \n" - "1: daddu %1, %1, %3 # count += 1 \n" - " li %0, 1 # ret = 1 \n" - "2: scd %1, %4 \n" - " beqz %1, 0b \n" - " sync \n" - " .set mips0 \n" - : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) - : "m"(*sem) - : "memory"); + if (unlikely(atomic_dec_return(&sem->count) < 0)) + ret = __down_interruptible(sem); return ret; } -/* - * Note! This is subtle. We jump to wake people up only if - * the semaphore was negative (== somebody was waiting on it). - */ -static inline void up(struct semaphore * sem) -{ - unsigned long tmp, tmp2; - int count; - -#if WAITQUEUE_DEBUG - CHECK_MAGIC(sem->__magic); -#endif - /* - * We must manipulate count and waking simultaneously and atomically. - * Otherwise we have races between up and __down_failed_interruptible - * waking up on a signal. - */ - - __asm__ __volatile__( - " .set mips3 \n" - " sync # up \n" - "1: lld %1, %3 \n" - " dsra32 %0, %1, 0 # extract count to %0 \n" - " daddiu %0, 1 # count += 1 \n" - " slti %2, %0, 1 # %3 = (%0 <= 0) \n" - " daddu %1, %2 # waking += %3 \n" - " dsll32 %1, %1, 0 # zero-extend %1 \n" - " dsrl32 %1, %1, 0 \n" - " dsll32 %2, %0, 0 # Reassemble union \n" - " or %1, %2 # from count and waking \n" - " scd %1, %3 \n" - " beqz %1, 1b \n" - " .set mips0 \n" - : "=&r"(count), "=&r"(tmp), "=&r"(tmp2), "+m"(*sem) - : - : "memory"); - - if (unlikely(count <= 0)) - __up_wakeup(sem); -} - -#else - -/* - * Non-blockingly attempt to down() a semaphore. - * Returns zero if we acquired it - */ static inline int down_trylock(struct semaphore * sem) { - unsigned long flags; - int count, waking; - int ret = 0; - -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - spin_lock_irqsave(&semaphore_lock, flags); - count = atomic_read(&sem->count) - 1; - atomic_set(&sem->count, count); - if (unlikely(count < 0)) { - waking = atomic_read(&sem->waking); - if (waking <= 0) { - atomic_set(&sem->count, count + 1); - ret = 1; - } else { - atomic_set(&sem->waking, waking - 1); - ret = 0; - } - } - spin_unlock_irqrestore(&semaphore_lock, flags); - - return ret; + return atomic_dec_if_positive(&sem->count) < 0; } -/* - * Note! This is subtle. We jump to wake people up only if - * the semaphore was negative (== somebody was waiting on it). - */ static inline void up(struct semaphore * sem) { - unsigned long flags; - int count, waking; - -#if WAITQUEUE_DEBUG +#ifdef WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - /* - * We must manipulate count and waking simultaneously and atomically. - * Otherwise we have races between up and __down_failed_interruptible - * waking up on a signal. - */ - - spin_lock_irqsave(&semaphore_lock, flags); - count = atomic_read(&sem->count) + 1; - waking = atomic_read(&sem->waking); - if (count <= 0) - waking++; - atomic_set(&sem->count, count); - atomic_set(&sem->waking, waking); - spin_unlock_irqrestore(&semaphore_lock, flags); - if (unlikely(count <= 0)) - __up_wakeup(sem); + if (unlikely(atomic_inc_return(&sem->count) <= 0)) + __up(sem); } -#endif /* CONFIG_CPU_HAS_LLDSCD */ +#endif /* __KERNEL__ */ -#endif /* _ASM_SEMAPHORE_H */ +#endif /* __ASM_SEMAPHORE_H */ diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index ae455b04b31a..83c735adef98 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -315,24 +315,6 @@ #define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS #endif -#ifdef CONFIG_TITAN_SERIAL -/* 16552 20 MHz crystal */ -#define TITAN_SERIAL_BASE_BAUD ( 20000000 / 16 ) -#define TITAN_SERIAL_IRQ XXX -#define TITAN_SERIAL_BASE 0xffffffff - -#define _TITAN_SERIAL_INIT(int, base) \ - { baud_base: TITAN_SERIAL_BASE_BAUD, irq: int, \ - flags: STD_COM_FLAGS, iomem_base: (u8 *) base, \ - iomem_reg_shift: 2, io_type: SERIAL_IO_MEM \ - } - -#define TITAN_SERIAL_PORT_DEFNS \ - _TITAN_SERIAL_INIT(TITAN_SERIAL_IRQ, TITAN_SERIAL_BASE) -#else -#define TITAN_SERIAL_PORT_DEFNS -#endif - #ifdef CONFIG_DDB5477 #include #define DDB5477_SERIAL_PORT_DEFNS \ @@ -371,7 +353,6 @@ MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \ MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ - TITAN_SERIAL_PORT_DEFNS \ TXX927_SERIAL_PORT_DEFNS \ AU1000_SERIAL_PORT_DEFNS diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 4146d42d48fe..f0ef26b43f7e 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -51,8 +51,6 @@ extern cpumask_t phys_cpu_present_map; extern cpumask_t cpu_online_map; #define cpu_possible_map phys_cpu_present_map -#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) - extern cpumask_t cpu_callout_map; /* We don't mark CPUs online until __cpu_up(), so we need another measure */ static inline int num_booting_cpus(void) @@ -90,12 +88,6 @@ extern void prom_init_secondary(void); */ extern void prom_prepare_cpus(unsigned int max_cpus); -/* - * Do whatever setup needs to be done for SMP at the board level. Return - * the number of cpus in the system, including this one - */ -extern int prom_setup_smp(void); - /* * Last chance for the board code to finish SMP initialization before * the CPU is "online". diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 626a8ab288e1..53a441c3cb3b 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -302,6 +302,7 @@ or t0, t1 xori t0, 0x1f mtc0 t0, CP0_STATUS + irq_disable_hazard .endm /* @@ -314,6 +315,7 @@ or t0, t1 xori t0, 0x1e mtc0 t0, CP0_STATUS + irq_enable_hazard .endm /* @@ -326,6 +328,7 @@ or t0, t1 xori t0, 0x1e mtc0 t0, CP0_STATUS + irq_disable_hazard .endm #endif /* _ASM_STACKFRAME_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 9b7354b872f1..9bacd119796b 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -19,6 +19,7 @@ #include #include +#include __asm__ ( ".macro\tlocal_irq_enable\n\t" @@ -29,6 +30,7 @@ __asm__ ( "ori\t$1,0x1f\n\t" "xori\t$1,0x1e\n\t" "mtc0\t$1,$12\n\t" + "irq_enable_hazard\n\t" ".set\tpop\n\t" ".endm"); @@ -57,9 +59,7 @@ __asm__ ( "xori\t$1,1\n\t" ".set\tnoreorder\n\t" "mtc0\t$1,$12\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" + "irq_disable_hazard\n\t" ".set\tpop\n\t" ".endm"); @@ -80,7 +80,7 @@ __asm__ ( ".set\tpop\n\t" ".endm"); -#define local_save_flags(x) \ +#define local_save_flags(x) \ __asm__ __volatile__( \ "local_save_flags %0" \ : "=r" (x)) @@ -95,9 +95,7 @@ __asm__ ( "xori\t$1, 1\n\t" ".set\tnoreorder\n\t" "mtc0\t$1, $12\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" + "irq_disable_hazard\n\t" ".set\tpop\n\t" ".endm"); @@ -108,7 +106,8 @@ __asm__ __volatile__( \ : /* no inputs */ \ : "memory") -__asm__(".macro\tlocal_irq_restore flags\n\t" +__asm__ ( + ".macro\tlocal_irq_restore flags\n\t" ".set\tnoreorder\n\t" ".set\tnoat\n\t" "mfc0\t$1, $12\n\t" @@ -117,14 +116,12 @@ __asm__(".macro\tlocal_irq_restore flags\n\t" "xori\t$1, 1\n\t" "or\t\\flags, $1\n\t" "mtc0\t\\flags, $12\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" - "sll\t$0, $0, 1\t\t\t# nop\n\t" + "irq_disable_hazard\n\t" ".set\tat\n\t" ".set\treorder\n\t" ".endm"); -#define local_irq_restore(flags) \ +#define local_irq_restore(flags) \ do { \ unsigned long __tmp1; \ \ diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index 11782520310b..508b32ad330a 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -68,6 +68,9 @@ register struct thread_info *__current_thread_info __asm__("$28"); #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_MIPS64) #define THREAD_SIZE_ORDER (2) #endif +#ifdef CONFIG_PAGE_SIZE_8KB +#define THREAD_SIZE_ORDER (1) +#endif #ifdef CONFIG_PAGE_SIZE_16KB #define THREAD_SIZE_ORDER (0) #endif diff --git a/include/asm-mips/titan_dep.h b/include/asm-mips/titan_dep.h index e25423d39bb5..d820445e8ead 100644 --- a/include/asm-mips/titan_dep.h +++ b/include/asm-mips/titan_dep.h @@ -16,9 +16,6 @@ #include /* for KSEG1ADDR() */ #include /* for cpu_to_le32() */ -/* Turn on serial */ -#define CONFIG_TITAN_SERIAL - /* PCI */ #define TITAN_PCI_BASE 0xbb000000 @@ -50,8 +47,181 @@ */ #define RM9000x2_HTLINK_REG 0xbb000644 #define RM9000x2_BASE_ADDR 0xbb000000 -#define RM9000x2_OCD_HTCFGA 0x06f8 -#define RM9000x2_OCD_HTCFGD 0x06fc + +#define OCD_BASE 0xfb000000UL +#define OCD_SIZE 0x3000UL + +extern unsigned long ocd_base; + +/* + * OCD Registers + */ +#define RM9000x2_OCD_LKB5 0x0128 /* Ethernet */ +#define RM9000x2_OCD_LKM5 0x012c + +#define RM9000x2_OCD_LKB7 0x0138 /* HT Region 0 */ +#define RM9000x2_OCD_LKM7 0x013c +#define RM9000x2_OCD_LKB8 0x0140 /* HT Region 1 */ +#define RM9000x2_OCD_LKM8 0x0144 + +#define RM9000x2_OCD_LKB9 0x0148 /* Local Bus */ +#define RM9000x2_OCD_LKM9 0x014c +#define RM9000x2_OCD_LKB10 0x0150 +#define RM9000x2_OCD_LKM10 0x0154 +#define RM9000x2_OCD_LKB11 0x0158 +#define RM9000x2_OCD_LKM11 0x015c +#define RM9000x2_OCD_LKB12 0x0160 +#define RM9000x2_OCD_LKM12 0x0164 + +#define RM9000x2_OCD_LKB13 0x0168 /* Scratch RAM */ +#define RM9000x2_OCD_LKM13 0x016c + +#define RM9000x2_OCD_LPD0 0x0200 /* Local Bus */ +#define RM9000x2_OCD_LPD1 0x0210 +#define RM9000x2_OCD_LPD2 0x0220 +#define RM9000x2_OCD_LPD3 0x0230 + +#define RM9000x2_OCD_HTDVID 0x0600 /* HT Device Header */ +#define RM9000x2_OCD_HTSC 0x0604 +#define RM9000x2_OCD_HTCCR 0x0608 +#define RM9000x2_OCD_HTBHL 0x060c +#define RM9000x2_OCD_HTBAR0 0x0610 +#define RM9000x2_OCD_HTBAR1 0x0614 +#define RM9000x2_OCD_HTBAR2 0x0618 +#define RM9000x2_OCD_HTBAR3 0x061c +#define RM9000x2_OCD_HTBAR4 0x0620 +#define RM9000x2_OCD_HTBAR5 0x0624 +#define RM9000x2_OCD_HTCBCPT 0x0628 +#define RM9000x2_OCD_HTSDVID 0x062c +#define RM9000x2_OCD_HTXRA 0x0630 +#define RM9000x2_OCD_HTCAP1 0x0634 +#define RM9000x2_OCD_HTIL 0x063c + +#define RM9000x2_OCD_HTLCC 0x0640 /* HT Capability Block */ +#define RM9000x2_OCD_HTLINK 0x0644 +#define RM9000x2_OCD_HTFQREV 0x0648 + +#define RM9000x2_OCD_HTERCTL 0x0668 /* HT Controller */ +#define RM9000x2_OCD_HTRXDB 0x066c +#define RM9000x2_OCD_HTIMPED 0x0670 +#define RM9000x2_OCD_HTSWIMP 0x0674 +#define RM9000x2_OCD_HTCAL 0x0678 + +#define RM9000x2_OCD_HTBAA30 0x0680 +#define RM9000x2_OCD_HTBAA54 0x0684 +#define RM9000x2_OCD_HTMASK0 0x0688 +#define RM9000x2_OCD_HTMASK1 0x068c +#define RM9000x2_OCD_HTMASK2 0x0690 +#define RM9000x2_OCD_HTMASK3 0x0694 +#define RM9000x2_OCD_HTMASK4 0x0698 +#define RM9000x2_OCD_HTMASK5 0x069c + +#define RM9000x2_OCD_HTIFCTL 0x06a0 +#define RM9000x2_OCD_HTPLL 0x06a4 + +#define RM9000x2_OCD_HTSRI 0x06b0 +#define RM9000x2_OCD_HTRXNUM 0x06b4 +#define RM9000x2_OCD_HTTXNUM 0x06b8 + +#define RM9000x2_OCD_HTTXCNT 0x06c8 + +#define RM9000x2_OCD_HTERROR 0x06d8 +#define RM9000x2_OCD_HTRCRCE 0x06dc +#define RM9000x2_OCD_HTEOI 0x06e0 + +#define RM9000x2_OCD_CRCR 0x06f0 + +#define RM9000x2_OCD_HTCFGA 0x06f8 +#define RM9000x2_OCD_HTCFGD 0x06fc + +#define RM9000x2_OCD_INTMSG 0x0a00 + +#define RM9000x2_OCD_INTPIN0 0x0a40 +#define RM9000x2_OCD_INTPIN1 0x0a44 +#define RM9000x2_OCD_INTPIN2 0x0a48 +#define RM9000x2_OCD_INTPIN3 0x0a4c +#define RM9000x2_OCD_INTPIN4 0x0a50 +#define RM9000x2_OCD_INTPIN5 0x0a54 +#define RM9000x2_OCD_INTPIN6 0x0a58 +#define RM9000x2_OCD_INTPIN7 0x0a5c +#define RM9000x2_OCD_SEM 0x0a60 +#define RM9000x2_OCD_SEMSET 0x0a64 +#define RM9000x2_OCD_SEMCLR 0x0a68 + +#define RM9000x2_OCD_TKT 0x0a70 +#define RM9000x2_OCD_TKTINC 0x0a74 + +#define RM9000x2_OCD_NMICONFIG 0x0ac0 /* Interrupts */ +#define RM9000x2_OCD_INTP0PRI 0x1a80 +#define RM9000x2_OCD_INTP1PRI 0x1a80 +#define RM9000x2_OCD_INTP0STATUS0 0x1b00 +#define RM9000x2_OCD_INTP0MASK0 0x1b04 +#define RM9000x2_OCD_INTP0SET0 0x1b08 +#define RM9000x2_OCD_INTP0CLEAR0 0x1b0c +#define RM9000x2_OCD_INTP0STATUS1 0x1b10 +#define RM9000x2_OCD_INTP0MASK1 0x1b14 +#define RM9000x2_OCD_INTP0SET1 0x1b18 +#define RM9000x2_OCD_INTP0CLEAR1 0x1b1c +#define RM9000x2_OCD_INTP0STATUS2 0x1b20 +#define RM9000x2_OCD_INTP0MASK2 0x1b24 +#define RM9000x2_OCD_INTP0SET2 0x1b28 +#define RM9000x2_OCD_INTP0CLEAR2 0x1b2c +#define RM9000x2_OCD_INTP0STATUS3 0x1b30 +#define RM9000x2_OCD_INTP0MASK3 0x1b34 +#define RM9000x2_OCD_INTP0SET3 0x1b38 +#define RM9000x2_OCD_INTP0CLEAR3 0x1b3c +#define RM9000x2_OCD_INTP0STATUS4 0x1b40 +#define RM9000x2_OCD_INTP0MASK4 0x1b44 +#define RM9000x2_OCD_INTP0SET4 0x1b48 +#define RM9000x2_OCD_INTP0CLEAR4 0x1b4c +#define RM9000x2_OCD_INTP0STATUS5 0x1b50 +#define RM9000x2_OCD_INTP0MASK5 0x1b54 +#define RM9000x2_OCD_INTP0SET5 0x1b58 +#define RM9000x2_OCD_INTP0CLEAR5 0x1b5c +#define RM9000x2_OCD_INTP0STATUS6 0x1b60 +#define RM9000x2_OCD_INTP0MASK6 0x1b64 +#define RM9000x2_OCD_INTP0SET6 0x1b68 +#define RM9000x2_OCD_INTP0CLEAR6 0x1b6c +#define RM9000x2_OCD_INTP0STATUS7 0x1b70 +#define RM9000x2_OCD_INTP0MASK7 0x1b74 +#define RM9000x2_OCD_INTP0SET7 0x1b78 +#define RM9000x2_OCD_INTP0CLEAR7 0x1b7c +#define RM9000x2_OCD_INTP1STATUS0 0x2b00 +#define RM9000x2_OCD_INTP1MASK0 0x2b04 +#define RM9000x2_OCD_INTP1SET0 0x2b08 +#define RM9000x2_OCD_INTP1CLEAR0 0x2b0c +#define RM9000x2_OCD_INTP1STATUS1 0x2b10 +#define RM9000x2_OCD_INTP1MASK1 0x2b14 +#define RM9000x2_OCD_INTP1SET1 0x2b18 +#define RM9000x2_OCD_INTP1CLEAR1 0x2b1c +#define RM9000x2_OCD_INTP1STATUS2 0x2b20 +#define RM9000x2_OCD_INTP1MASK2 0x2b24 +#define RM9000x2_OCD_INTP1SET2 0x2b28 +#define RM9000x2_OCD_INTP1CLEAR2 0x2b2c +#define RM9000x2_OCD_INTP1STATUS3 0x2b30 +#define RM9000x2_OCD_INTP1MASK3 0x2b34 +#define RM9000x2_OCD_INTP1SET3 0x2b38 +#define RM9000x2_OCD_INTP1CLEAR3 0x2b3c +#define RM9000x2_OCD_INTP1STATUS4 0x2b40 +#define RM9000x2_OCD_INTP1MASK4 0x2b44 +#define RM9000x2_OCD_INTP1SET4 0x2b48 +#define RM9000x2_OCD_INTP1CLEAR4 0x2b4c +#define RM9000x2_OCD_INTP1STATUS5 0x2b50 +#define RM9000x2_OCD_INTP1MASK5 0x2b54 +#define RM9000x2_OCD_INTP1SET5 0x2b58 +#define RM9000x2_OCD_INTP1CLEAR5 0x2b5c +#define RM9000x2_OCD_INTP1STATUS6 0x2b60 +#define RM9000x2_OCD_INTP1MASK6 0x2b64 +#define RM9000x2_OCD_INTP1SET6 0x2b68 +#define RM9000x2_OCD_INTP1CLEAR6 0x2b6c +#define RM9000x2_OCD_INTP1STATUS7 0x2b70 +#define RM9000x2_OCD_INTP1MASK7 0x2b74 +#define RM9000x2_OCD_INTP1SET7 0x2b78 +#define RM9000x2_OCD_INTP1CLEAR7 0x2b7c + +#define OCD_READ(reg) (*(volatile unsigned int *)(ocd_base + (reg))) +#define OCD_WRITE(reg, val) \ + do { *(volatile unsigned int *)(ocd_base + (reg)) = (val); } while (0) /* * Hypertransport specific macros @@ -65,4 +235,3 @@ #define RM9K_READ_16(ofs, val) *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) #endif - diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 4dfc72bd1b98..7c5a30028776 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -297,16 +297,17 @@ #define __NR_mq_timedreceive (__NR_Linux + 274) #define __NR_mq_notify (__NR_Linux + 275) #define __NR_mq_getsetattr (__NR_Linux + 276) +#define __NR_vserver (__NR_Linux + 277) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 276 +#define __NR_Linux_syscalls 277 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 276 +#define __NR_O32_Linux_syscalls 277 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -550,16 +551,17 @@ #define __NR_mq_timedreceive (__NR_Linux + 233) #define __NR_mq_notify (__NR_Linux + 234) #define __NR_mq_getsetattr (__NR_Linux + 235) +#define __NR_vserver (__NR_Linux + 236) /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 235 +#define __NR_Linux_syscalls 236 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 235 +#define __NR_64_Linux_syscalls 236 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -807,16 +809,17 @@ #define __NR_mq_timedreceive (__NR_Linux + 237) #define __NR_mq_notify (__NR_Linux + 238) #define __NR_mq_getsetattr (__NR_Linux + 239) +#define __NR_vserver (__NR_Linux + 240) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 239 +#define __NR_Linux_syscalls 240 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 239 +#define __NR_N32_Linux_syscalls 240 #ifndef __ASSEMBLY__ diff --git a/include/asm-mips/vr41xx/capcella.h b/include/asm-mips/vr41xx/capcella.h index 82d9db6cb352..5b55083c5281 100644 --- a/include/asm-mips/vr41xx/capcella.h +++ b/include/asm-mips/vr41xx/capcella.h @@ -1,53 +1,27 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/capcella.h + * capcella.h, Include file for ZAO Networks Capcella. * - * BRIEF MODULE DESCRIPTION - * Include file for ZAO Networks Capcella. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ZAO_CAPCELLA_H #define __ZAO_CAPCELLA_H -#include #include -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - /* * General-Purpose I/O Pin Number */ diff --git a/include/asm-mips/vr41xx/mpc30x.h b/include/asm-mips/vr41xx/mpc30x.h index bff9f0aafcce..e6ac3c8e8bae 100644 --- a/include/asm-mips/vr41xx/mpc30x.h +++ b/include/asm-mips/vr41xx/mpc30x.h @@ -1,53 +1,27 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/mpc30x.h + * mpc30x.h, Include file for Victor MP-C303/304. * - * BRIEF MODULE DESCRIPTION - * Include file for Victor MP-C303/304. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __VICTOR_MPC30X_H #define __VICTOR_MPC30X_H -#include #include -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - /* * General-Purpose I/O Pin Number */ diff --git a/include/asm-mips/vr41xx/tb0219.h b/include/asm-mips/vr41xx/tb0219.h new file mode 100644 index 000000000000..273c6392688f --- /dev/null +++ b/include/asm-mips/vr41xx/tb0219.h @@ -0,0 +1,42 @@ +/* + * tb0219.h, Include file for TANBAC TB0219. + * + * Copyright (C) 2002-2004 Yoichi Yuasa + * + * Modified for TANBAC TB0219: + * Copyright (C) 2003 Megasolution Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __TANBAC_TB0219_H +#define __TANBAC_TB0219_H + +#include + +/* + * General-Purpose I/O Pin Number + */ +#define TB0219_PCI_SLOT1_PIN 2 +#define TB0219_PCI_SLOT2_PIN 3 +#define TB0219_PCI_SLOT3_PIN 4 + +/* + * Interrupt Number + */ +#define TB0219_PCI_SLOT1_IRQ GIU_IRQ(TB0219_PCI_SLOT1_PIN) +#define TB0219_PCI_SLOT2_IRQ GIU_IRQ(TB0219_PCI_SLOT2_PIN) +#define TB0219_PCI_SLOT3_IRQ GIU_IRQ(TB0219_PCI_SLOT3_PIN) + +#endif /* __TANBAC_TB0219_H */ diff --git a/include/asm-mips/vr41xx/tb0226.h b/include/asm-mips/vr41xx/tb0226.h index 97ca8898b763..0ff9a60ecacc 100644 --- a/include/asm-mips/vr41xx/tb0226.h +++ b/include/asm-mips/vr41xx/tb0226.h @@ -1,53 +1,27 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/tb0226.h + * tb0226.h, Include file for TANBAC TB0226. * - * BRIEF MODULE DESCRIPTION - * Include file for TANBAC TB0226. + * Copyright (C) 2002-2004 Yoichi Yuasa * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TANBAC_TB0226_H #define __TANBAC_TB0226_H -#include #include -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - /* * General-Purpose I/O Pin Number */ diff --git a/include/asm-mips/vr41xx/tb0229.h b/include/asm-mips/vr41xx/tb0229.h deleted file mode 100644 index bd8cbc876e49..000000000000 --- a/include/asm-mips/vr41xx/tb0229.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * FILE NAME - * include/asm-mips/vr41xx/tb0229.h - * - * BRIEF MODULE DESCRIPTION - * Include file for TANBAC TB0229 and TB0219. - * - * Copyright 2002,2003 Yoichi Yuasa - * yuasa@hh.iij4u.or.jp - * - * Modified for TANBAC TB0229: - * Copyright 2003 Megasolution Inc. - * matsu@megasolution.jp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#ifndef __TANBAC_TB0229_H -#define __TANBAC_TB0229_H - -#include -#include - -/* - * Board specific address mapping - */ -#define VR41XX_PCI_MEM1_BASE 0x10000000 -#define VR41XX_PCI_MEM1_SIZE 0x04000000 -#define VR41XX_PCI_MEM1_MASK 0x7c000000 - -#define VR41XX_PCI_MEM2_BASE 0x14000000 -#define VR41XX_PCI_MEM2_SIZE 0x02000000 -#define VR41XX_PCI_MEM2_MASK 0x7e000000 - -#define VR41XX_PCI_IO_BASE 0x16000000 -#define VR41XX_PCI_IO_SIZE 0x02000000 -#define VR41XX_PCI_IO_MASK 0x7e000000 - -#define VR41XX_PCI_IO_START 0x01000000 -#define VR41XX_PCI_IO_END 0x01ffffff - -#define VR41XX_PCI_MEM_START 0x12000000 -#define VR41XX_PCI_MEM_END 0x15ffffff - -#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) -#define IO_PORT_RESOURCE_START 0 -#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE -#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE -#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) -#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE -#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) - -/* - * General-Purpose I/O Pin Number - */ -#define TB0219_PCI_SLOT1_PIN 2 -#define TB0219_PCI_SLOT2_PIN 3 -#define TB0219_PCI_SLOT3_PIN 4 - -/* - * Interrupt Number - */ -#define TB0219_PCI_SLOT1_IRQ GIU_IRQ(TB0219_PCI_SLOT1_PIN) -#define TB0219_PCI_SLOT2_IRQ GIU_IRQ(TB0219_PCI_SLOT2_PIN) -#define TB0219_PCI_SLOT3_IRQ GIU_IRQ(TB0219_PCI_SLOT3_PIN) - -#define TB0219_RESET_REGS KSEG1ADDR(0x0a00000e) - -extern void tanbac_tb0229_restart(char *command); - -#endif /* __TANBAC_TB0229_H */ diff --git a/include/asm-mips/vr41xx/vr41xx.h b/include/asm-mips/vr41xx/vr41xx.h index 53fe1162af7e..c57c8dca6117 100644 --- a/include/asm-mips/vr41xx/vr41xx.h +++ b/include/asm-mips/vr41xx/vr41xx.h @@ -42,12 +42,6 @@ /* VR4133 0x00000c84- */ #define PRID_VR4133 0x00000c84 -/* - * Memory resource - */ -#define IO_MEM_RESOURCE_START 0UL -#define IO_MEM_RESOURCE_END 0x1fffffffUL - /* * Bus Control Uint */ @@ -136,8 +130,71 @@ extern void vr41xx_mask_clock(vr41xx_clock_t clock); extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign); extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)); -extern void vr41xx_enable_dsiuint(void); -extern void vr41xx_disable_dsiuint(void); +#define PIUINT_COMMAND 0x0040 +#define PIUINT_DATA 0x0020 +#define PIUINT_PAGE1 0x0010 +#define PIUINT_PAGE0 0x0008 +#define PIUINT_DATALOST 0x0004 +#define PIUINT_STATUSCHANGE 0x0001 + +extern void vr41xx_enable_piuint(uint16_t mask); +extern void vr41xx_disable_piuint(uint16_t mask); + +#define AIUINT_INPUT_DMAEND 0x0800 +#define AIUINT_INPUT_DMAHALT 0x0400 +#define AIUINT_INPUT_DATALOST 0x0200 +#define AIUINT_INPUT_DATA 0x0100 +#define AIUINT_OUTPUT_DMAEND 0x0008 +#define AIUINT_OUTPUT_DMAHALT 0x0004 +#define AIUINT_OUTPUT_NODATA 0x0002 + +extern void vr41xx_enable_aiuint(uint16_t mask); +extern void vr41xx_disable_aiuint(uint16_t mask); + +#define KIUINT_DATALOST 0x0004 +#define KIUINT_DATAREADY 0x0002 +#define KIUINT_SCAN 0x0001 + +extern void vr41xx_enable_kiuint(uint16_t mask); +extern void vr41xx_disable_kiuint(uint16_t mask); + +#define DSIUINT_CTS 0x0800 +#define DSIUINT_RXERR 0x0400 +#define DSIUINT_RX 0x0200 +#define DSIUINT_TX 0x0100 +#define DSIUINT_ALL 0x0f00 + +extern void vr41xx_enable_dsiuint(uint16_t mask); +extern void vr41xx_disable_dsiuint(uint16_t mask); + +#define FIRINT_UNIT 0x0010 +#define FIRINT_RX_DMAEND 0x0008 +#define FIRINT_RX_DMAHALT 0x0004 +#define FIRINT_TX_DMAEND 0x0002 +#define FIRINT_TX_DMAHALT 0x0001 + +extern void vr41xx_enable_firint(uint16_t mask); +extern void vr41xx_disable_firint(uint16_t mask); + +extern void vr41xx_enable_pciint(void); +extern void vr41xx_disable_pciint(void); + +extern void vr41xx_enable_scuint(void); +extern void vr41xx_disable_scuint(void); + +#define CSIINT_TX_DMAEND 0x0040 +#define CSIINT_TX_DMAHALT 0x0020 +#define CSIINT_TX_DATA 0x0010 +#define CSIINT_TX_FIFOEMPTY 0x0008 +#define CSIINT_RX_DMAEND 0x0004 +#define CSIINT_RX_DMAHALT 0x0002 +#define CSIINT_RX_FIFOEMPTY 0x0001 + +extern void vr41xx_enable_csiint(uint16_t mask); +extern void vr41xx_disable_csiint(uint16_t mask); + +extern void vr41xx_enable_bcuint(void); +extern void vr41xx_disable_bcuint(void); /* * Power Management Unit @@ -220,18 +277,71 @@ extern void vr41xx_dsiu_init(void); /* * PCI Control Unit */ -struct vr41xx_pci_address_space { - u32 internal_base; - u32 address_mask; - u32 pci_base; +#define PCI_MASTER_ADDRESS_MASK 0x7fffffffU + +struct pci_master_address_conversion { + uint32_t bus_base_address; + uint32_t address_mask; + uint32_t pci_base_address; +}; + +struct pci_target_address_conversion { + uint32_t address_mask; + uint32_t bus_base_address; +}; + +typedef enum { + CANNOT_LOCK_FROM_DEVICE, + CAN_LOCK_FROM_DEVICE, +} pci_exclusive_access_t; + +struct pci_mailbox_address { + uint32_t base_address; }; -struct vr41xx_pci_address_map { - struct vr41xx_pci_address_space *mem1; - struct vr41xx_pci_address_space *mem2; - struct vr41xx_pci_address_space *io; +struct pci_target_address_window { + uint32_t base_address; +}; + +typedef enum { + PCI_ARBITRATION_MODE_FAIR, + PCI_ARBITRATION_MODE_ALTERNATE_0, + PCI_ARBITRATION_MODE_ALTERNATE_B, +} pci_arbiter_priority_control_t; + +typedef enum { + PCI_TAKE_AWAY_GNT_DISABLE, + PCI_TAKE_AWAY_GNT_ENABLE, +} pci_take_away_gnt_mode_t; + +struct pci_controller_unit_setup { + struct pci_master_address_conversion *master_memory1; + struct pci_master_address_conversion *master_memory2; + + struct pci_target_address_conversion *target_memory1; + struct pci_target_address_conversion *target_memory2; + + struct pci_master_address_conversion *master_io; + + pci_exclusive_access_t exclusive_access; + + uint32_t pci_clock_max; + uint8_t wait_time_limit_from_irdy_to_trdy; /* Only VR4122 is supported */ + + struct pci_mailbox_address *mailbox; + struct pci_target_address_window *target_window1; + struct pci_target_address_window *target_window2; + + uint8_t master_latency_timer; + uint8_t retry_limit; + + pci_arbiter_priority_control_t arbiter_priority_control; + pci_take_away_gnt_mode_t take_away_gnt_mode; + + struct resource *mem_resource; + struct resource *io_resource; }; -extern void vr41xx_pciu_init(struct vr41xx_pci_address_map *map); +extern void vr41xx_pciu_setup(struct pci_controller_unit_setup *setup); #endif /* __NEC_VR41XX_H */ diff --git a/include/asm-mips/vr41xx/vrc4173.h b/include/asm-mips/vr41xx/vrc4173.h index a8e873c06481..b14ef0377da1 100644 --- a/include/asm-mips/vr41xx/vrc4173.h +++ b/include/asm-mips/vr41xx/vrc4173.h @@ -1,19 +1,24 @@ /* - * FILE NAME - * include/asm-mips/vr41xx/vrc4173.h + * vrc4173.h, Include file for NEC VRC4173. * - * BRIEF MODULE DESCRIPTION - * Include file for NEC VRC4173. + * Copyright (C) 2000 Michael R. McDonald + * Copyright (C) 2001-2003 Montavista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2004 Yoichi Yuasa * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Copyright (C) 2000 by Michael R. McDonald + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Copyright 2001-2003 Montavista Software Inc. - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NEC_VRC4173_H #define __NEC_VRC4173_H @@ -72,35 +77,38 @@ extern unsigned long vrc4173_io_offset; /* * Clock Mask Unit */ -#define VRC4173_PIU_CLOCK 0x0001 -#define VRC4173_KIU_CLOCK 0x0002 -#define VRC4173_AIU_CLOCK 0x0004 -#define VRC4173_PS2CH1_CLOCK 0x0008 -#define VRC4173_PS2CH2_CLOCK 0x0010 -#define VRC4173_USBU_PCI_CLOCK 0x0020 -#define VRC4173_CARDU1_PCI_CLOCK 0x0040 -#define VRC4173_CARDU2_PCI_CLOCK 0x0080 -#define VRC4173_AC97U_PCI_CLOCK 0x0100 -#define VRC4173_USBU_48MHz_CLOCK 0x0400 -#define VRC4173_EXT_48MHz_CLOCK 0x0800 -#define VRC4173_48MHz_CLOCK 0x1000 +typedef enum vrc4173_clock { + VRC4173_PIU_CLOCK, + VRC4173_KIU_CLOCK, + VRC4173_AIU_CLOCK, + VRC4173_PS2_CH1_CLOCK, + VRC4173_PS2_CH2_CLOCK, + VRC4173_USBU_PCI_CLOCK, + VRC4173_CARDU1_PCI_CLOCK, + VRC4173_CARDU2_PCI_CLOCK, + VRC4173_AC97U_PCI_CLOCK, + VRC4173_USBU_48MHz_CLOCK, + VRC4173_EXT_48MHz_CLOCK, + VRC4173_48MHz_CLOCK, +} vrc4173_clock_t; -extern void vrc4173_clock_supply(u16 mask); -extern void vrc4173_clock_mask(u16 mask); +extern void vrc4173_supply_clock(vrc4173_clock_t clock); +extern void vrc4173_mask_clock(vrc4173_clock_t clock); /* * General-Purpose I/O Unit */ -enum { - PS2CH1_SELECT, - PS2CH2_SELECT, - TOUCHPANEL_SELECT, - KIU8_SELECT, - KIU10_SELECT, - KIU12_SELECT, - GPIO_SELECT -}; +typedef enum vrc4173_function { + PS2_CHANNEL1, + PS2_CHANNEL2, + TOUCHPANEL, + KEYBOARD_8SCANLINES, + KEYBOARD_10SCANLINES, + KEYBOARD_12SCANLINES, + GPIO_0_15PINS, + GPIO_16_20PINS, +} vrc4173_function_t; -extern void vrc4173_select_function(int func); +extern void vrc4173_select_function(vrc4173_function_t function); #endif /* __NEC_VRC4173_H */ -- cgit v1.2.3 From 1f1b84f0e7bd94dfa088364ca963a38e2a411986 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:20:06 -0700 Subject: [PATCH] Indydog update From: Ralf Baechle Forward port of the 2.4 driver with changes required for 2.6. Signed-off-by: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/watchdog/indydog.c | 117 ++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 72 deletions(-) diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c index 42363f353e71..cbd19e5a9478 100644 --- a/drivers/char/watchdog/indydog.c +++ b/drivers/char/watchdog/indydog.c @@ -22,16 +22,11 @@ #include #include #include -#include #include -#include +#include #define PFX "indydog: " -#define WATCHDOG_HEARTBEAT 60 - -static unsigned long indydog_alive; -static struct sgimc_misc_ctrl *mcmisc_regs; -static char expect_close; +static int indydog_alive; #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -39,96 +34,78 @@ static int nowayout = 1; static int nowayout = 0; #endif +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ + module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); static void indydog_start(void) { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + u32 mc_ctrl0 = sgimc->cpuctrl0; - mc_ctrl0 |= SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; - - printk(KERN_INFO PFX "Started watchdog timer.\n"); + mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; } static void indydog_stop(void) { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + u32 mc_ctrl0 = sgimc->cpuctrl0; mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; + sgimc->cpuctrl0 = mc_ctrl0; printk(KERN_INFO PFX "Stopped watchdog timer.\n"); } static void indydog_ping(void) { - mcmisc_regs->watchdogt = 0; + sgimc->watchdogt = 0; } /* * Allow only one person to hold it open */ - static int indydog_open(struct inode *inode, struct file *file) { - if( test_and_set_bit(0,&indydog_alive) ) + if (indydog_alive) return -EBUSY; if (nowayout) __module_get(THIS_MODULE); - /* - * Activate timer - */ + /* Activate timer */ indydog_start(); indydog_ping(); + indydog_alive = 1; + printk(KERN_INFO "Started watchdog timer.\n"); + return 0; } static int indydog_release(struct inode *inode, struct file *file) { - /* - * Shut off the timer. - * Lock it in if it's a module and we set nowayout - */ - - if (expect_close == 42) { - indydog_stop(); - } else { - printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); - indydog_ping(); + /* Shut off the timer. + * Lock it in if it's a module and we defined ...NOWAYOUT */ + if (!nowayout) { + u32 mc_ctrl0 = sgimc->cpuctrl0; + mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; + printk(KERN_INFO "Stopped watchdog timer.\n"); } - clear_bit(0,&indydog_alive); - expect_close = 0; + indydog_alive = 0; + return 0; } static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) { - /* Can't seek (pwrite) on this device */ + /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) return -ESPIPE; /* Refresh the timer. */ if (len) { - if (!nowayout) { - size_t i; - - /* In case it was set long ago */ - expect_close = 0; - - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - expect_close = 42; - } - } indydog_ping(); } return len; @@ -139,17 +116,18 @@ static int indydog_ioctl(struct inode *inode, struct file *file, { int options, retval = -EINVAL; static struct watchdog_info ident = { - .options = WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE, - .firmware_version = 0, - .identity = "Hardware Watchdog for SGI IP22", + .options = WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = "Hardware Watchdog for SGI IP22", }; switch (cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + if (copy_to_user((struct watchdog_info *)arg, + &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: @@ -165,14 +143,12 @@ static int indydog_ioctl(struct inode *inode, struct file *file, if (get_user(options, (int *)arg)) return -EFAULT; - if (options & WDIOS_DISABLECARD) - { + if (options & WDIOS_DISABLECARD) { indydog_stop(); retval = 0; } - if (options & WDIOS_ENABLECARD) - { + if (options & WDIOS_ENABLECARD) { indydog_start(); retval = 0; } @@ -184,40 +160,37 @@ static int indydog_ioctl(struct inode *inode, struct file *file, static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if (code==SYS_DOWN || code==SYS_HALT) { - /* Turn the WDT off */ - indydog_stop(); - } + if (code == SYS_DOWN || code == SYS_HALT) + indydog_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } static struct file_operations indydog_fops = { - .owner = THIS_MODULE, - .write = indydog_write, - .ioctl = indydog_ioctl, - .open = indydog_open, - .release= indydog_release, + .owner = THIS_MODULE, + .write = indydog_write, + .ioctl = indydog_ioctl, + .open = indydog_open, + .release = indydog_release, }; static struct miscdevice indydog_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &indydog_fops, + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &indydog_fops, }; static struct notifier_block indydog_notifier = { .notifier_call = indydog_notify_sys, }; -static char banner[] __initdata = KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; +static char banner[] __initdata = + KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; static int __init watchdog_init(void) { int ret; - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - ret = register_reboot_notifier(&indydog_notifier); if (ret) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", -- cgit v1.2.3 From 901c036a356f28ab412c39c93b2aa808c0ace3c3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:20:17 -0700 Subject: [PATCH] fix linker trouble with CONFIG_FB_RIVA_I2C=y and modular I2C From: Adrian Bunk > This version causes linker trouble with > CONFIG_I2C=m > CONFIG_I2C_ALGOBIT=m > CONFIG_FB_RIVA_I2C=y > > CC init/version.o > LD init/built-in.o > LD .tmp_vmlinux1 > drivers/built-in.o(.text+0xda101): In function `riva_setup_i2c_bus': > : undefined reference to `i2c_bit_add_bus' > drivers/built-in.o(.text+0xda218): In function `riva_delete_i2c_busses': > : undefined reference to `i2c_bit_del_bus' > drivers/built-in.o(.text+0xda237): In function `riva_delete_i2c_busses': > : undefined reference to `i2c_bit_del_bus' > drivers/built-in.o(.text+0xda2c9): In function `riva_do_probe_i2c_edid': > : undefined reference to `i2c_transfer' > make: *** [.tmp_vmlinux1] Error 1 >... The problem is: FB_RIVA=y FB_RIVA_I2C=y I2C=m I2C_ALGOBIT=m The patch below fixes this. Besides this, it contains: - help text by Antonino A. Daplas - converted spaces to tabs - it was forgotten that FB_RIVA_I2C requires I2C_ALGOBIT Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index b8ea9ab1e6a9..1e33ac4d16c8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -424,6 +424,8 @@ config E1355_FB_BASE config FB_RIVA tristate "nVidia Riva support" depends on FB && PCI + select I2C_ALGOBIT if FB_RIVA_I2C + select I2C if FB_RIVA_I2C help This driver supports graphics boards with the nVidia Riva/Geforce chips. @@ -434,7 +436,7 @@ config FB_RIVA config FB_RIVA_I2C bool "Enable DDC Support" - depends on FB_RIVA && I2C + depends on FB_RIVA help This enables I2C support for nVidia Chipsets. This is used only for getting EDID information from the attached display -- cgit v1.2.3 From 537bc91c60680d6c9c33dbc2a6972613fffdeb64 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:20:28 -0700 Subject: [PATCH] Fix early CPU vendor detection for non intel cpus From: Andi Kleen Early CPU detect can only work after the various sub CPU drivers have registered their devices. Currently the vendor would be always 0, which is Intel. This prevents Athlons from being recognized as buggy PPros and fixes some other workarounds for non Intel CPUs too. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index fbb6a591c234..ed44734ab6dd 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -473,7 +473,6 @@ void early_cpu_detect(void); void __init early_cpu_init(void) { - early_cpu_detect(); intel_cpu_init(); cyrix_init_cpu(); nsc_init_cpu(); @@ -483,6 +482,7 @@ void __init early_cpu_init(void) rise_init_cpu(); nexgen_init_cpu(); umc_init_cpu(); + early_cpu_detect(); #ifdef CONFIG_DEBUG_PAGEALLOC /* pse is not compatible with on-the-fly unmapping, -- cgit v1.2.3 From 77a5fdb07e54e8467aabdaf26cc5c31d2660a929 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:20:39 -0700 Subject: [PATCH] OProfile: allow normal user to trigger sample dumps From: John Levon In 2.4, OProfile allowed normal users to trigger sample dumps (useful under low sample load). The patch below, by Will Cohen, allows this for 2.6 too. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/oprofile/oprofile_files.c | 2 +- drivers/oprofile/oprofilefs.c | 25 +++++++++++++++++++------ include/linux/oprofile.h | 3 +++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index 381abef6fc07..b22d4ea3f9b5 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c @@ -90,7 +90,7 @@ static struct file_operations dump_fops = { void oprofile_create_files(struct super_block * sb, struct dentry * root) { oprofilefs_create_file(sb, root, "enable", &enable_fops); - oprofilefs_create_file(sb, root, "dump", &dump_fops); + oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index 2824c24c7f49..4b394ac31435 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c @@ -165,7 +165,8 @@ static struct file_operations ulong_ro_fops = { static struct dentry * __oprofilefs_create_file(struct super_block * sb, - struct dentry * root, char const * name, struct file_operations * fops) + struct dentry * root, char const * name, struct file_operations * fops, + int perm) { struct dentry * dentry; struct inode * inode; @@ -176,7 +177,7 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb, dentry = d_alloc(root, &qname); if (!dentry) return 0; - inode = oprofilefs_get_inode(sb, S_IFREG | 0644); + inode = oprofilefs_get_inode(sb, S_IFREG | perm); if (!inode) { dput(dentry); return 0; @@ -190,7 +191,8 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb, int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, char const * name, unsigned long * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &ulong_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &ulong_fops, 0644); if (!d) return -EFAULT; @@ -202,7 +204,8 @@ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root, char const * name, unsigned long * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &ulong_ro_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &ulong_ro_fops, 0444); if (!d) return -EFAULT; @@ -227,7 +230,8 @@ static struct file_operations atomic_ro_fops = { int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, char const * name, atomic_t * val) { - struct dentry * d = __oprofilefs_create_file(sb, root, name, &atomic_ro_fops); + struct dentry * d = __oprofilefs_create_file(sb, root, name, + &atomic_ro_fops, 0444); if (!d) return -EFAULT; @@ -239,7 +243,16 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, int oprofilefs_create_file(struct super_block * sb, struct dentry * root, char const * name, struct file_operations * fops) { - if (!__oprofilefs_create_file(sb, root, name, fops)) + if (!__oprofilefs_create_file(sb, root, name, fops, 0644)) + return -EFAULT; + return 0; +} + + +int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, + char const * name, struct file_operations * fops, int perm) +{ + if (!__oprofilefs_create_file(sb, root, name, fops, perm)) return -EFAULT; return 0; } diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index 80cfea0fa65f..f17c89c37c72 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -65,6 +65,9 @@ extern void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, */ int oprofilefs_create_file(struct super_block * sb, struct dentry * root, char const * name, struct file_operations * fops); + +int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, + char const * name, struct file_operations * fops, int perm); /** Create a file for read/write access to an unsigned long. */ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, -- cgit v1.2.3 From 4c03b0737e45f335f0ad30786644f6fb6384f8c3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:20:50 -0700 Subject: [PATCH] SubmittingDrivers fix From: Jesper Juhl Here's a small patch that lists X.Org as well as XFree86 in Documentation/SubmittingDrivers in the section talking about video drivers. Signed-off-by: Jesper Juhl Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/SubmittingDrivers | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers index 293591a884fe..2630629d7ab5 100644 --- a/Documentation/SubmittingDrivers +++ b/Documentation/SubmittingDrivers @@ -3,7 +3,8 @@ Submitting Drivers For The Linux Kernel This document is intended to explain how to submit device drivers to the various kernel trees. Note that if you are interested in video card drivers -you should probably talk to XFree86 (http://www.xfree86.org) instead. +you should probably talk to XFree86 (http://www.xfree86.org/) and/or X.Org +(http://x.org/) instead. Also read the Documentation/SubmittingPatches document. -- cgit v1.2.3 From 0a88d6091a146d1a25f3736f40c5d017a301f487 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:01 -0700 Subject: [PATCH] Core fbcon fixes From: "Antonino A. Daplas" This patch fixes the following bugs/regressions for fbcon: 1. Initialize and update global arrays used by fbcon during initialization and and by set_con2fbmap code. 2. Fixed screen corruption (white rectangle) at initial mode setting plaguing cards with VGA cores and with VGA console enabled. (vga16fb, however, still shows remnants of previous text if boot logo is enabled) 3. Improved fbcon_startup/fbcon_init code. 4. Fixed set_con2fbmap code -- should support multiple devices mapped to Signed-off-by: Antonino A. Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 332 +++++++++++++++++++++++++++++++++--------- drivers/video/fbmem.c | 16 +- include/linux/fb.h | 1 + 3 files changed, 272 insertions(+), 77 deletions(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index e928f4ed6ae4..f25e11b649ff 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -118,6 +118,9 @@ static int fbcon_is_default = 1; /* font data */ static char fontname[40]; +/* current fb_info */ +static int info_idx = -1; + #define REFCOUNT(fd) (((int *)(fd))[-1]) #define FNTSIZE(fd) (((int *)(fd))[-2]) #define FNTCHARCNT(fd) (((int *)(fd))[-3]) @@ -165,6 +168,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op); static int fbcon_set_palette(struct vc_data *vc, unsigned char *table); static int fbcon_scrolldelta(struct vc_data *vc, int lines); +void accel_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only); /* @@ -177,6 +182,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count); static __inline__ void ypan_down(struct vc_data *vc, int count); static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, int dy, int dx, int height, int width, u_int y_break); +static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc); #ifdef CONFIG_MAC /* @@ -194,9 +200,14 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) static void fb_flashcursor(void *private) { struct fb_info *info = (struct fb_info *) private; + struct vc_data *vc = NULL; + + if (info->currcon != -1) + vc = vc_cons[info->currcon].d; - if (!info || info->state != FBINFO_STATE_RUNNING || - info->cursor.rop == ROP_COPY) + if (info->state != FBINFO_STATE_RUNNING || + info->cursor.rop == ROP_COPY || !vc || !CON_IS_VISIBLE(vc) + || registered_fb[(int) con2fb_map[vc->vc_num]] != info) return; acquire_console_sem(); info->cursor.enable ^= 1; @@ -218,17 +229,12 @@ static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) } #endif -static void cursor_timer_handler(unsigned long dev_addr); - -static struct timer_list cursor_timer = - TIMER_INITIALIZER(cursor_timer_handler, 0, 0); - static void cursor_timer_handler(unsigned long dev_addr) { struct fb_info *info = (struct fb_info *) dev_addr; - schedule_work(&info->queue); - mod_timer(&cursor_timer, jiffies + HZ/5); + schedule_work(&info->queue); + mod_timer(&info->cursor_timer, jiffies + HZ/5); } int __init fb_console_setup(char *this_opt) @@ -285,6 +291,28 @@ int __init fb_console_setup(char *this_opt) __setup("fbcon=", fb_console_setup); +static int search_fb_in_map(int idx) +{ + int i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map[i] == idx) + return 1; + } + return 0; +} + +static int search_for_mapped_con(void) +{ + int i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map[i] != -1) + return 1; + } + return 0; +} + /** * set_con2fb_map - map console to frame buffer device * @unit: virtual console number to map @@ -296,12 +324,74 @@ __setup("fbcon=", fb_console_setup); int set_con2fb_map(int unit, int newidx) { struct vc_data *vc = vc_cons[unit].d; + int oldidx = con2fb_map[unit]; + struct fb_info *info = registered_fb[newidx]; + struct fb_info *oldinfo = registered_fb[oldidx]; + int found; + + if (!search_for_mapped_con()) { + info_idx = newidx; + fb_console_init(); + return 0; + } + if (oldidx == newidx) + return 0; if (!vc) - return -ENODEV; + return -ENODEV; + found = search_fb_in_map(newidx); + + acquire_console_sem(); con2fb_map[unit] = newidx; - fbcon_is_default = (vc->vc_sw == &fb_con) ? 1 : 0; - return take_over_console(&fb_con, unit, unit, fbcon_is_default); + if (!found) { + if (!try_module_get(info->fbops->owner)) { + release_console_sem(); + return -ENODEV; + } + if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { + module_put(info->fbops->owner); + release_console_sem(); + return -ENODEV; + } + } + + /* + * If old fb is not mapped to any of the consoles, + * fbcon should release it. + */ + if (oldinfo && !search_fb_in_map(oldidx)) { + int err; + + if (info->queue.func == fb_flashcursor) + del_timer_sync(&oldinfo->cursor_timer); + if (oldinfo->fbops->fb_release) { + err = oldinfo->fbops->fb_release(oldinfo, 0); + if (err) { + con2fb_map[unit] = oldidx; + release_console_sem(); + return err; + } + } + module_put(oldinfo->fbops->owner); + } + info->currcon = -1; + if (!found) { + if (!info->queue.func || info->queue.func == fb_flashcursor) { + if (!info->queue.func) + INIT_WORK(&info->queue, fb_flashcursor, info); + + init_timer(&info->cursor_timer); + info->cursor_timer.function = cursor_timer_handler; + info->cursor_timer.expires = jiffies + HZ / 5; + info->cursor_timer.data = (unsigned long ) info; + add_timer(&info->cursor_timer); + } + } + if (info->fbops->fb_set_par) + info->fbops->fb_set_par(info); + fbcon_set_disp(info, vc); + release_console_sem(); + return 0; } /* @@ -443,9 +533,8 @@ static const char *fbcon_startup(void) struct vc_data *vc = vc_cons[fg_console].d; struct font_desc *font = NULL; struct module *owner; - struct fb_info *info; - static int done = 0; - int cols, rows; + struct fb_info *info = NULL; + int rows, cols; int irqres; irqres = 1; @@ -453,20 +542,24 @@ static const char *fbcon_startup(void) * If num_registered_fb is zero, this is a call for the dummy part. * The frame buffer devices weren't initialized yet. */ - if (!num_registered_fb || done) + if (!num_registered_fb || info_idx == -1) return display_desc; - done = 1; - - info = registered_fb[0]; - if (!info) return NULL; + /* + * Instead of blindly using registered_fb[0], we use info_idx, set by + * fb_console_init(); + */ + info = registered_fb[info_idx]; + if (!info) + return NULL; info->currcon = -1; owner = info->fbops->owner; if (!try_module_get(owner)) return NULL; - if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) + if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { module_put(owner); - + return NULL; + } if (info->fix.type != FB_TYPE_TEXT) { if (fbcon_softback_size) { if (!softback_buf) { @@ -503,15 +596,8 @@ static const char *fbcon_startup(void) vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ } - /* - * We must always set the mode. The mode of the previous console - * driver could be in the same resolution but we are using different - * hardware so we have to initialize the hardware. - */ - if (info->fbops->fb_set_par) - info->fbops->fb_set_par(info); - cols = info->var.xres/vc->vc_font.width; - rows = info->var.yres/vc->vc_font.height; + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; vc_resize(vc->vc_num, cols, rows); DPRINTK("mode: %s\n", info->fix.id); @@ -585,10 +671,12 @@ static const char *fbcon_startup(void) * default timer to flash the cursor. */ if (!info->queue.func) { INIT_WORK(&info->queue, fb_flashcursor, info); - - cursor_timer.expires = jiffies + HZ / 5; - cursor_timer.data = (unsigned long ) info; - add_timer(&cursor_timer); + + init_timer(&info->cursor_timer); + info->cursor_timer.function = cursor_timer_handler; + info->cursor_timer.expires = jiffies + HZ / 5; + info->cursor_timer.data = (unsigned long ) info; + add_timer(&info->cursor_timer); } return display_desc; } @@ -599,10 +687,12 @@ static void fbcon_init(struct vc_data *vc, int init) struct vc_data **default_mode = vc->vc_display_fg; struct display *t, *p = &fb_display[vc->vc_num]; int display_fg = (*default_mode)->vc_num; - int logo = 1, rows, cols, charcnt = 256; + int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; unsigned short *save = NULL, *r, *q; int cap = info->flags; + if (info_idx == -1 || info == NULL) + return; if (vc->vc_num != display_fg || (info->flags & FBINFO_MODULE) || (info->fix.type == FB_TYPE_TEXT)) logo = 0; @@ -612,16 +702,17 @@ static void fbcon_init(struct vc_data *vc, int init) /* If we are not the first console on this fb, copy the font from that console */ t = &fb_display[display_fg]; - vc->vc_font.width = (*default_mode)->vc_font.width; - vc->vc_font.height = (*default_mode)->vc_font.height; - vc->vc_font.data = p->fontdata = t->fontdata; - p->userfont = t->userfont; - if (p->userfont) { - REFCOUNT(p->fontdata)++; - charcnt = FNTCHARCNT(p->fontdata); + if (!vc->vc_font.data) { + vc->vc_font.data = p->fontdata = t->fontdata; + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; + con_copy_unimap(vc->vc_num, display_fg); } - con_copy_unimap(vc->vc_num, display_fg); - + if (p->userfont) + charcnt = FNTCHARCNT(p->fontdata); vc->vc_can_do_color = info->var.bits_per_pixel != 1; vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { @@ -631,12 +722,24 @@ static void fbcon_init(struct vc_data *vc, int init) if (vc->vc_can_do_color) vc->vc_complement_mask <<= 1; } + cols = vc->vc_cols; + rows = vc->vc_rows; + new_cols = info->var.xres / vc->vc_font.width; + new_rows = info->var.yres / vc->vc_font.height; + vc_resize(vc->vc_num, new_cols, new_rows); + /* + * We must always set the mode. The mode of the previous console + * driver could be in the same resolution but we are using different + * hardware so we have to initialize the hardware. + * + * We need to do it in fbcon_init() to prevent screen corruption. + */ + if (CON_IS_VISIBLE(vc) && info->fbops->fb_set_par) + info->fbops->fb_set_par(info); - cols = info->var.xres / vc->vc_font.width; - rows = info->var.yres / vc->vc_font.height; - vc_resize(vc->vc_num, cols, rows); - if ((cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED)) + if ((cap & FBINFO_HWACCEL_COPYAREA) && + !(cap & FBINFO_HWACCEL_DISABLED)) p->scrollmode = SCROLL_ACCEL; else /* default to something safe */ p->scrollmode = SCROLL_REDRAW; @@ -646,9 +749,9 @@ static void fbcon_init(struct vc_data *vc, int init) * vc_{cols,rows}, but we must not set those if we are only * resizing the console. */ - if (init) { - vc->vc_cols = cols; - vc->vc_rows = rows; + if (!init) { + vc->vc_cols = new_cols; + vc->vc_rows = new_rows; } if (logo) { @@ -665,14 +768,15 @@ static void fbcon_init(struct vc_data *vc, int init) for (r = q - logo_lines * cols; r < q; r++) if (scr_readw(r) != vc->vc_video_erase_char) break; - if (r != q && rows >= rows + logo_lines) { - save = kmalloc(logo_lines * cols * 2, GFP_KERNEL); + if (r != q && new_rows >= rows + logo_lines) { + save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL); if (save) { + int i = cols < new_cols ? cols : new_cols; scr_memsetw(save, vc->vc_video_erase_char, - logo_lines * cols * 2); + logo_lines * new_cols * 2); r = q - step; - for (cnt = 0; cnt < logo_lines; cnt++, r += cols) - scr_memcpyw(save + cnt * cols, r, 2 * cols); + for (cnt = 0; cnt < logo_lines; cnt++, r += i) + scr_memcpyw(save + cnt * new_cols, r, 2 * i); r = q; } } @@ -688,19 +792,19 @@ static void fbcon_init(struct vc_data *vc, int init) vc->vc_pos += logo_lines * vc->vc_size_row; } } - scr_memsetw((unsigned short *) vc->vc_origin, - vc->vc_video_erase_char, - vc->vc_size_row * logo_lines); - if (CON_IS_VISIBLE(vc) && vt_cons[vc->vc_num]->vc_mode == KD_TEXT) { accel_clear_margins(vc, info, 0); update_screen(vc->vc_num); } + scr_memsetw((unsigned short *) vc->vc_origin, + vc->vc_video_erase_char, + vc->vc_size_row * logo_lines); + if (save) { q = (unsigned short *) (vc->vc_origin + vc->vc_size_row * rows); - scr_memcpyw(q, save, logo_lines * cols * 2); + scr_memcpyw(q, save, logo_lines * new_cols * 2); vc->vc_y += logo_lines; vc->vc_pos += logo_lines * vc->vc_size_row; kfree(save); @@ -731,6 +835,8 @@ static void fbcon_deinit(struct vc_data *vc) { struct display *p = &fb_display[vc->vc_num]; + if (info_idx != -1) + return; fbcon_free_font(p); } @@ -925,7 +1031,8 @@ static void fbcon_cursor(struct vc_data *vc, int mode) cursor.set |= FB_CUR_SETHOT; } - if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) { + if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape) + || info->cursor.mask == NULL) { char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; @@ -984,6 +1091,57 @@ int update_var(int con, struct fb_info *info) return 0; } +static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc) +{ + struct display *p = &fb_display[vc->vc_num], *t; + struct vc_data **default_mode = vc->vc_display_fg; + int display_fg = (*default_mode)->vc_num; + int rows, cols, charcnt = 256; + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + t = &fb_display[display_fg]; + if (!vc->vc_font.data) { + vc->vc_font.data = p->fontdata = t->fontdata; + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; + con_copy_unimap(vc->vc_num, display_fg); + } + if (p->userfont) + charcnt = FNTCHARCNT(p->fontdata); + + vc->vc_can_do_color = info->var.bits_per_pixel != 1; + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + if (charcnt == 256) { + vc->vc_hi_font_mask = 0; + } else { + vc->vc_hi_font_mask = 0x100; + if (vc->vc_can_do_color) + vc->vc_complement_mask <<= 1; + } + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; + vc_resize(vc->vc_num, cols, rows); + if (CON_IS_VISIBLE(vc)) { + update_screen(vc->vc_num); + if (softback_buf) { + int l = fbcon_softback_size / vc->vc_size_row; + + if (l > 5) + softback_end = softback_buf + l * + vc->vc_size_row; + else { + /* Smaller scrollback makes no sense, and 0 + would screw the operation totally */ + softback_top = 0; + } + } + } + switch_screen(fg_console); +} + static __inline__ void ywrap_up(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; @@ -1537,6 +1695,7 @@ static int fbcon_switch(struct vc_data *vc) { struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; + int i; if (softback_top) { int l = fbcon_softback_size / vc->vc_size_row; @@ -1563,6 +1722,20 @@ static int fbcon_switch(struct vc_data *vc) } if (info) info->var.yoffset = p->yscroll = 0; + + /* + * FIXME: If we have multiple fbdev's loaded, we need to + * update all info->currcon. Perhaps, we can place this + * in a centralized structure, but this might break some + * drivers. + * + * info->currcon = vc->vc_num; + */ + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) + registered_fb[i]->currcon = vc->vc_num; + } + fbcon_resize(vc, vc->vc_cols, vc->vc_rows); switch (p->scrollmode) { case SCROLL_WRAP: @@ -1580,8 +1753,6 @@ static int fbcon_switch(struct vc_data *vc) scrollback_max = 0; scrollback_current = 0; - info->currcon = vc->vc_num; - update_var(vc->vc_num, info); fbcon_set_palette(vc, color_table); @@ -2186,6 +2357,7 @@ static void fbcon_resumed(struct fb_info *info) update_screen(vc->vc_num); } + static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { @@ -2199,6 +2371,7 @@ static int fbcon_event_notify(struct notifier_block *self, fbcon_resumed(info); break; } + return 0; } @@ -2229,27 +2402,42 @@ const struct consw fb_con = { .con_resize = fbcon_resize, }; -static struct notifier_block fbcon_event_notifer = { +static struct notifier_block fbcon_event_notifier = { .notifier_call = fbcon_event_notify, }; - static int fbcon_event_notifier_registered; int __init fb_console_init(void) { - int err; + int err, i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) + con2fb_map[i] = -1; if (!num_registered_fb) return -ENODEV; + if (info_idx == -1) { + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) { + info_idx = i; + break; + } + } + } + for (i = first_fb_vc; i <= last_fb_vc; i++) + con2fb_map[i] = info_idx; err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); - if (err) + if (err) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + con2fb_map[i] = -1; + } return err; - + } acquire_console_sem(); if (!fbcon_event_notifier_registered) { - fb_register_client(&fbcon_event_notifer); + fb_register_client(&fbcon_event_notifier); fbcon_event_notifier_registered = 1; } release_console_sem(); @@ -2262,7 +2450,7 @@ void __exit fb_console_exit(void) { acquire_console_sem(); if (fbcon_event_notifier_registered) { - fb_unregister_client(&fbcon_event_notifer); + fb_unregister_client(&fbcon_event_notifier); fbcon_event_notifier_registered = 0; } release_console_sem(); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 65a4021cece4..6162b5ab7c67 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -721,6 +721,7 @@ int fb_show_logo(struct fb_info *info) u32 *palette = NULL, *saved_pseudo_palette = NULL; unsigned char *logo_new = NULL; struct fb_image image; + struct fb_fillrect rect; int x; /* Return if the frame buffer is not mapped or suspended */ @@ -766,6 +767,12 @@ int fb_show_logo(struct fb_info *info) image.height = fb_logo.logo->height; image.dy = 0; + rect.dx = 0; + rect.dy = 0; + rect.color = 0; + rect.width = info->var.xres; + rect.height = fb_logo.logo->height; + info->fbops->fb_fillrect(info, &rect); for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { image.dx = x; @@ -1104,11 +1111,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, #endif /* CONFIG_KMOD */ if (!registered_fb[con2fb.framebuffer]) return -EINVAL; - if (con2fb.console != 0) - set_con2fb_map(con2fb.console-1, con2fb.framebuffer); - else - fb_console_init(); - return 0; + if (con2fb.console > 0 && con2fb.console < MAX_NR_CONSOLES) + return set_con2fb_map(con2fb.console-1, + con2fb.framebuffer); + return -EINVAL; #endif /* CONFIG_FRAMEBUFFER_CONSOLE */ case FBIOBLANK: acquire_console_sem(); diff --git a/include/linux/fb.h b/include/linux/fb.h index cc7f14febf7c..c2ff4024cc25 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -539,6 +539,7 @@ struct fb_info { struct fb_monspecs monspecs; /* Current Monitor specs */ struct fb_cursor cursor; /* Current cursor */ struct work_struct queue; /* Framebuffer event queue */ + struct timer_list cursor_timer; /* Cursor timer */ struct fb_pixmap pixmap; /* Image hardware mapper */ struct fb_pixmap sprite; /* Cursor hardware mapper */ struct fb_cmap cmap; /* Current cmap */ -- cgit v1.2.3 From 81d5fd846719a74a43ec5497ed469f88fb11cd85 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:13 -0700 Subject: [PATCH] fbdev: video mode change notify (fbset) From: "Antonino A. Daplas" This patch allows fbset to change the video mode and the console window size via the notifier call chain. It will only notify fbcon of mode changes from user space. Changes coming from upstream will be ignored. The code will only update the current console. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 53 +++++++++++++++++++++++++++++++++++++++++++ drivers/video/fbmem.c | 8 ++++++- include/linux/fb.h | 2 ++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index f25e11b649ff..58a9b8a8b722 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2358,6 +2358,56 @@ static void fbcon_resumed(struct fb_info *info) update_screen(vc->vc_num); } +static void fbcon_modechanged(struct fb_info *info) +{ + struct vc_data *vc = vc_cons[info->currcon].d; + struct display *p; + int rows, cols; + + if (info->currcon < 0 || vt_cons[info->currcon]->vc_mode != + KD_TEXT) + return; + p = &fb_display[vc->vc_num]; + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + vc->vc_can_do_color = info->var.bits_per_pixel != 1; + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + + if (CON_IS_VISIBLE(vc)) { + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; + vc_resize(vc->vc_num, cols, rows); + switch (p->scrollmode) { + case SCROLL_WRAP: + scrollback_phys_max = p->vrows - vc->vc_rows; + break; + case SCROLL_PAN: + scrollback_phys_max = p->vrows - 2 * vc->vc_rows; + if (scrollback_phys_max < 0) + scrollback_phys_max = 0; + break; + default: + scrollback_phys_max = 0; + break; + } + scrollback_max = 0; + scrollback_current = 0; + update_var(vc->vc_num, info); + fbcon_set_palette(vc, color_table); + update_screen(vc->vc_num); + if (softback_buf) { + int l = fbcon_softback_size / vc->vc_size_row; + if (l > 5) + softback_end = softback_buf + l * vc->vc_size_row; + else { + /* Smaller scrollback makes no sense, and 0 + would screw the operation totally */ + softback_top = 0; + } + } + } +} + static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { @@ -2370,6 +2420,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_RESUME: fbcon_resumed(info); break; + case FB_EVENT_MODE_CHANGE: + fbcon_modechanged(info); + break; } return 0; diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 6162b5ab7c67..bbdd131dbb34 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1005,7 +1005,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) fb_set_cmap(&info->cmap, 1, info); - notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info); + if (info->flags & FBINFO_MISC_MODECHANGEUSER) { + notifier_call_chain(&fb_notifier_list, + FB_EVENT_MODE_CHANGE, info); + info->flags &= ~FBINFO_MISC_MODECHANGEUSER; + } } } return 0; @@ -1056,7 +1060,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (copy_from_user(&var, (void *) arg, sizeof(var))) return -EFAULT; acquire_console_sem(); + info->flags |= FBINFO_MISC_MODECHANGEUSER; i = fb_set_var(info, &var); + info->flags &= ~FBINFO_MISC_MODECHANGEUSER; release_console_sem(); if (i) return i; if (copy_to_user((void *) arg, &var, sizeof(var))) diff --git a/include/linux/fb.h b/include/linux/fb.h index c2ff4024cc25..a25a0ae12656 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -530,6 +530,8 @@ struct fb_ops { #define FBINFO_HWACCEL_YPAN 0x2000 /* optional */ #define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */ +#define FBINFO_MISC_MODECHANGEUSER 0x10000 /* mode change request + from userspace */ struct fb_info { int node; -- cgit v1.2.3 From 0d7040ad559d36eaae430565d828c45da4e43268 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:24 -0700 Subject: [PATCH] ppc64: fix POWER3 NUMA init From: Anton Blanchard We were passing in the hole size as kB not pages to free_area_init which made the VM misbehave. This only hit on POWER3 because POWER4 and newer places IO above all memory and so doesnt have a hole. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/mm/numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c index c1c4d6cd0b32..222120298ab8 100644 --- a/arch/ppc64/mm/numa.c +++ b/arch/ppc64/mm/numa.c @@ -457,7 +457,7 @@ void __init paging_init(void) zones_size[ZONE_DMA] = end_pfn - start_pfn; zholes_size[ZONE_DMA] = 0; if (nid == 0) - zholes_size[ZONE_DMA] = node0_io_hole_size; + zholes_size[ZONE_DMA] = node0_io_hole_size >> PAGE_SHIFT; dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); -- cgit v1.2.3 From c98476cb50a665294105f20e0521061767a9461b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:35 -0700 Subject: [PATCH] Add PPC85xx MAINTAINERS entry From: Kumar Gala Added myself to the MAINTAINERS file for 85xx. Added an entry into the CREDITS file for me. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- CREDITS | 6 ++++++ MAINTAINERS | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/CREDITS b/CREDITS index 3efc555b7fbd..29601a7bd6f0 100644 --- a/CREDITS +++ b/CREDITS @@ -1060,6 +1060,12 @@ S: USA N: Jeff Garzik E: jgarzik@pobox.com +N: Kumar Gala +E: kumar.gala@freescale.com +D: Embedded PowerPC 6xx/7xx/74xx/82xx/85xx support +S: Austin, Texas 78729 +S: USA + N: Jacques Gelinas E: jacques@solucorp.qc.ca D: Author of the Umsdos file system diff --git a/MAINTAINERS b/MAINTAINERS index 9d6c1955bd14..211ffa92b55b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1278,6 +1278,13 @@ W: http://www.penguinppc.org/ L: linuxppc-embedded@lists.linuxppc.org S: Maintained +LINUX FOR POWERPC EMBEDDED PPC85XX +P: Kumar Gala +M: kumar.gala@freescale.com +W: http://www.penguinppc.org/ +L: linuxppc-embedded@lists.linuxppc.org +S: Maintained + LLC (802.2) P: Arnaldo Carvalho de Melo M: acme@conectiva.com.br -- cgit v1.2.3 From d2c40dc029c95a1c6bf20b2e0ba558287510d1f8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:46 -0700 Subject: [PATCH] (o)profile Documentation/basic_profiling.txt updates From: bert hubert Signed-off-by: bert hubert Signed-off-by: John Levon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/basic_profiling.txt | 40 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/Documentation/basic_profiling.txt b/Documentation/basic_profiling.txt index cd3b422cc501..65e3dc2d4437 100644 --- a/Documentation/basic_profiling.txt +++ b/Documentation/basic_profiling.txt @@ -5,16 +5,19 @@ Thanks to John Levon, Dave Hansen, et al. for help writing this. is the thing you're trying to measure. Make sure you have the correct System.map / vmlinux referenced! -IMHO it's easier to use "make install" for linux and hack /sbin/installkernel -to copy config files, system.map, vmlinux to /boot. + +It is probably easiest to use "make install" for linux and hack +/sbin/installkernel to copy vmlinux to /boot, in addition to vmlinuz, +config, System.map, which are usually installed by default. Readprofile ----------- -You need a fixed readprofile command for 2.5 ... either get hold of -a current version from: +A recent readprofile command is needed for 2.6, such as found in util-linux +2.12a, which can be downloaded from: + http://www.kernel.org/pub/linux/utils/util-linux/ -or get readprofile binary fixed for 2.5 / akpm's 2.5 patch from -ftp://ftp.kernel.org/pub/linux/kernel/people/mbligh/tools/readprofile/ + +Most distributions will ship it already. Add "profile=2" to the kernel command line. @@ -24,25 +27,26 @@ dump output readprofile -m /boot/System.map > captured_profile Oprofile -------- -get source (I use 0.5) from http://oprofile.sourceforge.net/ -add "idle=poll" to the kernel command line +Get the source (I use 0.8) from http://oprofile.sourceforge.net/ +and add "idle=poll" to the kernel command line Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel ./configure --with-kernel-support make install -One time setup (pick appropriate one for your CPU): -P3 opcontrol --setup --vmlinux=/boot/vmlinux \ - --ctr0-event=CPU_CLK_UNHALTED --ctr0-count=100000 -Athlon/x86-64 opcontrol --setup --vmlinux=/boot/vmlinux \ - --ctr0-event=RETIRED_INSNS --ctr0-count=100000 -P4 opcontrol --setup --vmlinux=/boot/vmlinux \ - --ctr0-event=GLOBAL_POWER_EVENTS \ - --ctr0-unit-mask=1 --ctr0-count=100000 +For superior results, be sure to enable the local APIC. If opreport sees +a 0Hz CPU, APIC was not on. Be aware that idle=poll may mean a performance +penalty. + +One time setup: + opcontrol --setup --vmlinux=/boot/vmlinux -start daemon opcontrol --start-daemon clear opcontrol --reset start opcontrol --start stop opcontrol --stop -dump output oprofpp -dl -i /boot/vmlinux > output_file +dump output opreport > output_file + +To only report on the kernel, run opreport /boot/vmlinux > output_file + +A reset is needed to clear old statistics, which survive a reboot. -- cgit v1.2.3 From 75c4f2196bdab43b5d5fe3bce806b41a28b93bc4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:21:57 -0700 Subject: [PATCH] SELinux: Extend and revise calls to secondary module From: Stephen Smalley This patch extends the set of calls to the secondary security module by SELinux as well as revising a few existing calls to support other security modules and to more cleanly stack with the capability module. Please apply. Signed-off-by: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 94 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b2a1418ac28c..e1009456e6d4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1389,11 +1389,11 @@ static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effect { int error; - error = task_has_perm(current, target, PROCESS__SETCAP); + error = secondary_ops->capset_check(target, effective, inheritable, permitted); if (error) return error; - return secondary_ops->capset_check(target, effective, inheritable, permitted); + return task_has_perm(current, target, PROCESS__SETCAP); } static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, @@ -1427,6 +1427,10 @@ static int selinux_sysctl(ctl_table *table, int op) u32 tsid; int rc; + rc = secondary_ops->sysctl(table, op); + if (rc) + return rc; + tsec = current->security; rc = selinux_proc_get_sid(table->de, (op == 001) ? @@ -1690,7 +1694,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) static int selinux_bprm_check_security (struct linux_binprm *bprm) { - return 0; + return secondary_ops->bprm_check_security(bprm); } @@ -1708,12 +1712,7 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm) PROCESS__NOATSECURE, NULL, NULL); } - /* Note that we must include the legacy uid/gid test below - to retain it, as the new userland will simply use the - value passed by AT_SECURE to decide whether to enable - secure mode. */ - return ( atsecure || current->euid != current->uid || - current->egid != current->gid); + return (atsecure || secondary_ops->bprm_secureexec(bprm)); } static void selinux_bprm_free_security(struct linux_binprm *bprm) @@ -2058,6 +2057,12 @@ static int selinux_mount(char * dev_name, unsigned long flags, void * data) { + int rc; + + rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data); + if (rc) + return rc; + if (flags & MS_REMOUNT) return superblock_has_perm(current, nd->mnt->mnt_sb, FILESYSTEM__REMOUNT, NULL); @@ -2068,6 +2073,12 @@ static int selinux_mount(char * dev_name, static int selinux_umount(struct vfsmount *mnt, int flags) { + int rc; + + rc = secondary_ops->sb_umount(mnt, flags); + if (rc) + return rc; + return superblock_has_perm(current,mnt->mnt_sb, FILESYSTEM__UNMOUNT,NULL); } @@ -2111,6 +2122,11 @@ static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *ino static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) { + int rc; + + rc = secondary_ops->inode_unlink(dir, dentry); + if (rc) + return rc; return may_link(dir, dentry, MAY_UNLINK); } @@ -2141,6 +2157,12 @@ static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { + int rc; + + rc = secondary_ops->inode_mknod(dir, dentry, mode, dev); + if (rc) + return rc; + return may_create(dir, dentry, inode_mode_to_security_class(mode)); } @@ -2179,6 +2201,12 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na static int selinux_inode_permission(struct inode *inode, int mask, struct nameidata *nd) { + int rc; + + rc = secondary_ops->inode_permission(inode, mask, nd); + if (rc) + return rc; + if (!mask) { /* No permission to check. Existence test. */ return 0; @@ -2190,6 +2218,12 @@ static int selinux_inode_permission(struct inode *inode, int mask, static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) { + int rc; + + rc = secondary_ops->inode_setattr(dentry, iattr); + if (rc) + return rc; + if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_ATIME_SET | ATTR_MTIME_SET)) return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); @@ -2456,6 +2490,11 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned long flags) { u32 av; + int rc; + + rc = secondary_ops->file_mmap(file, prot, flags); + if (rc) + return rc; if (file) { /* read access is always possible with a mapping */ @@ -2476,6 +2515,12 @@ static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned lon static int selinux_file_mprotect(struct vm_area_struct *vma, unsigned long prot) { + int rc; + + rc = secondary_ops->file_mprotect(vma, prot); + if (rc) + return rc; + return selinux_file_mmap(vma->vm_file, prot, vma->vm_flags); } @@ -2573,6 +2618,12 @@ static int selinux_file_receive(struct file *file) static int selinux_task_create(unsigned long clone_flags) { + int rc; + + rc = secondary_ops->task_create(clone_flags); + if (rc) + return rc; + return task_has_perm(current, current, PROCESS__FORK); } @@ -2648,12 +2699,23 @@ static int selinux_task_setgroups(struct group_info *group_info) static int selinux_task_setnice(struct task_struct *p, int nice) { + int rc; + + rc = secondary_ops->task_setnice(p, nice); + if (rc) + return rc; + return task_has_perm(current,p, PROCESS__SETSCHED); } static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) { struct rlimit *old_rlim = current->rlim + resource; + int rc; + + rc = secondary_ops->task_setrlimit(resource, new_rlim); + if (rc) + return rc; /* Control the ability to change the hard limit (whether lowering or raising it), so that the hard limit can @@ -2688,6 +2750,11 @@ static int selinux_task_getscheduler(struct task_struct *p) static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) { u32 perm; + int rc; + + rc = secondary_ops->task_kill(p, info, sig); + if (rc) + return rc; if (info && ((unsigned long)info == 1 || (unsigned long)info == 2 || SI_FROMKERNEL(info))) @@ -3129,6 +3196,10 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, struct avc_audit_data ad; int err; + err = secondary_ops->unix_stream_connect(sock, other, newsk); + if (err) + return err; + isec = SOCK_INODE(sock)->i_security; other_isec = SOCK_INODE(other)->i_security; @@ -3847,6 +3918,11 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg) { u32 perms; + int rc; + + rc = secondary_ops->shm_shmat(shp, shmaddr, shmflg); + if (rc) + return rc; if (shmflg & SHM_RDONLY) perms = SHM__READ; -- cgit v1.2.3 From 01ae403b3f59152ab428dd2ddbbb64f06227763b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:22:08 -0700 Subject: [PATCH] fix allocate_pgdat comments From: "Martin J. Bligh" From: Andy Whitcroft The comments for i386 allocate_pgdat indicate that the routine should be modified to place the pgdat into node local memory. However, this has already been done as the pgdat is placed at node_remap_start_vaddr. This patch updates the comments to reflect this reality. Signed-off-by: Andy Whitcroft Signed-off-by: Martin J. Bligh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mm/discontig.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index c1de0903db02..ad04cfd73dc9 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c @@ -129,8 +129,11 @@ static void __init find_max_pfn_node(int nid) } /* - * Allocate memory for the pg_data_t via a crude pre-bootmem method - * We ought to relocate these onto their own node later on during boot. + * Allocate memory for the pg_data_t for this node via a crude pre-bootmem + * method. For node zero take this from the bottom of memory, for + * subsequent nodes place them at node_remap_start_vaddr which contains + * node local data in physically node local memory. See setup_memory() + * for details. */ static void __init allocate_pgdat(int nid) { -- cgit v1.2.3 From 4a37dd4c3d60b13cecc40e5cec9399bb4dc16344 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:22:20 -0700 Subject: [PATCH] drivers/media/video/tda9840.c: honour return code of i2c_add_driver() From: Michael Hunold i2c_add_driver() may actually fail, but my driver returns 0 regardless. Thanks to Arthur Othieno for this obviously correct patch. Signed-off-by: Michael Hunold Signed-off-by: Arthur Othieno Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/tda9840.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index d1e74ecf2c1d..fd8ac116c863 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -268,13 +268,12 @@ static struct i2c_driver driver = { .command = tda9840_command, }; -static int tda9840_init_module(void) +static int __init tda9840_init_module(void) { - i2c_add_driver(&driver); - return 0; + return i2c_add_driver(&driver); } -static void tda9840_cleanup_module(void) +static void __exit tda9840_cleanup_module(void) { i2c_del_driver(&driver); } @@ -285,4 +284,3 @@ module_exit(tda9840_cleanup_module); MODULE_AUTHOR("Michael Hunold "); MODULE_DESCRIPTION("tda9840 driver"); MODULE_LICENSE("GPL"); - -- cgit v1.2.3 From 1d5e0f0673afd6e7619ac8e975b9dbbc81fd8918 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:22:31 -0700 Subject: [PATCH] zap_pte_range speedup From: Hugh Dickins zap_pte_range is wasting time marking anon pages accessed: its original !PageSwapCache test should have been reinstated when page_mapping was changed to return swapper_space; or more simply, just check !PageAnon. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index 3df1f05e76b8..13a2a3a83ad7 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -407,7 +407,7 @@ static void zap_pte_range(struct mmu_gather *tlb, set_pte(ptep, pgoff_to_pte(page->index)); if (pte_dirty(pte)) set_page_dirty(page); - if (pte_young(pte) && page_mapping(page)) + if (pte_young(pte) && !PageAnon(page)) mark_page_accessed(page); tlb->freed++; page_remove_rmap(page); -- cgit v1.2.3 From c8e8d619be317afcc416bb9216af01961c335ec6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:22:42 -0700 Subject: [PATCH] h8300: delete obsolute header From: Yoshinori Sato - delete obsolute(unused) header file Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-h8300/h8300_ne.h | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 include/asm-h8300/h8300_ne.h diff --git a/include/asm-h8300/h8300_ne.h b/include/asm-h8300/h8300_ne.h deleted file mode 100644 index c797603f3819..000000000000 --- a/include/asm-h8300/h8300_ne.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************/ - -/* - * h8300_ne.h -- NE2000 in H8/300H Evalution Board. - * - * (C) Copyright 2002, Yoshinori Sato - */ - -/****************************************************************************/ -#ifndef h8300ne_h -#define h8300ne_h -/****************************************************************************/ - -#define H8300_NE_DEFINE -#include -#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ) -#undef H8300_NE_DEFINE - -/****************************************************************************/ -#endif /* h8300ne_h */ -- cgit v1.2.3 From aa888075d6c488002c4b3506196c68c15e45dc5c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:22:53 -0700 Subject: [PATCH] cirrusfb: major update From: David Eger This patch brings the cirrusfb driver up to date with 2.6. cirrusfb has suffered bit rot like you wouldn't believe (last updated... 2.3.x era?). The driver will now compile again, and you can change to a high resolution text mode with stty. Known defects: doesn't play nice with X, nor fbset. C = Cosmetic change L = Logical change A = API change W = register Writing change (1-CA) fb_info and cirrusfb_info: - mostly cosmetic, but a lot less confusing, and no more nasty casting. It used to be stylish to embed struct fb_info_gen (now struct fb_info) as the first member of struct clgenfb_info (now struct cirrusfb_info), and then you'd cast to the deisred struct. Now we pass the size of our data structure to framebuffer_alloc(), and we make fb_info and cirrusfb_info reference each other with pointers (as in radeonfb). In the old code, there two declarations were common: clgenfb_info *fb_info; clgenfb_info *info; since there's also a 'struct fb_info' now, I found this really confusing, and unified usage as: cirrusfb_info *cinfo; fb_info *info; This accounts for a lot of the search and replace cosmetic upgrade. (2-A) All of the FB knowledge of FB internals is gone in 2.6 (3-LW) revised maxclock numbers (cirrusfb_board_info_rec.maxclock[5]) In my quest to get fbset to work, I borrowed some maxclock data from the X.Org tree for various chipsets. It didn't really seem to help. oh well. (3-LA) upgraded PCI registration Instead of doing PCI walking from the driver, we hand off a pci_device_id table to the PCI subsystem and just get called when it finds a relevant board. (4-L) striking lots of __init and __initdata specifiers I was running into some things not working when I moved the call to init_vgachip() from the driver registration to set_par(). I thought perhaps this was due to some things being marked __init accidentally so I axed said annotations. Turns out it was something else. See 5. (5-LA) delayed chip initialization, nasty double-set_par() pseudo-bug Tony says that the fb drivers shouldn't do any chipset initialization until they get a set_par() call. This way, fb modules can be safely unloaded if no one gets around to using them, and the vga_con -> fbcon hand off is smoother, as fbcon can still grab the back-scroll data from vga_con... In any case, moving the calls to init_vgachip() and fbgen_do_set_var() from driver initialization to set_par() revealed that the cirrus register-writing function needs to be called twice for a mode change to work. I don't understand why. (6-LA) split clgen_decode_var() into the bits that check the var and the bits that actually generate register information (par/regs) to write Adding modedb hooks here might actually fix fbset, i think... (7-LW) No longer write the palette in init_vgachip() nor in set_par(). Someone else (fbcon?) seems to be making its own calls to setcolreg() for us. (8-LW) setcolreg() -- while removing all of the console cruft, I had to try to reconstitute the palette code. I think I got this right, but I could be off -- the penguin boots in the correct colors at least ;-) (9-L) pan_display() - we don't do wrap, silly. that's only on the amiga. (10-L) pan+BLT - to make pan play nicely with copyarea()/fillrect() I had to add a couple of calls to cirrusfb_WaitBLT() to make sure the engine is idle. (11-LW) cirrusfb_blank() - I upgraded the switch here to use the new VESA_* blanking mode constants. I think I translated the right logic for the right blanking levels. Signed-off-by: David Eger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/Kconfig | 2 +- drivers/video/Makefile | 2 +- drivers/video/cirrusfb.c | 2778 ++++++++++++++++++++-------------------------- drivers/video/fbmem.c | 8 +- 4 files changed, 1231 insertions(+), 1559 deletions(-) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 1e33ac4d16c8..d80e806d132a 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -40,7 +40,7 @@ config FB config FB_CIRRUS tristate "Cirrus Logic support" - depends on FB && (AMIGA || PCI) && BROKEN + depends on FB && (AMIGA || PCI) ---help--- This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 22644fc8deb8..52e37a0fcda3 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o obj-$(CONFIG_FB_OF) += offb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_IMSTT) += imsttfb.o cfbimgblt.o obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o -obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o +obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_TRIDENT) += tridentfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_S3TRIO) += S3triofb.o obj-$(CONFIG_FB_TGA) += tgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 237ec2ee50a8..f201c8f77ee7 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -1,10 +1,13 @@ /* - * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets + * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets * * Copyright 1999-2001 Jeff Garzik * * Contributors (thanks, all!) * + * David Eger: + * Overhaul for Linux 2.6 + * * Jeff Rugen: * Major contributions; Motorola PowerStack (PPC and PCI) support, * GD54xx, 1280x1024 mode support, change MCLK based on VCLK. @@ -15,9 +18,9 @@ * Lars Hecking: * Amiga updates and testing. * - * Original clgenfb author: Frank Neumann + * Original cirrusfb author: Frank Neumann * - * Based on retz3fb.c and clgen.c: + * Based on retz3fb.c and cirrusfb.c: * Copyright (C) 1997 Jes Sorensen * Copyright (C) 1996 Frank Neumann * @@ -31,7 +34,7 @@ * */ -#define CLGEN_VERSION "1.9.9.1" +#define CIRRUSFB_VERSION "2.0-pre2" #include #include @@ -63,15 +66,8 @@ #define isPReP 0 #endif -#include