diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/processor_perflib.c | 46 | ||||
-rw-r--r-- | drivers/char/agp/ali-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 22 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 8 | ||||
-rw-r--r-- | drivers/char/agp/nvidia-agp.c | 9 | ||||
-rw-r--r-- | drivers/char/agp/sgi-agp.c | 5 | ||||
-rw-r--r-- | drivers/char/agp/sis-agp.c | 278 | ||||
-rw-r--r-- | drivers/char/agp/sworks-agp.c | 23 | ||||
-rw-r--r-- | drivers/cpufreq/Kconfig | 61 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 47 | ||||
-rw-r--r-- | drivers/s390/block/dasd.c | 45 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 81 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 2 | ||||
-rw-r--r-- | drivers/s390/char/tape.h | 1 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.c | 29 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.h | 4 | ||||
-rw-r--r-- | drivers/s390/char/tape_core.c | 3 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.c | 240 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 52 | ||||
-rw-r--r-- | drivers/s390/net/qeth.h | 3 | ||||
-rw-r--r-- | drivers/s390/net/qeth_main.c | 77 | ||||
-rw-r--r-- | drivers/s390/net/qeth_mpc.h | 1 |
23 files changed, 653 insertions, 388 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 2f2e796..c4efc0c 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -433,49 +433,6 @@ static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) PDE(inode)->data); } -static ssize_t -acpi_processor_write_performance(struct file *file, - const char __user * buffer, - size_t count, loff_t * data) -{ - int result = 0; - struct seq_file *m = file->private_data; - struct acpi_processor *pr = m->private; - struct acpi_processor_performance *perf; - char state_string[12] = { '\0' }; - unsigned int new_state = 0; - struct cpufreq_policy policy; - - - if (!pr || (count > sizeof(state_string) - 1)) - return -EINVAL; - - perf = pr->performance; - if (!perf) - return -EINVAL; - - if (copy_from_user(state_string, buffer, count)) - return -EFAULT; - - state_string[count] = '\0'; - new_state = simple_strtoul(state_string, NULL, 0); - - if (new_state >= perf->state_count) - return -EINVAL; - - cpufreq_get_policy(&policy, pr->id); - - policy.cpu = pr->id; - policy.min = perf->states[new_state].core_frequency * 1000; - policy.max = perf->states[new_state].core_frequency * 1000; - - result = cpufreq_set_policy(&policy); - if (result) - return result; - - return count; -} - static void acpi_cpufreq_add_file(struct acpi_processor *pr) { struct proc_dir_entry *entry = NULL; @@ -487,10 +444,9 @@ static void acpi_cpufreq_add_file(struct acpi_processor *pr) /* add file 'performance' [R/W] */ entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, - S_IFREG | S_IRUGO | S_IWUSR, + S_IFREG | S_IRUGO, acpi_device_dir(device)); if (entry){ - acpi_processor_perf_fops.write = acpi_processor_write_performance; entry->proc_fops = &acpi_processor_perf_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 5b684fd..4941ddb 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -145,6 +145,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) void *addr = agp_generic_alloc_page(agp_bridge); u32 temp; + global_flush_tlb(); if (!addr) return NULL; @@ -160,6 +161,7 @@ static void ali_destroy_page(void * addr) if (addr) { global_cache_flush(); /* is this really needed? --hch */ agp_generic_destroy_page(addr); + global_flush_tlb(); } } diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index f902d71..45aeb91 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -51,28 +51,6 @@ int agp_memory_reserved; */ EXPORT_SYMBOL_GPL(agp_memory_reserved); -#if defined(CONFIG_X86) -int map_page_into_agp(struct page *page) -{ - int i; - i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); - /* Caller's responsibility to call global_flush_tlb() for - * performance reasons */ - return i; -} -EXPORT_SYMBOL_GPL(map_page_into_agp); - -int unmap_page_from_agp(struct page *page) -{ - int i; - i = change_page_attr(page, 1, PAGE_KERNEL); - /* Caller's responsibility to call global_flush_tlb() for - * performance reasons */ - return i; -} -EXPORT_SYMBOL_GPL(unmap_page_from_agp); -#endif - /* * Generic routines for handling agp_memory structures - * They use the basic page allocation routines to do the brunt of the work. diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 55392a4..9c69f2e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -186,8 +186,9 @@ static void *i8xx_alloc_pages(void) return NULL; if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) { + change_page_attr(page, 4, PAGE_KERNEL); global_flush_tlb(); - __free_page(page); + __free_pages(page, 2); return NULL; } global_flush_tlb(); @@ -209,7 +210,7 @@ static void i8xx_destroy_pages(void *addr) global_flush_tlb(); put_page(page); unlock_page(page); - free_pages((unsigned long)addr, 2); + __free_pages(page, 2); atomic_dec(&agp_bridge->current_memory_agp); } @@ -315,9 +316,6 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) struct agp_memory *new; void *addr; - if (pg_count != 1 && pg_count != 4) - return NULL; - switch (pg_count) { case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); global_flush_tlb(); diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 0c9dab5..6cd7373 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -320,11 +320,11 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev, u8 cap_ptr; nvidia_private.dev_1 = - pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); + pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); nvidia_private.dev_2 = - pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); + pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); nvidia_private.dev_3 = - pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); + pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) { printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 " @@ -443,6 +443,9 @@ static int __init agp_nvidia_init(void) static void __exit agp_nvidia_cleanup(void) { pci_unregister_driver(&agp_nvidia_pci_driver); + pci_dev_put(nvidia_private.dev_1); + pci_dev_put(nvidia_private.dev_2); + pci_dev_put(nvidia_private.dev_3); } module_init(agp_nvidia_init); diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index ee8f50e..cda608c 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -47,9 +47,8 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) nid = info->ca_closest_node; page = alloc_pages_node(nid, GFP_KERNEL, 0); - if (page == NULL) { - return 0; - } + if (!page) + return NULL; get_page(page); SetPageLocked(page); diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 125f428..eb1a1c7 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -143,96 +143,6 @@ static struct agp_bridge_driver sis_driver = { .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; -static struct agp_device_ids sis_agp_device_ids[] __devinitdata = -{ - { - .device_id = PCI_DEVICE_ID_SI_5591_AGP, - .chipset_name = "5591", - }, - { - .device_id = PCI_DEVICE_ID_SI_530, - .chipset_name = "530", - }, - { - .device_id = PCI_DEVICE_ID_SI_540, - .chipset_name = "540", - }, - { - .device_id = PCI_DEVICE_ID_SI_550, - .chipset_name = "550", - }, - { - .device_id = PCI_DEVICE_ID_SI_620, - .chipset_name = "620", - }, - { - .device_id = PCI_DEVICE_ID_SI_630, - .chipset_name = "630", - }, - { - .device_id = PCI_DEVICE_ID_SI_635, - .chipset_name = "635", - }, - { - .device_id = PCI_DEVICE_ID_SI_645, - .chipset_name = "645", - }, - { - .device_id = PCI_DEVICE_ID_SI_646, - .chipset_name = "646", - }, - { - .device_id = PCI_DEVICE_ID_SI_648, - .chipset_name = "648", - }, - { - .device_id = PCI_DEVICE_ID_SI_650, - .chipset_name = "650", - }, - { - .device_id = PCI_DEVICE_ID_SI_651, - .chipset_name = "651", - }, - { - .device_id = PCI_DEVICE_ID_SI_655, - .chipset_name = "655", - }, - { - .device_id = PCI_DEVICE_ID_SI_661, - .chipset_name = "661", - }, - { - .device_id = PCI_DEVICE_ID_SI_730, - .chipset_name = "730", - }, - { - .device_id = PCI_DEVICE_ID_SI_735, - .chipset_name = "735", - }, - { - .device_id = PCI_DEVICE_ID_SI_740, - .chipset_name = "740", - }, - { - .device_id = PCI_DEVICE_ID_SI_741, - .chipset_name = "741", - }, - { - .device_id = PCI_DEVICE_ID_SI_745, - .chipset_name = "745", - }, - { - .device_id = PCI_DEVICE_ID_SI_746, - .chipset_name = "746", - }, - { - .device_id = PCI_DEVICE_ID_SI_760, - .chipset_name = "760", - }, - { }, /* dummy final entry, always present */ -}; - - // chipsets that require the 'delay hack' static int sis_broken_chipsets[] __devinitdata = { PCI_DEVICE_ID_SI_648, @@ -269,29 +179,15 @@ static void __devinit sis_get_driver(struct agp_bridge_data *bridge) static int __devinit agp_sis_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct agp_device_ids *devs = sis_agp_device_ids; struct agp_bridge_data *bridge; u8 cap_ptr; - int j; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) return -ENODEV; - /* probe for known chipsets */ - for (j = 0; devs[j].chipset_name; j++) { - if (pdev->device == devs[j].device_id) { - printk(KERN_INFO PFX "Detected SiS %s chipset\n", - devs[j].chipset_name); - goto found; - } - } - - printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n", - pdev->device); - return -ENODEV; -found: + printk(KERN_INFO PFX "Detected SiS chipset - id:%i\n", pdev->device); bridge = agp_alloc_bridge(); if (!bridge) return -ENOMEM; @@ -320,12 +216,172 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev) static struct pci_device_id agp_sis_pci_table[] = { { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_5591_AGP, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_530, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_540, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_550, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_620, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_630, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_635, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_645, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_646, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_648, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_650, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_651, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_655, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_661, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_730, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_735, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_740, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_741, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_745, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_746, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_760, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { } }; diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 55212a3..551ef25 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -455,15 +455,6 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, u32 temp, temp2; u8 cap_ptr = 0; - /* Everything is on func 1 here so we are hardcoding function one */ - bridge_dev = pci_find_slot((unsigned int)pdev->bus->number, - PCI_DEVFN(0, 1)); - if (!bridge_dev) { - printk(KERN_INFO PFX "Detected a Serverworks chipset " - "but could not find the secondary device.\n"); - return -ENODEV; - } - cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); switch (pdev->device) { @@ -483,6 +474,15 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, return -ENODEV; } + /* Everything is on func 1 here so we are hardcoding function one */ + bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number, + PCI_DEVFN(0, 1)); + if (!bridge_dev) { + printk(KERN_INFO PFX "Detected a Serverworks chipset " + "but could not find the secondary device.\n"); + return -ENODEV; + } + serverworks_private.svrwrks_dev = bridge_dev; serverworks_private.gart_addr_ofs = 0x10; @@ -515,7 +515,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, bridge->driver = &sworks_driver; bridge->dev_private_data = &serverworks_private, - bridge->dev = pdev; + bridge->dev = pci_dev_get(pdev); pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); @@ -525,8 +525,11 @@ static void __devexit agp_serverworks_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); + pci_dev_put(bridge->dev); agp_remove_bridge(bridge); agp_put_bridge(bridge); + pci_dev_put(serverworks_private.svrwrks_dev); + serverworks_private.svrwrks_dev = NULL; } static struct pci_device_id agp_serverworks_pci_table[] = { diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index d155e81..993fa7b 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -9,6 +9,9 @@ config CPU_FREQ clock speed, you need to either enable a dynamic cpufreq governor (see below) after boot, or use a userspace tool. + To compile this driver as a module, choose M here: the + module will be called cpufreq. + For details, take a look at <file:Documentation/cpu-freq>. If in doubt, say N. @@ -16,7 +19,7 @@ config CPU_FREQ if CPU_FREQ config CPU_FREQ_TABLE - tristate + tristate config CPU_FREQ_DEBUG bool "Enable CPUfreq debugging" @@ -32,19 +35,26 @@ config CPU_FREQ_DEBUG 4 to activate CPUfreq governor debugging config CPU_FREQ_STAT - tristate "CPU frequency translation statistics" - select CPU_FREQ_TABLE - default y - help - This driver exports CPU frequency statistics information through sysfs - file system + tristate "CPU frequency translation statistics" + select CPU_FREQ_TABLE + default y + help + This driver exports CPU frequency statistics information through sysfs + file system. + + To compile this driver as a module, choose M here: the + module will be called cpufreq_stats. + + If in doubt, say N. config CPU_FREQ_STAT_DETAILS - bool "CPU frequency translation statistics details" - depends on CPU_FREQ_STAT - help - This will show detail CPU frequency translation table in sysfs file - system + bool "CPU frequency translation statistics details" + depends on CPU_FREQ_STAT + help + This will show detail CPU frequency translation table in sysfs file + system. + + If in doubt, say N. # Note that it is not currently possible to set the other governors (such as ondemand) # as the default, since if they fail to initialise, cpufreq will be @@ -78,29 +88,38 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE endchoice config CPU_FREQ_GOV_PERFORMANCE - tristate "'performance' governor" - help + tristate "'performance' governor" + help This cpufreq governor sets the frequency statically to the highest available CPU frequency. + To compile this driver as a module, choose M here: the + module will be called cpufreq_performance. + If in doubt, say Y. config CPU_FREQ_GOV_POWERSAVE - tristate "'powersave' governor" - help + tristate "'powersave' governor" + help This cpufreq governor sets the frequency statically to the lowest available CPU frequency. + To compile this driver as a module, choose M here: the + module will be called cpufreq_powersave. + If in doubt, say Y. config CPU_FREQ_GOV_USERSPACE - tristate "'userspace' governor for userspace frequency scaling" - help + tristate "'userspace' governor for userspace frequency scaling" + help Enable this cpufreq governor when you either want to set the CPU frequency manually or when an userspace program shall be able to set the CPU dynamically, like on LART <http://www.lartmaker.nl/>. + To compile this driver as a module, choose M here: the + module will be called cpufreq_userspace. + For details, take a look at <file:Documentation/cpu-freq/>. If in doubt, say Y. @@ -116,6 +135,9 @@ config CPU_FREQ_GOV_ONDEMAND do fast frequency switching (i.e, very low latency frequency transitions). + To compile this driver as a module, choose M here: the + module will be called cpufreq_ondemand. + For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. @@ -136,6 +158,9 @@ config CPU_FREQ_GOV_CONSERVATIVE step-by-step latency issues between the minimum and maximum frequency transitions in the CPU) you will probably want to use this governor. + To compile this driver as a module, choose M here: the + module will be called cpufreq_conservative. + For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3162010..893dbaf 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -768,6 +768,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) unlock_policy_rwsem_write(cpu); goto err_out; } + policy->user_policy.min = policy->cpuinfo.min_freq; + policy->user_policy.max = policy->cpuinfo.max_freq; + policy->user_policy.governor = policy->governor; #ifdef CONFIG_SMP for_each_cpu_mask(j, policy->cpus) { @@ -858,10 +861,13 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) policy->governor = NULL; /* to assure that the starting sequence is * run in cpufreq_set_policy */ - unlock_policy_rwsem_write(cpu); /* set default policy */ - ret = cpufreq_set_policy(&new_policy); + ret = __cpufreq_set_policy(policy, &new_policy); + policy->user_policy.policy = policy->policy; + + unlock_policy_rwsem_write(cpu); + if (ret) { dprintk("setting policy failed\n"); goto err_out_unregister; @@ -1620,43 +1626,6 @@ error_out: } /** - * cpufreq_set_policy - set a new CPUFreq policy - * @policy: policy to be set. - * - * Sets a new CPU frequency and voltage scaling policy. - */ -int cpufreq_set_policy(struct cpufreq_policy *policy) -{ - int ret = 0; - struct cpufreq_policy *data; - - if (!policy) - return -EINVAL; - - data = cpufreq_cpu_get(policy->cpu); - if (!data) - return -EINVAL; - - if (unlikely(lock_policy_rwsem_write(policy->cpu))) - return -EINVAL; - - - ret = __cpufreq_set_policy(data, policy); - data->user_policy.min = data->min; - data->user_policy.max = data->max; - data->user_policy.policy = data->policy; - data->user_policy.governor = data->governor; - - unlock_policy_rwsem_write(policy->cpu); - - cpufreq_cpu_put(data); - - return ret; -} -EXPORT_SYMBOL(cpufreq_set_policy); - - -/** * cpufreq_update_policy - re-evaluate an existing cpufreq policy * @cpu: CPU which shall be re-evaluated * diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index e71929d..9775210 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2174,6 +2174,51 @@ dasd_generic_notify(struct ccw_device *cdev, int event) return ret; } +struct dasd_ccw_req * dasd_generic_build_rdc(struct dasd_device *device, + void *rdc_buffer, + int rdc_buffer_size, char *magic) +{ + struct dasd_ccw_req *cqr; + struct ccw1 *ccw; + + cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device); + + if (IS_ERR(cqr)) { + DEV_MESSAGE(KERN_WARNING, device, "%s", + "Could not allocate RDC request"); + return cqr; + } + + ccw = cqr->cpaddr; + ccw->cmd_code = CCW_CMD_RDC; + ccw->cda = (__u32)(addr_t)rdc_buffer; + ccw->count = rdc_buffer_size; + + cqr->device = device; + cqr->expires = 10*HZ; + clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); + cqr->retries = 2; + cqr->buildclk = get_clock(); + cqr->status = DASD_CQR_FILLED; + return cqr; +} + + +int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic, + void **rdc_buffer, int rdc_buffer_size) +{ + int ret; + struct dasd_ccw_req *cqr; + + cqr = dasd_generic_build_rdc(device, *rdc_buffer, rdc_buffer_size, + magic); + if (IS_ERR(cqr)) + return PTR_ERR(cqr); + + ret = dasd_sleep_on(cqr); + dasd_sfree_request(cqr, cqr->device); + return ret; +} static int __init dasd_init(void) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index cecab22..c9583fb 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -450,6 +450,81 @@ dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid) return 0; } +struct dasd_ccw_req * dasd_eckd_build_rcd_lpm(struct dasd_device *device, + void *rcd_buffer, + struct ciw *ciw, __u8 lpm) +{ + struct dasd_ccw_req *cqr; + struct ccw1 *ccw; + + cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device); + + if (IS_ERR(cqr)) { + DEV_MESSAGE(KERN_WARNING, device, "%s", + "Could not allocate RCD request"); + return cqr; + } + + ccw = cqr->cpaddr; + ccw->cmd_code = ciw->cmd; + ccw->cda = (__u32)(addr_t)rcd_buffer; + ccw->count = ciw->count; + + cqr->device = device; + cqr->expires = 10*HZ; + cqr->lpm = lpm; + clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); + cqr->retries = 2; + cqr->buildclk = get_clock(); + cqr->status = DASD_CQR_FILLED; + return cqr; +} + +static int dasd_eckd_read_conf_lpm(struct dasd_device *device, + void **rcd_buffer, + int *rcd_buffer_size, __u8 lpm) +{ + struct ciw *ciw; + char *rcd_buf = NULL; + int ret; + struct dasd_ccw_req *cqr; + + /* + * scan for RCD command in extended SenseID data + */ + ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD); + if (!ciw || ciw->cmd == 0) { + ret = -EOPNOTSUPP; + goto out_error; + } + rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); + if (!rcd_buf) { + ret = -ENOMEM; + goto out_error; + } + cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm); + if (IS_ERR(cqr)) { + ret = PTR_ERR(cqr); + goto out_error; + } + ret = dasd_sleep_on(cqr); + /* + * on success we update the user input parms + */ + dasd_sfree_request(cqr, cqr->device); + if (ret) + goto out_error; + + *rcd_buffer_size = ciw->count; + *rcd_buffer = rcd_buf; + return 0; +out_error: + kfree(rcd_buf); + *rcd_buffer = NULL; + *rcd_buffer_size = 0; + return ret; +} + static int dasd_eckd_read_conf(struct dasd_device *device) { @@ -469,8 +544,8 @@ dasd_eckd_read_conf(struct dasd_device *device) /* get configuration data per operational path */ for (lpm = 0x80; lpm; lpm>>= 1) { if (lpm & path_data->opm){ - rc = read_conf_data_lpm(device->cdev, &conf_data, - &conf_len, lpm); + rc = dasd_eckd_read_conf_lpm(device, &conf_data, + &conf_len, lpm); if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ MESSAGE(KERN_WARNING, "Read configuration data returned " @@ -639,7 +714,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) /* Read Device Characteristics */ rdc_data = (void *) &(private->rdc_data); memset(rdc_data, 0, sizeof(rdc_data)); - rc = read_dev_chars(device->cdev, &rdc_data, 64); + rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64); if (rc) DEV_MESSAGE(KERN_WARNING, device, "Read device characteristics returned " diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index be0909e..da16ead 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -135,7 +135,7 @@ dasd_fba_check_characteristics(struct dasd_device *device) } /* Read Device Characteristics */ rdc_data = (void *) &(private->rdc_data); - rc = read_dev_chars(device->cdev, &rdc_data, 32); + rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32); if (rc) { DEV_MESSAGE(KERN_WARNING, device, "Read device characteristics returned error %d", diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index a2cc69e..241294c 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -509,6 +509,8 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); int dasd_generic_set_offline (struct ccw_device *cdev); int dasd_generic_notify(struct ccw_device *, int); +int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); + /* externals in dasd_devmap.c */ extern int dasd_max_devindex; extern int dasd_probeonly; diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index bb4ff53..3b52f5c 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -103,6 +103,7 @@ enum tape_op { TO_CRYPT_OFF, /* Disable encrpytion */ TO_KEKL_SET, /* Set KEK label */ TO_KEKL_QUERY, /* Query KEK label */ + TO_RDC, /* Read device characteristics */ TO_SIZE, /* #entries in tape_op_t */ }; diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 50f5eda..7e2b2ab 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -788,6 +788,7 @@ tape_3590_done(struct tape_device *device, struct tape_request *request) case TO_SIZE: case TO_KEKL_SET: case TO_KEKL_QUERY: + case TO_RDC: break; } return TAPE_IO_SUCCESS; @@ -1549,6 +1550,26 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, return TAPE_IO_STOP; } + +static int tape_3590_read_dev_chars(struct tape_device *device, + struct tape_3590_rdc_data *rdc_data) +{ + int rc; + struct tape_request *request; + + request = tape_alloc_request(1, sizeof(*rdc_data)); + if (IS_ERR(request)) + return PTR_ERR(request); + request->op = TO_RDC; + tape_ccw_end(request->cpaddr, CCW_CMD_RDC, sizeof(*rdc_data), + request->cpdata); + rc = tape_do_io(device, request); + if (rc == 0) + memcpy(rdc_data, request->cpdata, sizeof(*rdc_data)); + tape_free_request(request); + return rc; +} + /* * Setup device function */ @@ -1557,7 +1578,7 @@ tape_3590_setup_device(struct tape_device *device) { int rc; struct tape_3590_disc_data *data; - char *rdc_data; + struct tape_3590_rdc_data *rdc_data; DBF_EVENT(6, "3590 device setup\n"); data = kzalloc(sizeof(struct tape_3590_disc_data), GFP_KERNEL | GFP_DMA); @@ -1566,12 +1587,12 @@ tape_3590_setup_device(struct tape_device *device) data->read_back_op = READ_PREVIOUS; device->discdata = data; - rdc_data = kmalloc(64, GFP_KERNEL | GFP_DMA); + rdc_data = kmalloc(sizeof(*rdc_data), GFP_KERNEL | GFP_DMA); if (!rdc_data) { rc = -ENOMEM; goto fail_kmalloc; } - rc = read_dev_chars(device->cdev, (void**)&rdc_data, 64); + rc = tape_3590_read_dev_chars(device, rdc_data); if (rc) { DBF_LH(3, "Read device characteristics failed!\n"); goto fail_kmalloc; @@ -1579,7 +1600,7 @@ tape_3590_setup_device(struct tape_device *device) rc = tape_std_assign(device); if (rc) goto fail_rdc_data; - if (rdc_data[31] == 0x13) { + if (rdc_data->data[31] == 0x13) { PRINT_INFO("Device has crypto support\n"); data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK; tape_3592_disable_crypt(device); diff --git a/drivers/s390/char/tape_3590.h b/drivers/s390/char/tape_3590.h index aa51388..4534055 100644 --- a/drivers/s390/char/tape_3590.h +++ b/drivers/s390/char/tape_3590.h @@ -129,6 +129,10 @@ struct tape_3590_med_sense { char pad2[116]; } __attribute__ ((packed)); +struct tape_3590_rdc_data { + char data[64]; +} __attribute__ ((packed)); + /* Datastructures for 3592 encryption support */ struct tape3592_kekl { diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index e2a8a1a..2fae633 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -73,7 +73,7 @@ const char *tape_op_verbose[TO_SIZE] = [TO_DIS] = "DIS", [TO_ASSIGN] = "ASS", [TO_UNASSIGN] = "UAS", [TO_CRYPT_ON] = "CON", [TO_CRYPT_OFF] = "COF", [TO_KEKL_SET] = "KLS", - [TO_KEKL_QUERY] = "KLQ", + [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC", }; static int @@ -911,6 +911,7 @@ __tape_start_request(struct tape_device *device, struct tape_request *request) case TO_ASSIGN: case TO_UNASSIGN: case TO_READ_ATTMSG: + case TO_RDC: if (device->tape_state == TS_INIT) break; if (device->tape_state == TS_UNUSED) diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 05fac07..cba64e4 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -69,7 +69,6 @@ static const char version[] = "QDIO base support version 2"; static int qdio_performance_stats = 0; static int proc_perf_file_registration; -static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; static struct qdio_perf_stats perf_stats; static int hydra_thinints; @@ -111,6 +110,31 @@ qdio_min(int a,int b) } /***************** SCRUBBER HELPER ROUTINES **********************/ +#ifdef CONFIG_64BIT +static inline void qdio_perf_stat_inc(atomic64_t *count) +{ + if (qdio_performance_stats) + atomic64_inc(count); +} + +static inline void qdio_perf_stat_dec(atomic64_t *count) +{ + if (qdio_performance_stats) + atomic64_dec(count); +} +#else /* CONFIG_64BIT */ +static inline void qdio_perf_stat_inc(atomic_t *count) +{ + if (qdio_performance_stats) + atomic_inc(count); +} + +static inline void qdio_perf_stat_dec(atomic_t *count) +{ + if (qdio_performance_stats) + atomic_dec(count); +} +#endif /* CONFIG_64BIT */ static inline __u64 qdio_get_micros(void) @@ -277,8 +301,7 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, QDIO_DBF_TEXT4(0,trace,"sigasync"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - if (qdio_performance_stats) - perf_stats.siga_syncs++; + qdio_perf_stat_inc(&perf_stats.siga_syncs); cc = do_siga_sync(q->schid, gpr2, gpr3); if (cc) @@ -323,8 +346,7 @@ qdio_siga_output(struct qdio_q *q) __u32 busy_bit; __u64 start_time=0; - if (qdio_performance_stats) - perf_stats.siga_outs++; + qdio_perf_stat_inc(&perf_stats.siga_outs); QDIO_DBF_TEXT4(0,trace,"sigaout"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); @@ -358,8 +380,7 @@ qdio_siga_input(struct qdio_q *q) QDIO_DBF_TEXT4(0,trace,"sigain"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - if (qdio_performance_stats) - perf_stats.siga_ins++; + qdio_perf_stat_inc(&perf_stats.siga_ins); cc = do_siga_input(q->schid, q->mask); @@ -953,8 +974,7 @@ __qdio_outbound_processing(struct qdio_q *q) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - o_p_c++; + qdio_perf_stat_inc(&perf_stats.outbound_tl_runs_resched); /* as we're sissies, we'll check next time */ if (likely(!atomic_read(&q->is_in_shutdown))) { qdio_mark_q(q); @@ -962,10 +982,8 @@ __qdio_outbound_processing(struct qdio_q *q) } return; } - if (qdio_performance_stats) { - o_p_nc++; - perf_stats.tl_runs++; - } + qdio_perf_stat_inc(&perf_stats.outbound_tl_runs); + qdio_perf_stat_inc(&perf_stats.tl_runs); /* see comment in qdio_kick_outbound_q */ siga_attempts=atomic_read(&q->busy_siga_counter); @@ -1139,17 +1157,6 @@ qdio_has_inbound_q_moved(struct qdio_q *q) { int i; - static int old_pcis=0; - static int old_thinints=0; - - if (qdio_performance_stats) { - if ((old_pcis==perf_stats.pcis)&& - (old_thinints==perf_stats.thinints)) - perf_stats.start_time_inbound=NOW; - else - old_pcis=perf_stats.pcis; - } - i=qdio_get_inbound_buffer_frontier(q); if ( (i!=GET_SAVED_FRONTIER(q)) || (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) { @@ -1337,10 +1344,7 @@ qdio_kick_inbound_handler(struct qdio_q *q) q->siga_error=0; q->error_status_flags=0; - if (qdio_performance_stats) { - perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; - perf_stats.inbound_cnt++; - } + qdio_perf_stat_inc(&perf_stats.inbound_cnt); } static void @@ -1360,8 +1364,7 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) */ if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - ii_p_c++; + qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs_resched); /* * as we might just be about to stop polling, we make * sure that we check again at least once more @@ -1369,8 +1372,7 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) tiqdio_sched_tl(); return; } - if (qdio_performance_stats) - ii_p_nc++; + qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs); if (unlikely(atomic_read(&q->is_in_shutdown))) { qdio_unmark_q(q); goto out; @@ -1412,8 +1414,7 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) for (i=0;i<irq_ptr->no_output_qs;i++) { oq = irq_ptr->output_qs[i]; if (!qdio_is_outbound_q_done(oq)) { - if (qdio_performance_stats) - perf_stats.tl_runs--; + qdio_perf_stat_dec(&perf_stats.tl_runs); __qdio_outbound_processing(oq); } } @@ -1452,8 +1453,7 @@ __qdio_inbound_processing(struct qdio_q *q) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - i_p_c++; + qdio_perf_stat_inc(&perf_stats.inbound_tl_runs_resched); /* as we're sissies, we'll check next time */ if (likely(!atomic_read(&q->is_in_shutdown))) { qdio_mark_q(q); @@ -1461,10 +1461,8 @@ __qdio_inbound_processing(struct qdio_q *q) } return; } - if (qdio_performance_stats) { - i_p_nc++; - perf_stats.tl_runs++; - } + qdio_perf_stat_inc(&perf_stats.inbound_tl_runs); + qdio_perf_stat_inc(&perf_stats.tl_runs); again: if (qdio_has_inbound_q_moved(q)) { @@ -1510,8 +1508,7 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - ii_p_c++; + qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs_resched); /* * as we might just be about to stop polling, we make * sure that we check again at least once more @@ -1602,8 +1599,7 @@ tiqdio_tl(unsigned long data) { QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); - if (qdio_performance_stats) - perf_stats.tl_runs++; + qdio_perf_stat_inc(&perf_stats.tl_runs); tiqdio_inbound_checks(); } @@ -1914,10 +1910,7 @@ tiqdio_thinint_handler(void) { QDIO_DBF_TEXT4(0,trace,"thin_int"); - if (qdio_performance_stats) { - perf_stats.thinints++; - perf_stats.start_time_inbound=NOW; - } + qdio_perf_stat_inc(&perf_stats.thinints); /* SVS only when needed: * issue SVS to benefit from iqdio interrupt avoidance @@ -1972,17 +1965,12 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) int i; struct qdio_q *q; - if (qdio_performance_stats) { - perf_stats.pcis++; - perf_stats.start_time_inbound=NOW; - } + qdio_perf_stat_inc(&perf_stats.pcis); for (i=0;i<irq_ptr->no_input_qs;i++) { q=irq_ptr->input_qs[i]; if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) qdio_mark_q(q); else { - if (qdio_performance_stats) - perf_stats.tl_runs--; __qdio_inbound_processing(q); } } @@ -1992,8 +1980,7 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) q=irq_ptr->output_qs[i]; if (qdio_is_outbound_q_done(q)) continue; - if (qdio_performance_stats) - perf_stats.tl_runs--; + qdio_perf_stat_dec(&perf_stats.tl_runs); if (!irq_ptr->sync_done_on_outb_pcis) SYNC_MEMORY; __qdio_outbound_processing(q); @@ -3463,18 +3450,12 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; /* This is the outbound handling of queues */ - if (qdio_performance_stats) - perf_stats.start_time_outbound=NOW; - qdio_do_qdio_fill_output(q,qidx,count,buffers); used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; if (callflags&QDIO_FLAG_DONT_SIGA) { - if (qdio_performance_stats) { - perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; - perf_stats.outbound_cnt++; - } + qdio_perf_stat_inc(&perf_stats.outbound_cnt); return; } if (q->is_iqdio_q) { @@ -3504,8 +3485,7 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, qdio_kick_outbound_q(q); } else { QDIO_DBF_TEXT3(0,trace, "fast-req"); - if (qdio_performance_stats) - perf_stats.fast_reqs++; + qdio_perf_stat_inc(&perf_stats.fast_reqs); } } /* @@ -3516,10 +3496,7 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, __qdio_outbound_processing(q); } - if (qdio_performance_stats) { - perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; - perf_stats.outbound_cnt++; - } + qdio_perf_stat_inc(&perf_stats.outbound_cnt); } /* count must be 1 in iqdio */ @@ -3589,33 +3566,67 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, return 0; #define _OUTP_IT(x...) c+=sprintf(buffer+c,x) - _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); - _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); - _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); - _OUTP_IT("Number of tasklet runs (total) : %lu\n", - perf_stats.tl_runs); +#ifdef CONFIG_64BIT + _OUTP_IT("Number of tasklet runs (total) : %li\n", + (long)atomic64_read(&perf_stats.tl_runs)); + _OUTP_IT("Inbound tasklet runs tried/retried : %li/%li\n", + (long)atomic64_read(&perf_stats.inbound_tl_runs), + (long)atomic64_read(&perf_stats.inbound_tl_runs_resched)); + _OUTP_IT("Inbound-thin tasklet runs tried/retried : %li/%li\n", + (long)atomic64_read(&perf_stats.inbound_thin_tl_runs), + (long)atomic64_read(&perf_stats.inbound_thin_tl_runs_resched)); + _OUTP_IT("Outbound tasklet runs tried/retried : %li/%li\n", + (long)atomic64_read(&perf_stats.outbound_tl_runs), + (long)atomic64_read(&perf_stats.outbound_tl_runs_resched)); _OUTP_IT("\n"); - _OUTP_IT("Number of SIGA sync's issued : %lu\n", - perf_stats.siga_syncs); - _OUTP_IT("Number of SIGA in's issued : %lu\n", - perf_stats.siga_ins); - _OUTP_IT("Number of SIGA out's issued : %lu\n", - perf_stats.siga_outs); - _OUTP_IT("Number of PCIs caught : %lu\n", - perf_stats.pcis); - _OUTP_IT("Number of adapter interrupts caught : %lu\n", - perf_stats.thinints); - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n", - perf_stats.fast_reqs); + _OUTP_IT("Number of SIGA sync's issued : %li\n", + (long)atomic64_read(&perf_stats.siga_syncs)); + _OUTP_IT("Number of SIGA in's issued : %li\n", + (long)atomic64_read(&perf_stats.siga_ins)); + _OUTP_IT("Number of SIGA out's issued : %li\n", + (long)atomic64_read(&perf_stats.siga_outs)); + _OUTP_IT("Number of PCIs caught : %li\n", + (long)atomic64_read(&perf_stats.pcis)); + _OUTP_IT("Number of adapter interrupts caught : %li\n", + (long)atomic64_read(&perf_stats.thinints)); + _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %li\n", + (long)atomic64_read(&perf_stats.fast_reqs)); _OUTP_IT("\n"); - _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n", - perf_stats.inbound_time); - _OUTP_IT("Number of inbound transfers : %lu\n", - perf_stats.inbound_cnt); - _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n", - perf_stats.outbound_time); - _OUTP_IT("Number of do_QDIOs outbound : %lu\n", - perf_stats.outbound_cnt); + _OUTP_IT("Number of inbound transfers : %li\n", + (long)atomic64_read(&perf_stats.inbound_cnt)); + _OUTP_IT("Number of do_QDIOs outbound : %li\n", + (long)atomic64_read(&perf_stats.outbound_cnt)); +#else /* CONFIG_64BIT */ + _OUTP_IT("Number of tasklet runs (total) : %i\n", + atomic_read(&perf_stats.tl_runs)); + _OUTP_IT("Inbound tasklet runs tried/retried : %i/%i\n", + atomic_read(&perf_stats.inbound_tl_runs), + atomic_read(&perf_stats.inbound_tl_runs_resched)); + _OUTP_IT("Inbound-thin tasklet runs tried/retried : %i/%i\n", + atomic_read(&perf_stats.inbound_thin_tl_runs), + atomic_read(&perf_stats.inbound_thin_tl_runs_resched)); + _OUTP_IT("Outbound tasklet runs tried/retried : %i/%i\n", + atomic_read(&perf_stats.outbound_tl_runs), + atomic_read(&perf_stats.outbound_tl_runs_resched)); + _OUTP_IT("\n"); + _OUTP_IT("Number of SIGA sync's issued : %i\n", + atomic_read(&perf_stats.siga_syncs)); + _OUTP_IT("Number of SIGA in's issued : %i\n", + atomic_read(&perf_stats.siga_ins)); + _OUTP_IT("Number of SIGA out's issued : %i\n", + atomic_read(&perf_stats.siga_outs)); + _OUTP_IT("Number of PCIs caught : %i\n", + atomic_read(&perf_stats.pcis)); + _OUTP_IT("Number of adapter interrupts caught : %i\n", + atomic_read(&perf_stats.thinints)); + _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %i\n", + atomic_read(&perf_stats.fast_reqs)); + _OUTP_IT("\n"); + _OUTP_IT("Number of inbound transfers : %i\n", + atomic_read(&perf_stats.inbound_cnt)); + _OUTP_IT("Number of do_QDIOs outbound : %i\n", + atomic_read(&perf_stats.outbound_cnt)); +#endif /* CONFIG_64BIT */ _OUTP_IT("\n"); return c; @@ -3642,8 +3653,6 @@ qdio_add_procfs_entry(void) static void qdio_remove_procfs_entry(void) { - perf_stats.tl_runs=0; - if (!proc_perf_file_registration) /* means if it went ok earlier */ remove_proc_entry(QDIO_PERF,&proc_root); } @@ -3671,13 +3680,38 @@ qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count qdio_performance_stats = i; if (i==0) { /* reset perf. stat. info */ - i_p_nc = 0; - i_p_c = 0; - ii_p_nc = 0; - ii_p_c = 0; - o_p_nc = 0; - o_p_c = 0; - memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); +#ifdef CONFIG_64BIT + atomic64_set(&perf_stats.tl_runs, 0); + atomic64_set(&perf_stats.outbound_tl_runs, 0); + atomic64_set(&perf_stats.inbound_tl_runs, 0); + atomic64_set(&perf_stats.inbound_tl_runs_resched, 0); + atomic64_set(&perf_stats.inbound_thin_tl_runs, 0); + atomic64_set(&perf_stats.inbound_thin_tl_runs_resched, + 0); + atomic64_set(&perf_stats.siga_outs, 0); + atomic64_set(&perf_stats.siga_ins, 0); + atomic64_set(&perf_stats.siga_syncs, 0); + atomic64_set(&perf_stats.pcis, 0); + atomic64_set(&perf_stats.thinints, 0); + atomic64_set(&perf_stats.fast_reqs, 0); + atomic64_set(&perf_stats.outbound_cnt, 0); + atomic64_set(&perf_stats.inbound_cnt, 0); +#else /* CONFIG_64BIT */ + atomic_set(&perf_stats.tl_runs, 0); + atomic_set(&perf_stats.outbound_tl_runs, 0); + atomic_set(&perf_stats.inbound_tl_runs, 0); + atomic_set(&perf_stats.inbound_tl_runs_resched, 0); + atomic_set(&perf_stats.inbound_thin_tl_runs, 0); + atomic_set(&perf_stats.inbound_thin_tl_runs_resched, 0); + atomic_set(&perf_stats.siga_outs, 0); + atomic_set(&perf_stats.siga_ins, 0); + atomic_set(&perf_stats.siga_syncs, 0); + atomic_set(&perf_stats.pcis, 0); + atomic_set(&perf_stats.thinints, 0); + atomic_set(&perf_stats.fast_reqs, 0); + atomic_set(&perf_stats.outbound_cnt, 0); + atomic_set(&perf_stats.inbound_cnt, 0); +#endif /* CONFIG_64BIT */ } } else { QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index ec9af72..2895392 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -406,21 +406,43 @@ do_clear_global_summary(void) #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 struct qdio_perf_stats { - unsigned long tl_runs; - - unsigned long siga_outs; - unsigned long siga_ins; - unsigned long siga_syncs; - unsigned long pcis; - unsigned long thinints; - unsigned long fast_reqs; - - __u64 start_time_outbound; - unsigned long outbound_cnt; - unsigned long outbound_time; - __u64 start_time_inbound; - unsigned long inbound_cnt; - unsigned long inbound_time; +#ifdef CONFIG_64BIT + atomic64_t tl_runs; + atomic64_t outbound_tl_runs; + atomic64_t outbound_tl_runs_resched; + atomic64_t inbound_tl_runs; + atomic64_t inbound_tl_runs_resched; + atomic64_t inbound_thin_tl_runs; + atomic64_t inbound_thin_tl_runs_resched; + + atomic64_t siga_outs; + atomic64_t siga_ins; + atomic64_t siga_syncs; + atomic64_t pcis; + atomic64_t thinints; + atomic64_t fast_reqs; + + atomic64_t outbound_cnt; + atomic64_t inbound_cnt; +#else /* CONFIG_64BIT */ + atomic_t tl_runs; + atomic_t outbound_tl_runs; + atomic_t outbound_tl_runs_resched; + atomic_t inbound_tl_runs; + atomic_t inbound_tl_runs_resched; + atomic_t inbound_thin_tl_runs; + atomic_t inbound_thin_tl_runs_resched; + + atomic_t siga_outs; + atomic_t siga_ins; + atomic_t siga_syncs; + atomic_t pcis; + atomic_t thinints; + atomic_t fast_reqs; + + atomic_t outbound_cnt; + atomic_t inbound_cnt; +#endif /* CONFIG_64BIT */ }; /* unlikely as the later the better */ diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 84b108d..b34eb82 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -288,6 +288,7 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) */ #define IF_NAME_LEN 16 #define QETH_TX_TIMEOUT 100 * HZ +#define QETH_RCD_TIMEOUT 60 * HZ #define QETH_HEADER_SIZE 32 #define MAX_PORTNO 15 #define QETH_FAKE_LL_LEN_ETH ETH_HLEN @@ -582,6 +583,8 @@ enum qeth_channel_states { CH_STATE_ACTIVATING, CH_STATE_HALTED, CH_STATE_STOPPED, + CH_STATE_RCD, + CH_STATE_RCD_DONE, }; /** * card state machine diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index ad7792d..6fd8870 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -315,7 +315,8 @@ qeth_alloc_card(void) } static long -__qeth_check_irb_error(struct ccw_device *cdev, struct irb *irb) +__qeth_check_irb_error(struct ccw_device *cdev, unsigned long intparm, + struct irb *irb) { if (!IS_ERR(irb)) return 0; @@ -330,6 +331,14 @@ __qeth_check_irb_error(struct ccw_device *cdev, struct irb *irb) PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id); QETH_DBF_TEXT(trace, 2, "ckirberr"); QETH_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT); + if (intparm == QETH_RCD_PARM) { + struct qeth_card *card = CARD_FROM_CDEV(cdev); + + if (card && (card->data.ccwdev == cdev)) { + card->data.state = CH_STATE_DOWN; + wake_up(&card->wait_q); + } + } break; default: PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb), @@ -401,7 +410,7 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) QETH_DBF_TEXT(trace,5,"irq"); - if (__qeth_check_irb_error(cdev, irb)) + if (__qeth_check_irb_error(cdev, intparm, irb)) return; cstat = irb->scsw.cstat; dstat = irb->scsw.dstat; @@ -429,7 +438,8 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) channel->state = CH_STATE_HALTED; /*let's wake up immediately on data channel*/ - if ((channel == &card->data) && (intparm != 0)) + if ((channel == &card->data) && (intparm != 0) && + (intparm != QETH_RCD_PARM)) goto out; if (intparm == QETH_CLEAR_CHANNEL_PARM) { @@ -453,6 +463,10 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) HEXDUMP16(WARN,"irb: ",irb); HEXDUMP16(WARN,"sense data: ",irb->ecw); } + if (intparm == QETH_RCD_PARM) { + channel->state = CH_STATE_DOWN; + goto out; + } rc = qeth_get_problem(cdev,irb); if (rc) { qeth_schedule_recovery(card); @@ -460,6 +474,10 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } } + if (intparm == QETH_RCD_PARM) { + channel->state = CH_STATE_RCD_DONE; + goto out; + } if (intparm) { buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm); buffer->state = BUF_STATE_PROCESSED; @@ -1204,6 +1222,54 @@ qeth_probe_device(struct ccwgroup_device *gdev) } +static int qeth_read_conf_data(struct qeth_card *card, void **buffer, + int *length) +{ + struct ciw *ciw; + char *rcd_buf; + int ret; + struct qeth_channel *channel = &card->data; + unsigned long flags; + + /* + * scan for RCD command in extended SenseID data + */ + ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD); + if (!ciw || ciw->cmd == 0) + return -EOPNOTSUPP; + rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); + if (!rcd_buf) + return -ENOMEM; + + channel->ccw.cmd_code = ciw->cmd; + channel->ccw.cda = (__u32) __pa (rcd_buf); + channel->ccw.count = ciw->count; + channel->ccw.flags = CCW_FLAG_SLI; + channel->state = CH_STATE_RCD; + spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); + ret = ccw_device_start_timeout(channel->ccwdev, &channel->ccw, + QETH_RCD_PARM, LPM_ANYPATH, 0, + QETH_RCD_TIMEOUT); + spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); + if (!ret) + wait_event(card->wait_q, + (channel->state == CH_STATE_RCD_DONE || + channel->state == CH_STATE_DOWN)); + if (channel->state == CH_STATE_DOWN) + ret = -EIO; + else + channel->state = CH_STATE_DOWN; + if (ret) { + kfree(rcd_buf); + *buffer = NULL; + *length = 0; + } else { + *length = ciw->count; + *buffer = rcd_buf; + } + return ret; +} + static int qeth_get_unitaddr(struct qeth_card *card) { @@ -1212,9 +1278,9 @@ qeth_get_unitaddr(struct qeth_card *card) int rc; QETH_DBF_TEXT(setup, 2, "getunit"); - rc = read_conf_data(CARD_DDEV(card), (void **) &prcd, &length); + rc = qeth_read_conf_data(card, (void **) &prcd, &length); if (rc) { - PRINT_ERR("read_conf_data for device %s returned %i\n", + PRINT_ERR("qeth_read_conf_data for device %s returned %i\n", CARD_DDEV_ID(card), rc); return rc; } @@ -1223,6 +1289,7 @@ qeth_get_unitaddr(struct qeth_card *card) card->info.cula = prcd[63]; card->info.guestlan = ((prcd[0x10] == _ascebc['V']) && (prcd[0x11] == _ascebc['M'])); + kfree(prcd); return 0; } diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h index 0477c47..d74bc43d 100644 --- a/drivers/s390/net/qeth_mpc.h +++ b/drivers/s390/net/qeth_mpc.h @@ -37,6 +37,7 @@ extern unsigned char IPA_PDU_HEADER[]; #define QETH_CLEAR_CHANNEL_PARM -10 #define QETH_HALT_CHANNEL_PARM -11 +#define QETH_RCD_PARM -12 /*****************************************************************************/ /* IP Assist related definitions */ |