Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6

* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] Poison init section before freeing it.
[S390] Use add_active_range() and free_area_init_nodes().
[S390] Virtual memmap for s390.
[S390] Update documentation for dynamic subchannel mapping.
[S390] Use dev->groups for adding/removing the subchannel attribute group.
[S390] Support for disconnected devices reappearing on another subchannel.
[S390] subchannel lock conversion.
[S390] Some preparations for the dynamic subchannel mapping patch.
[S390] runtime switch for qdio performance statistics
[S390] New DASD feature for ERP related logging
[S390] add reset call handler to the ap bus.
[S390] more workqueue fixes.
[S390] workqueue fixes.
[S390] uaccess_pt: add missing down_read() and convert to is_init().

+1301 -658
+7
Documentation/s390/driver-model.txt
··· 18 18 - 0.0.0002/ 19 19 - 0.1.0000/0.1.1234/ 20 20 ... 21 + - defunct/ 21 22 22 23 In this example, device 0815 is accessed via subchannel 0 in subchannel set 0, 23 24 device 4711 via subchannel 1 in subchannel set 0, and subchannel 2 is a non-I/O 24 25 subchannel. Device 1234 is accessed via subchannel 0 in subchannel set 1. 26 + 27 + The subchannel named 'defunct' does not represent any real subchannel on the 28 + system; it is a pseudo subchannel where disconnnected ccw devices are moved to 29 + if they are displaced by another ccw device becoming operational on their 30 + former subchannel. The ccw devices will be moved again to a proper subchannel 31 + if they become operational again on that subchannel. 25 32 26 33 You should address a ccw device via its bus id (e.g. 0.0.4711); the device can 27 34 be found under bus/ccw/devices/.
+6 -8
arch/s390/Kconfig
··· 241 241 This allows you to specify the maximum frame size a function may 242 242 have without the compiler complaining about it. 243 243 244 + config ARCH_POPULATES_NODE_MAP 245 + def_bool y 246 + 244 247 source "mm/Kconfig" 248 + 249 + config HOLES_IN_ZONE 250 + def_bool y 245 251 246 252 comment "I/O subsystem configuration" 247 253 ··· 271 265 module will be called qdio. 272 266 273 267 If unsure, say Y. 274 - 275 - config QDIO_PERF_STATS 276 - bool "Performance statistics in /proc" 277 - depends on QDIO 278 - help 279 - Say Y here to get performance statistics in /proc/qdio_perf 280 - 281 - If unsure, say N. 282 268 283 269 config QDIO_DEBUG 284 270 bool "Extended debugging information"
-1
arch/s390/defconfig
··· 134 134 # 135 135 CONFIG_MACHCHK_WARNING=y 136 136 CONFIG_QDIO=y 137 - # CONFIG_QDIO_PERF_STATS is not set 138 137 # CONFIG_QDIO_DEBUG is not set 139 138 140 139 #
+13 -42
arch/s390/kernel/setup.c
··· 64 64 unsigned int console_irq = -1; 65 65 unsigned long machine_flags = 0; 66 66 67 - struct mem_chunk memory_chunk[MEMORY_CHUNKS]; 67 + struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; 68 68 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ 69 - unsigned long __initdata zholes_size[MAX_NR_ZONES]; 70 69 static unsigned long __initdata memory_end; 71 70 72 71 /* ··· 353 354 */ 354 355 void (*pm_power_off)(void) = machine_power_off; 355 356 356 - static void __init 357 - add_memory_hole(unsigned long start, unsigned long end) 358 - { 359 - unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; 360 - 361 - if (end <= dma_pfn) 362 - zholes_size[ZONE_DMA] += end - start + 1; 363 - else if (start > dma_pfn) 364 - zholes_size[ZONE_NORMAL] += end - start + 1; 365 - else { 366 - zholes_size[ZONE_DMA] += dma_pfn - start + 1; 367 - zholes_size[ZONE_NORMAL] += end - dma_pfn; 368 - } 369 - } 370 - 371 357 static int __init early_parse_mem(char *p) 372 358 { 373 359 memory_end = memparse(p, &p); ··· 505 521 { 506 522 unsigned long bootmap_size; 507 523 unsigned long start_pfn, end_pfn, init_pfn; 508 - unsigned long last_rw_end; 509 524 int i; 510 525 511 526 /* ··· 560 577 /* 561 578 * Register RAM areas with the bootmem allocator. 562 579 */ 563 - last_rw_end = start_pfn; 564 580 565 581 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 566 - unsigned long start_chunk, end_chunk; 582 + unsigned long start_chunk, end_chunk, pfn; 567 583 568 584 if (memory_chunk[i].type != CHUNK_READ_WRITE) 569 585 continue; 570 - start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1); 571 - start_chunk >>= PAGE_SHIFT; 572 - end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); 573 - end_chunk >>= PAGE_SHIFT; 574 - if (start_chunk < start_pfn) 575 - start_chunk = start_pfn; 576 - if (end_chunk > end_pfn) 577 - end_chunk = end_pfn; 578 - if (start_chunk < end_chunk) { 579 - /* Initialize storage key for RAM pages */ 580 - for (init_pfn = start_chunk ; init_pfn < end_chunk; 581 - init_pfn++) 582 - page_set_storage_key(init_pfn << PAGE_SHIFT, 583 - PAGE_DEFAULT_KEY); 584 - free_bootmem(start_chunk << PAGE_SHIFT, 585 - (end_chunk - start_chunk) << PAGE_SHIFT); 586 - if (last_rw_end < start_chunk) 587 - add_memory_hole(last_rw_end, start_chunk - 1); 588 - last_rw_end = end_chunk; 589 - } 586 + start_chunk = PFN_DOWN(memory_chunk[i].addr); 587 + end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1; 588 + end_chunk = min(end_chunk, end_pfn); 589 + if (start_chunk >= end_chunk) 590 + continue; 591 + add_active_range(0, start_chunk, end_chunk); 592 + pfn = max(start_chunk, start_pfn); 593 + for (; pfn <= end_chunk; pfn++) 594 + page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); 590 595 } 591 596 592 597 psw_set_key(PAGE_DEFAULT_KEY); 593 598 594 - if (last_rw_end < end_pfn - 1) 595 - add_memory_hole(last_rw_end, end_pfn - 1); 599 + free_bootmem_with_active_regions(0, max_pfn); 600 + reserve_bootmem(0, PFN_PHYS(start_pfn)); 596 601 597 602 /* 598 603 * Reserve the bootmem bitmap itself as well. We do this in two
+3 -2
arch/s390/lib/uaccess_pt.c
··· 8 8 */ 9 9 10 10 #include <linux/errno.h> 11 - #include <asm/uaccess.h> 12 11 #include <linux/mm.h> 12 + #include <asm/uaccess.h> 13 13 #include <asm/futex.h> 14 14 15 15 static inline int __handle_fault(struct mm_struct *mm, unsigned long address, ··· 60 60 61 61 out_of_memory: 62 62 up_read(&mm->mmap_sem); 63 - if (current->pid == 1) { 63 + if (is_init(current)) { 64 64 yield(); 65 + down_read(&mm->mmap_sem); 65 66 goto survive; 66 67 } 67 68 printk("VM: killing process %s\n", current->comm);
+1 -1
arch/s390/mm/Makefile
··· 2 2 # Makefile for the linux s390-specific parts of the memory manager. 3 3 # 4 4 5 - obj-y := init.o fault.o ioremap.o extmem.o mmap.o 5 + obj-y := init.o fault.o ioremap.o extmem.o mmap.o vmem.o 6 6 obj-$(CONFIG_CMM) += cmm.o 7 7
+28 -82
arch/s390/mm/extmem.c
··· 16 16 #include <linux/bootmem.h> 17 17 #include <linux/ctype.h> 18 18 #include <asm/page.h> 19 + #include <asm/pgtable.h> 19 20 #include <asm/ebcdic.h> 20 21 #include <asm/errno.h> 21 22 #include <asm/extmem.h> ··· 239 238 } 240 239 241 240 /* 242 - * check if the given segment collides with guest storage. 243 - * returns 1 if this is the case, 0 if no collision was found 244 - */ 245 - static int 246 - segment_overlaps_storage(struct dcss_segment *seg) 247 - { 248 - int i; 249 - 250 - for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 251 - if (memory_chunk[i].type != CHUNK_READ_WRITE) 252 - continue; 253 - if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) 254 - continue; 255 - if (((memory_chunk[i].addr + memory_chunk[i].size - 1) >> 20) 256 - < (seg->start_addr >> 20)) 257 - continue; 258 - return 1; 259 - } 260 - return 0; 261 - } 262 - 263 - /* 264 - * check if segment collides with other segments that are currently loaded 265 - * returns 1 if this is the case, 0 if no collision was found 266 - */ 267 - static int 268 - segment_overlaps_others (struct dcss_segment *seg) 269 - { 270 - struct list_head *l; 271 - struct dcss_segment *tmp; 272 - 273 - BUG_ON(!mutex_is_locked(&dcss_lock)); 274 - list_for_each(l, &dcss_list) { 275 - tmp = list_entry(l, struct dcss_segment, list); 276 - if ((tmp->start_addr >> 20) > (seg->end >> 20)) 277 - continue; 278 - if ((tmp->end >> 20) < (seg->start_addr >> 20)) 279 - continue; 280 - if (seg == tmp) 281 - continue; 282 - return 1; 283 - } 284 - return 0; 285 - } 286 - 287 - /* 288 - * check if segment exceeds the kernel mapping range (detected or set via mem=) 289 - * returns 1 if this is the case, 0 if segment fits into the range 290 - */ 291 - static inline int 292 - segment_exceeds_range (struct dcss_segment *seg) 293 - { 294 - int seg_last_pfn = (seg->end) >> PAGE_SHIFT; 295 - if (seg_last_pfn > max_pfn) 296 - return 1; 297 - return 0; 298 - } 299 - 300 - /* 301 241 * get info about a segment 302 242 * possible return values: 303 243 * -ENOSYS : we are not running on VM ··· 283 341 rc = query_segment_type (seg); 284 342 if (rc < 0) 285 343 goto out_free; 286 - if (segment_exceeds_range(seg)) { 287 - PRINT_WARN ("segment_load: not loading segment %s - exceeds" 288 - " kernel mapping range\n",name); 289 - rc = -ERANGE; 344 + 345 + rc = add_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); 346 + 347 + switch (rc) { 348 + case 0: 349 + break; 350 + case -ENOSPC: 351 + PRINT_WARN("segment_load: not loading segment %s - overlaps " 352 + "storage/segment\n", name); 353 + goto out_free; 354 + case -ERANGE: 355 + PRINT_WARN("segment_load: not loading segment %s - exceeds " 356 + "kernel mapping range\n", name); 357 + goto out_free; 358 + default: 359 + PRINT_WARN("segment_load: not loading segment %s (rc: %d)\n", 360 + name, rc); 290 361 goto out_free; 291 362 } 292 - if (segment_overlaps_storage(seg)) { 293 - PRINT_WARN ("segment_load: not loading segment %s - overlaps" 294 - " storage\n",name); 295 - rc = -ENOSPC; 296 - goto out_free; 297 - } 298 - if (segment_overlaps_others(seg)) { 299 - PRINT_WARN ("segment_load: not loading segment %s - overlaps" 300 - " other segments\n",name); 301 - rc = -EBUSY; 302 - goto out_free; 303 - } 363 + 304 364 if (do_nonshared) 305 365 dcss_command = DCSS_LOADNSR; 306 366 else ··· 316 372 rc = dcss_diag_translate_rc (seg->end); 317 373 dcss_diag(DCSS_PURGESEG, seg->dcss_name, 318 374 &seg->start_addr, &seg->end); 319 - goto out_free; 375 + goto out_shared; 320 376 } 321 377 seg->do_nonshared = do_nonshared; 322 378 atomic_set(&seg->ref_count, 1); ··· 335 391 (void*)seg->start_addr, (void*)seg->end, 336 392 segtype_string[seg->vm_segtype]); 337 393 goto out; 394 + out_shared: 395 + remove_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); 338 396 out_free: 339 397 kfree(seg); 340 398 out: ··· 476 530 "please report to linux390@de.ibm.com\n",name); 477 531 goto out_unlock; 478 532 } 479 - if (atomic_dec_return(&seg->ref_count) == 0) { 480 - list_del(&seg->list); 481 - dcss_diag(DCSS_PURGESEG, seg->dcss_name, 482 - &dummy, &dummy); 483 - kfree(seg); 484 - } 533 + if (atomic_dec_return(&seg->ref_count) != 0) 534 + goto out_unlock; 535 + remove_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); 536 + list_del(&seg->list); 537 + dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); 538 + kfree(seg); 485 539 out_unlock: 486 540 mutex_unlock(&dcss_lock); 487 541 }
+48 -138
arch/s390/mm/init.c
··· 24 24 #include <linux/pagemap.h> 25 25 #include <linux/bootmem.h> 26 26 #include <linux/pfn.h> 27 + #include <linux/poison.h> 27 28 28 29 #include <asm/processor.h> 29 30 #include <asm/system.h> ··· 70 69 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 71 70 i = max_mapnr; 72 71 while (i-- > 0) { 72 + if (!pfn_valid(i)) 73 + continue; 73 74 page = pfn_to_page(i); 74 75 total++; 75 76 if (PageReserved(page)) ··· 87 84 printk("%d pages swap cached\n",cached); 88 85 } 89 86 90 - extern unsigned long __initdata zholes_size[]; 87 + static void __init setup_ro_region(void) 88 + { 89 + pgd_t *pgd; 90 + pmd_t *pmd; 91 + pte_t *pte; 92 + pte_t new_pte; 93 + unsigned long address, end; 94 + 95 + address = ((unsigned long)&__start_rodata) & PAGE_MASK; 96 + end = PFN_ALIGN((unsigned long)&__end_rodata); 97 + 98 + for (; address < end; address += PAGE_SIZE) { 99 + pgd = pgd_offset_k(address); 100 + pmd = pmd_offset(pgd, address); 101 + pte = pte_offset_kernel(pmd, address); 102 + new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO)); 103 + set_pte(pte, new_pte); 104 + } 105 + } 106 + 107 + extern void vmem_map_init(void); 108 + 91 109 /* 92 110 * paging_init() sets up the page tables 93 111 */ 94 - 95 - #ifndef CONFIG_64BIT 96 112 void __init paging_init(void) 97 113 { 98 - pgd_t * pg_dir; 99 - pte_t * pg_table; 100 - pte_t pte; 101 - int i; 102 - unsigned long tmp; 103 - unsigned long pfn = 0; 104 - unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; 105 - static const int ssm_mask = 0x04000000L; 106 - unsigned long ro_start_pfn, ro_end_pfn; 107 - unsigned long zones_size[MAX_NR_ZONES]; 108 - 109 - ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); 110 - ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); 111 - 112 - memset(zones_size, 0, sizeof(zones_size)); 113 - zones_size[ZONE_DMA] = max_low_pfn; 114 - free_area_init_node(0, &contig_page_data, zones_size, 115 - __pa(PAGE_OFFSET) >> PAGE_SHIFT, 116 - zholes_size); 117 - 118 - /* unmap whole virtual address space */ 119 - 120 - pg_dir = swapper_pg_dir; 121 - 122 - for (i = 0; i < PTRS_PER_PGD; i++) 123 - pmd_clear((pmd_t *) pg_dir++); 124 - 125 - /* 126 - * map whole physical memory to virtual memory (identity mapping) 127 - */ 128 - 129 - pg_dir = swapper_pg_dir; 130 - 131 - while (pfn < max_low_pfn) { 132 - /* 133 - * pg_table is physical at this point 134 - */ 135 - pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); 136 - 137 - pmd_populate_kernel(&init_mm, (pmd_t *) pg_dir, pg_table); 138 - pg_dir++; 139 - 140 - for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { 141 - if (pfn >= ro_start_pfn && pfn < ro_end_pfn) 142 - pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); 143 - else 144 - pte = pfn_pte(pfn, PAGE_KERNEL); 145 - if (pfn >= max_low_pfn) 146 - pte_val(pte) = _PAGE_TYPE_EMPTY; 147 - set_pte(pg_table, pte); 148 - pfn++; 149 - } 150 - } 151 - 152 - S390_lowcore.kernel_asce = pgdir_k; 153 - 154 - /* enable virtual mapping in kernel mode */ 155 - __ctl_load(pgdir_k, 1, 1); 156 - __ctl_load(pgdir_k, 7, 7); 157 - __ctl_load(pgdir_k, 13, 13); 158 - __raw_local_irq_ssm(ssm_mask); 159 - 160 - local_flush_tlb(); 161 - } 162 - 163 - #else /* CONFIG_64BIT */ 164 - 165 - void __init paging_init(void) 166 - { 167 - pgd_t * pg_dir; 168 - pmd_t * pm_dir; 169 - pte_t * pt_dir; 170 - pte_t pte; 171 - int i,j,k; 172 - unsigned long pfn = 0; 173 - unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | 174 - _KERN_REGION_TABLE; 114 + pgd_t *pg_dir; 115 + int i; 116 + unsigned long pgdir_k; 175 117 static const int ssm_mask = 0x04000000L; 176 - unsigned long zones_size[MAX_NR_ZONES]; 177 - unsigned long dma_pfn, high_pfn; 178 - unsigned long ro_start_pfn, ro_end_pfn; 118 + unsigned long max_zone_pfns[MAX_NR_ZONES]; 179 119 180 - memset(zones_size, 0, sizeof(zones_size)); 181 - dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; 182 - high_pfn = max_low_pfn; 183 - ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); 184 - ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); 185 - 186 - if (dma_pfn > high_pfn) 187 - zones_size[ZONE_DMA] = high_pfn; 188 - else { 189 - zones_size[ZONE_DMA] = dma_pfn; 190 - zones_size[ZONE_NORMAL] = high_pfn - dma_pfn; 191 - } 192 - 193 - /* Initialize mem_map[]. */ 194 - free_area_init_node(0, &contig_page_data, zones_size, 195 - __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); 196 - 197 - /* 198 - * map whole physical memory to virtual memory (identity mapping) 199 - */ 200 - 201 - pg_dir = swapper_pg_dir; 120 + pg_dir = swapper_pg_dir; 202 121 203 - for (i = 0 ; i < PTRS_PER_PGD ; i++,pg_dir++) { 204 - 205 - if (pfn >= max_low_pfn) { 206 - pgd_clear(pg_dir); 207 - continue; 208 - } 209 - 210 - pm_dir = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE * 4); 211 - pgd_populate(&init_mm, pg_dir, pm_dir); 212 - 213 - for (j = 0 ; j < PTRS_PER_PMD ; j++,pm_dir++) { 214 - if (pfn >= max_low_pfn) { 215 - pmd_clear(pm_dir); 216 - continue; 217 - } 218 - 219 - pt_dir = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); 220 - pmd_populate_kernel(&init_mm, pm_dir, pt_dir); 221 - 222 - for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { 223 - if (pfn >= ro_start_pfn && pfn < ro_end_pfn) 224 - pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); 225 - else 226 - pte = pfn_pte(pfn, PAGE_KERNEL); 227 - if (pfn >= max_low_pfn) 228 - pte_val(pte) = _PAGE_TYPE_EMPTY; 229 - set_pte(pt_dir, pte); 230 - pfn++; 231 - } 232 - } 233 - } 122 + #ifdef CONFIG_64BIT 123 + pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE; 124 + for (i = 0; i < PTRS_PER_PGD; i++) 125 + pgd_clear(pg_dir + i); 126 + #else 127 + pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; 128 + for (i = 0; i < PTRS_PER_PGD; i++) 129 + pmd_clear((pmd_t *)(pg_dir + i)); 130 + #endif 131 + vmem_map_init(); 132 + setup_ro_region(); 234 133 235 134 S390_lowcore.kernel_asce = pgdir_k; 236 135 ··· 142 237 __ctl_load(pgdir_k, 13, 13); 143 238 __raw_local_irq_ssm(ssm_mask); 144 239 145 - local_flush_tlb(); 240 + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 241 + max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); 242 + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; 243 + free_area_init_nodes(max_zone_pfns); 146 244 } 147 - #endif /* CONFIG_64BIT */ 148 245 149 246 void __init mem_init(void) 150 247 { ··· 176 269 printk("Write protected kernel read-only data: %#lx - %#lx\n", 177 270 (unsigned long)&__start_rodata, 178 271 PFN_ALIGN((unsigned long)&__end_rodata) - 1); 272 + printk("Virtual memmap size: %ldk\n", 273 + (max_pfn * sizeof(struct page)) >> 10); 179 274 } 180 275 181 276 void free_initmem(void) ··· 188 279 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { 189 280 ClearPageReserved(virt_to_page(addr)); 190 281 init_page_count(virt_to_page(addr)); 282 + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); 191 283 free_page(addr); 192 284 totalram_pages++; 193 285 }
+381
arch/s390/mm/vmem.c
··· 1 + /* 2 + * arch/s390/mm/vmem.c 3 + * 4 + * Copyright IBM Corp. 2006 5 + * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 6 + */ 7 + 8 + #include <linux/bootmem.h> 9 + #include <linux/pfn.h> 10 + #include <linux/mm.h> 11 + #include <linux/module.h> 12 + #include <linux/list.h> 13 + #include <asm/pgalloc.h> 14 + #include <asm/pgtable.h> 15 + #include <asm/setup.h> 16 + #include <asm/tlbflush.h> 17 + 18 + unsigned long vmalloc_end; 19 + EXPORT_SYMBOL(vmalloc_end); 20 + 21 + static struct page *vmem_map; 22 + static DEFINE_MUTEX(vmem_mutex); 23 + 24 + struct memory_segment { 25 + struct list_head list; 26 + unsigned long start; 27 + unsigned long size; 28 + }; 29 + 30 + static LIST_HEAD(mem_segs); 31 + 32 + void memmap_init(unsigned long size, int nid, unsigned long zone, 33 + unsigned long start_pfn) 34 + { 35 + struct page *start, *end; 36 + struct page *map_start, *map_end; 37 + int i; 38 + 39 + start = pfn_to_page(start_pfn); 40 + end = start + size; 41 + 42 + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 43 + unsigned long cstart, cend; 44 + 45 + cstart = PFN_DOWN(memory_chunk[i].addr); 46 + cend = cstart + PFN_DOWN(memory_chunk[i].size); 47 + 48 + map_start = mem_map + cstart; 49 + map_end = mem_map + cend; 50 + 51 + if (map_start < start) 52 + map_start = start; 53 + if (map_end > end) 54 + map_end = end; 55 + 56 + map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1)) 57 + / sizeof(struct page); 58 + map_end += ((PFN_ALIGN((unsigned long) map_end) 59 + - (unsigned long) map_end) 60 + / sizeof(struct page)); 61 + 62 + if (map_start < map_end) 63 + memmap_init_zone((unsigned long)(map_end - map_start), 64 + nid, zone, page_to_pfn(map_start)); 65 + } 66 + } 67 + 68 + static inline void *vmem_alloc_pages(unsigned int order) 69 + { 70 + if (slab_is_available()) 71 + return (void *)__get_free_pages(GFP_KERNEL, order); 72 + return alloc_bootmem_pages((1 << order) * PAGE_SIZE); 73 + } 74 + 75 + static inline pmd_t *vmem_pmd_alloc(void) 76 + { 77 + pmd_t *pmd; 78 + int i; 79 + 80 + pmd = vmem_alloc_pages(PMD_ALLOC_ORDER); 81 + if (!pmd) 82 + return NULL; 83 + for (i = 0; i < PTRS_PER_PMD; i++) 84 + pmd_clear(pmd + i); 85 + return pmd; 86 + } 87 + 88 + static inline pte_t *vmem_pte_alloc(void) 89 + { 90 + pte_t *pte; 91 + pte_t empty_pte; 92 + int i; 93 + 94 + pte = vmem_alloc_pages(PTE_ALLOC_ORDER); 95 + if (!pte) 96 + return NULL; 97 + pte_val(empty_pte) = _PAGE_TYPE_EMPTY; 98 + for (i = 0; i < PTRS_PER_PTE; i++) 99 + set_pte(pte + i, empty_pte); 100 + return pte; 101 + } 102 + 103 + /* 104 + * Add a physical memory range to the 1:1 mapping. 105 + */ 106 + static int vmem_add_range(unsigned long start, unsigned long size) 107 + { 108 + unsigned long address; 109 + pgd_t *pg_dir; 110 + pmd_t *pm_dir; 111 + pte_t *pt_dir; 112 + pte_t pte; 113 + int ret = -ENOMEM; 114 + 115 + for (address = start; address < start + size; address += PAGE_SIZE) { 116 + pg_dir = pgd_offset_k(address); 117 + if (pgd_none(*pg_dir)) { 118 + pm_dir = vmem_pmd_alloc(); 119 + if (!pm_dir) 120 + goto out; 121 + pgd_populate(&init_mm, pg_dir, pm_dir); 122 + } 123 + 124 + pm_dir = pmd_offset(pg_dir, address); 125 + if (pmd_none(*pm_dir)) { 126 + pt_dir = vmem_pte_alloc(); 127 + if (!pt_dir) 128 + goto out; 129 + pmd_populate_kernel(&init_mm, pm_dir, pt_dir); 130 + } 131 + 132 + pt_dir = pte_offset_kernel(pm_dir, address); 133 + pte = pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL); 134 + set_pte(pt_dir, pte); 135 + } 136 + ret = 0; 137 + out: 138 + flush_tlb_kernel_range(start, start + size); 139 + return ret; 140 + } 141 + 142 + /* 143 + * Remove a physical memory range from the 1:1 mapping. 144 + * Currently only invalidates page table entries. 145 + */ 146 + static void vmem_remove_range(unsigned long start, unsigned long size) 147 + { 148 + unsigned long address; 149 + pgd_t *pg_dir; 150 + pmd_t *pm_dir; 151 + pte_t *pt_dir; 152 + pte_t pte; 153 + 154 + pte_val(pte) = _PAGE_TYPE_EMPTY; 155 + for (address = start; address < start + size; address += PAGE_SIZE) { 156 + pg_dir = pgd_offset_k(address); 157 + if (pgd_none(*pg_dir)) 158 + continue; 159 + pm_dir = pmd_offset(pg_dir, address); 160 + if (pmd_none(*pm_dir)) 161 + continue; 162 + pt_dir = pte_offset_kernel(pm_dir, address); 163 + set_pte(pt_dir, pte); 164 + } 165 + flush_tlb_kernel_range(start, start + size); 166 + } 167 + 168 + /* 169 + * Add a backed mem_map array to the virtual mem_map array. 170 + */ 171 + static int vmem_add_mem_map(unsigned long start, unsigned long size) 172 + { 173 + unsigned long address, start_addr, end_addr; 174 + struct page *map_start, *map_end; 175 + pgd_t *pg_dir; 176 + pmd_t *pm_dir; 177 + pte_t *pt_dir; 178 + pte_t pte; 179 + int ret = -ENOMEM; 180 + 181 + map_start = vmem_map + PFN_DOWN(start); 182 + map_end = vmem_map + PFN_DOWN(start + size); 183 + 184 + start_addr = (unsigned long) map_start & PAGE_MASK; 185 + end_addr = PFN_ALIGN((unsigned long) map_end); 186 + 187 + for (address = start_addr; address < end_addr; address += PAGE_SIZE) { 188 + pg_dir = pgd_offset_k(address); 189 + if (pgd_none(*pg_dir)) { 190 + pm_dir = vmem_pmd_alloc(); 191 + if (!pm_dir) 192 + goto out; 193 + pgd_populate(&init_mm, pg_dir, pm_dir); 194 + } 195 + 196 + pm_dir = pmd_offset(pg_dir, address); 197 + if (pmd_none(*pm_dir)) { 198 + pt_dir = vmem_pte_alloc(); 199 + if (!pt_dir) 200 + goto out; 201 + pmd_populate_kernel(&init_mm, pm_dir, pt_dir); 202 + } 203 + 204 + pt_dir = pte_offset_kernel(pm_dir, address); 205 + if (pte_none(*pt_dir)) { 206 + unsigned long new_page; 207 + 208 + new_page =__pa(vmem_alloc_pages(0)); 209 + if (!new_page) 210 + goto out; 211 + pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); 212 + set_pte(pt_dir, pte); 213 + } 214 + } 215 + ret = 0; 216 + out: 217 + flush_tlb_kernel_range(start_addr, end_addr); 218 + return ret; 219 + } 220 + 221 + static int vmem_add_mem(unsigned long start, unsigned long size) 222 + { 223 + int ret; 224 + 225 + ret = vmem_add_range(start, size); 226 + if (ret) 227 + return ret; 228 + return vmem_add_mem_map(start, size); 229 + } 230 + 231 + /* 232 + * Add memory segment to the segment list if it doesn't overlap with 233 + * an already present segment. 234 + */ 235 + static int insert_memory_segment(struct memory_segment *seg) 236 + { 237 + struct memory_segment *tmp; 238 + 239 + if (PFN_DOWN(seg->start + seg->size) > max_pfn || 240 + seg->start + seg->size < seg->start) 241 + return -ERANGE; 242 + 243 + list_for_each_entry(tmp, &mem_segs, list) { 244 + if (seg->start >= tmp->start + tmp->size) 245 + continue; 246 + if (seg->start + seg->size <= tmp->start) 247 + continue; 248 + return -ENOSPC; 249 + } 250 + list_add(&seg->list, &mem_segs); 251 + return 0; 252 + } 253 + 254 + /* 255 + * Remove memory segment from the segment list. 256 + */ 257 + static void remove_memory_segment(struct memory_segment *seg) 258 + { 259 + list_del(&seg->list); 260 + } 261 + 262 + static void __remove_shared_memory(struct memory_segment *seg) 263 + { 264 + remove_memory_segment(seg); 265 + vmem_remove_range(seg->start, seg->size); 266 + } 267 + 268 + int remove_shared_memory(unsigned long start, unsigned long size) 269 + { 270 + struct memory_segment *seg; 271 + int ret; 272 + 273 + mutex_lock(&vmem_mutex); 274 + 275 + ret = -ENOENT; 276 + list_for_each_entry(seg, &mem_segs, list) { 277 + if (seg->start == start && seg->size == size) 278 + break; 279 + } 280 + 281 + if (seg->start != start || seg->size != size) 282 + goto out; 283 + 284 + ret = 0; 285 + __remove_shared_memory(seg); 286 + kfree(seg); 287 + out: 288 + mutex_unlock(&vmem_mutex); 289 + return ret; 290 + } 291 + 292 + int add_shared_memory(unsigned long start, unsigned long size) 293 + { 294 + struct memory_segment *seg; 295 + struct page *page; 296 + unsigned long pfn, num_pfn, end_pfn; 297 + int ret; 298 + 299 + mutex_lock(&vmem_mutex); 300 + ret = -ENOMEM; 301 + seg = kzalloc(sizeof(*seg), GFP_KERNEL); 302 + if (!seg) 303 + goto out; 304 + seg->start = start; 305 + seg->size = size; 306 + 307 + ret = insert_memory_segment(seg); 308 + if (ret) 309 + goto out_free; 310 + 311 + ret = vmem_add_mem(start, size); 312 + if (ret) 313 + goto out_remove; 314 + 315 + pfn = PFN_DOWN(start); 316 + num_pfn = PFN_DOWN(size); 317 + end_pfn = pfn + num_pfn; 318 + 319 + page = pfn_to_page(pfn); 320 + memset(page, 0, num_pfn * sizeof(struct page)); 321 + 322 + for (; pfn < end_pfn; pfn++) { 323 + page = pfn_to_page(pfn); 324 + init_page_count(page); 325 + reset_page_mapcount(page); 326 + SetPageReserved(page); 327 + INIT_LIST_HEAD(&page->lru); 328 + } 329 + goto out; 330 + 331 + out_remove: 332 + __remove_shared_memory(seg); 333 + out_free: 334 + kfree(seg); 335 + out: 336 + mutex_unlock(&vmem_mutex); 337 + return ret; 338 + } 339 + 340 + /* 341 + * map whole physical memory to virtual memory (identity mapping) 342 + */ 343 + void __init vmem_map_init(void) 344 + { 345 + unsigned long map_size; 346 + int i; 347 + 348 + map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page); 349 + vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size); 350 + vmem_map = (struct page *) vmalloc_end; 351 + NODE_DATA(0)->node_mem_map = vmem_map; 352 + 353 + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) 354 + vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); 355 + } 356 + 357 + /* 358 + * Convert memory chunk array to a memory segment list so there is a single 359 + * list that contains both r/w memory and shared memory segments. 360 + */ 361 + static int __init vmem_convert_memory_chunk(void) 362 + { 363 + struct memory_segment *seg; 364 + int i; 365 + 366 + mutex_lock(&vmem_mutex); 367 + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 368 + if (!memory_chunk[i].size) 369 + continue; 370 + seg = kzalloc(sizeof(*seg), GFP_KERNEL); 371 + if (!seg) 372 + panic("Out of memory...\n"); 373 + seg->start = memory_chunk[i].addr; 374 + seg->size = memory_chunk[i].size; 375 + insert_memory_segment(seg); 376 + } 377 + mutex_unlock(&vmem_mutex); 378 + return 0; 379 + } 380 + 381 + core_initcall(vmem_convert_memory_chunk);
+4 -4
drivers/s390/block/dasd.c
··· 1050 1050 } 1051 1051 } else { /* error */ 1052 1052 memcpy(&cqr->irb, irb, sizeof (struct irb)); 1053 - #ifdef ERP_DEBUG 1054 - /* dump sense data */ 1055 - dasd_log_sense(cqr, irb); 1056 - #endif 1053 + if (device->features & DASD_FEATURE_ERPLOG) { 1054 + /* dump sense data */ 1055 + dasd_log_sense(cqr, irb); 1056 + } 1057 1057 switch (era) { 1058 1058 case dasd_era_fatal: 1059 1059 cqr->status = DASD_CQR_FAILED;
+9 -14
drivers/s390/block/dasd_3990_erp.c
··· 2641 2641 struct dasd_ccw_req *erp = NULL; 2642 2642 struct dasd_device *device = cqr->device; 2643 2643 __u32 cpa = cqr->irb.scsw.cpa; 2644 + struct dasd_ccw_req *temp_erp = NULL; 2644 2645 2645 - #ifdef ERP_DEBUG 2646 - /* print current erp_chain */ 2647 - DEV_MESSAGE(KERN_ERR, device, "%s", 2648 - "ERP chain at BEGINNING of ERP-ACTION"); 2649 - { 2650 - struct dasd_ccw_req *temp_erp = NULL; 2651 - 2646 + if (device->features & DASD_FEATURE_ERPLOG) { 2647 + /* print current erp_chain */ 2648 + DEV_MESSAGE(KERN_ERR, device, "%s", 2649 + "ERP chain at BEGINNING of ERP-ACTION"); 2652 2650 for (temp_erp = cqr; 2653 2651 temp_erp != NULL; temp_erp = temp_erp->refers) { 2654 2652 ··· 2656 2658 temp_erp->refers); 2657 2659 } 2658 2660 } 2659 - #endif /* ERP_DEBUG */ 2660 2661 2661 2662 /* double-check if current erp/cqr was successfull */ 2662 2663 if ((cqr->irb.scsw.cstat == 0x00) && ··· 2692 2695 erp = dasd_3990_erp_handle_match_erp(cqr, erp); 2693 2696 } 2694 2697 2695 - #ifdef ERP_DEBUG 2696 - /* print current erp_chain */ 2697 - DEV_MESSAGE(KERN_ERR, device, "%s", "ERP chain at END of ERP-ACTION"); 2698 - { 2699 - struct dasd_ccw_req *temp_erp = NULL; 2698 + if (device->features & DASD_FEATURE_ERPLOG) { 2699 + /* print current erp_chain */ 2700 + DEV_MESSAGE(KERN_ERR, device, "%s", 2701 + "ERP chain at END of ERP-ACTION"); 2700 2702 for (temp_erp = erp; 2701 2703 temp_erp != NULL; temp_erp = temp_erp->refers) { 2702 2704 ··· 2705 2709 temp_erp->refers); 2706 2710 } 2707 2711 } 2708 - #endif /* ERP_DEBUG */ 2709 2712 2710 2713 if (erp->status == DASD_CQR_FAILED) 2711 2714 dasd_log_ccw(erp, 1, cpa);
+49
drivers/s390/block/dasd_devmap.c
··· 202 202 features |= DASD_FEATURE_READONLY; 203 203 else if (len == 4 && !strncmp(str, "diag", 4)) 204 204 features |= DASD_FEATURE_USEDIAG; 205 + else if (len == 6 && !strncmp(str, "erplog", 6)) 206 + features |= DASD_FEATURE_ERPLOG; 205 207 else { 206 208 MESSAGE(KERN_WARNING, 207 209 "unsupported feature: %*s, " ··· 711 709 } 712 710 713 711 static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); 712 + /* 713 + * erplog controls the logging of ERP related data 714 + * (e.g. failing channel programs). 715 + */ 716 + static ssize_t 717 + dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf) 718 + { 719 + struct dasd_devmap *devmap; 720 + int erplog; 721 + 722 + devmap = dasd_find_busid(dev->bus_id); 723 + if (!IS_ERR(devmap)) 724 + erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0; 725 + else 726 + erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0; 727 + return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n"); 728 + } 729 + 730 + static ssize_t 731 + dasd_erplog_store(struct device *dev, struct device_attribute *attr, 732 + const char *buf, size_t count) 733 + { 734 + struct dasd_devmap *devmap; 735 + int val; 736 + char *endp; 737 + 738 + devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 739 + if (IS_ERR(devmap)) 740 + return PTR_ERR(devmap); 741 + 742 + val = simple_strtoul(buf, &endp, 0); 743 + if (((endp + 1) < (buf + count)) || (val > 1)) 744 + return -EINVAL; 745 + 746 + spin_lock(&dasd_devmap_lock); 747 + if (val) 748 + devmap->features |= DASD_FEATURE_ERPLOG; 749 + else 750 + devmap->features &= ~DASD_FEATURE_ERPLOG; 751 + if (devmap->device) 752 + devmap->device->features = devmap->features; 753 + spin_unlock(&dasd_devmap_lock); 754 + return count; 755 + } 756 + 757 + static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store); 714 758 715 759 /* 716 760 * use_diag controls whether the driver should use diag rather than ssch ··· 944 896 &dev_attr_uid.attr, 945 897 &dev_attr_use_diag.attr, 946 898 &dev_attr_eer_enabled.attr, 899 + &dev_attr_erplog.attr, 947 900 NULL, 948 901 }; 949 902
-4
drivers/s390/block/dasd_int.h
··· 13 13 14 14 #ifdef __KERNEL__ 15 15 16 - /* erp debugging in dasd.c and dasd_3990_erp.c */ 17 - #define ERP_DEBUG 18 - 19 - 20 16 /* we keep old device allocation scheme; IOW, minors are still in 0..255 */ 21 17 #define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS)) 22 18 #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
+5 -4
drivers/s390/char/ctrlchar.c
··· 16 16 17 17 #ifdef CONFIG_MAGIC_SYSRQ 18 18 static int ctrlchar_sysrq_key; 19 + static struct tty_struct *sysrq_tty; 19 20 20 21 static void 21 - ctrlchar_handle_sysrq(void *tty) 22 + ctrlchar_handle_sysrq(struct work_struct *work) 22 23 { 23 - handle_sysrq(ctrlchar_sysrq_key, (struct tty_struct *) tty); 24 + handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); 24 25 } 25 26 26 - static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq, NULL); 27 + static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); 27 28 #endif 28 29 29 30 ··· 54 53 /* racy */ 55 54 if (len == 3 && buf[1] == '-') { 56 55 ctrlchar_sysrq_key = buf[2]; 57 - ctrlchar_work.data = tty; 56 + sysrq_tty = tty; 58 57 schedule_work(&ctrlchar_work); 59 58 return CTRLCHAR_SYSRQ; 60 59 }
+2 -1
drivers/s390/char/tape.h
··· 179 179 /* Block Frontend Data */ 180 180 struct tape_blk_data 181 181 { 182 + struct tape_device * device; 182 183 /* Block device request queue. */ 183 184 request_queue_t * request_queue; 184 185 spinlock_t request_queue_lock; ··· 241 240 #endif 242 241 243 242 /* Function to start or stop the next request later. */ 244 - struct work_struct tape_dnr; 243 + struct delayed_work tape_dnr; 245 244 }; 246 245 247 246 /* Externals from tape_core.c */
+11 -12
drivers/s390/char/tape_34xx.c
··· 95 95 return rc; 96 96 } 97 97 98 + struct tape_34xx_work { 99 + struct tape_device *device; 100 + enum tape_op op; 101 + struct work_struct work; 102 + }; 103 + 98 104 /* 99 105 * These functions are currently used only to schedule a medium_sense for 100 106 * later execution. This is because we get an interrupt whenever a medium ··· 109 103 * interrupt handler. 110 104 */ 111 105 static void 112 - tape_34xx_work_handler(void *data) 106 + tape_34xx_work_handler(struct work_struct *work) 113 107 { 114 - struct { 115 - struct tape_device *device; 116 - enum tape_op op; 117 - struct work_struct work; 118 - } *p = data; 108 + struct tape_34xx_work *p = 109 + container_of(work, struct tape_34xx_work, work); 119 110 120 111 switch(p->op) { 121 112 case TO_MSEN: ··· 129 126 static int 130 127 tape_34xx_schedule_work(struct tape_device *device, enum tape_op op) 131 128 { 132 - struct { 133 - struct tape_device *device; 134 - enum tape_op op; 135 - struct work_struct work; 136 - } *p; 129 + struct tape_34xx_work *p; 137 130 138 131 if ((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL) 139 132 return -ENOMEM; 140 133 141 134 memset(p, 0, sizeof(*p)); 142 - INIT_WORK(&p->work, tape_34xx_work_handler, p); 135 + INIT_WORK(&p->work, tape_34xx_work_handler); 143 136 144 137 p->device = tape_get_device_reference(device); 145 138 p->op = op;
+4 -3
drivers/s390/char/tape_3590.c
··· 236 236 }; 237 237 238 238 static void 239 - tape_3590_work_handler(void *data) 239 + tape_3590_work_handler(struct work_struct *work) 240 240 { 241 - struct work_handler_data *p = data; 241 + struct work_handler_data *p = 242 + container_of(work, struct work_handler_data, work); 242 243 243 244 switch (p->op) { 244 245 case TO_MSEN: ··· 264 263 if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL) 265 264 return -ENOMEM; 266 265 267 - INIT_WORK(&p->work, tape_3590_work_handler, p); 266 + INIT_WORK(&p->work, tape_3590_work_handler); 268 267 269 268 p->device = tape_get_device_reference(device); 270 269 p->op = op;
+9 -5
drivers/s390/char/tape_block.c
··· 15 15 #include <linux/blkdev.h> 16 16 #include <linux/interrupt.h> 17 17 #include <linux/buffer_head.h> 18 + #include <linux/kernel.h> 18 19 19 20 #include <asm/debug.h> 20 21 ··· 144 143 * queue. 145 144 */ 146 145 static void 147 - tapeblock_requeue(void *data) { 146 + tapeblock_requeue(struct work_struct *work) { 147 + struct tape_blk_data * blkdat; 148 148 struct tape_device * device; 149 149 request_queue_t * queue; 150 150 int nr_queued; ··· 153 151 struct list_head * l; 154 152 int rc; 155 153 156 - device = (struct tape_device *) data; 154 + blkdat = container_of(work, struct tape_blk_data, requeue_task); 155 + device = blkdat->device; 157 156 if (!device) 158 157 return; 159 158 ··· 215 212 int rc; 216 213 217 214 blkdat = &device->blk_data; 215 + blkdat->device = device; 218 216 spin_lock_init(&blkdat->request_queue_lock); 219 217 atomic_set(&blkdat->requeue_scheduled, 0); 220 218 ··· 259 255 260 256 add_disk(disk); 261 257 262 - INIT_WORK(&blkdat->requeue_task, tapeblock_requeue, 263 - tape_get_device_reference(device)); 258 + tape_get_device_reference(device); 259 + INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); 264 260 265 261 return 0; 266 262 ··· 275 271 tapeblock_cleanup_device(struct tape_device *device) 276 272 { 277 273 flush_scheduled_work(); 278 - device->blk_data.requeue_task.data = tape_put_device(device); 274 + tape_put_device(device); 279 275 280 276 if (!device->blk_data.disk) { 281 277 PRINT_ERR("(%s): No gendisk to clean up!\n",
+7 -7
drivers/s390/char/tape_core.c
··· 28 28 #define PRINTK_HEADER "TAPE_CORE: " 29 29 30 30 static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *); 31 - static void tape_delayed_next_request(void * data); 31 + static void tape_delayed_next_request(struct work_struct *); 32 32 33 33 /* 34 34 * One list to contain all tape devices of all disciplines, so ··· 272 272 return 0; 273 273 case -EBUSY: 274 274 request->status = TAPE_REQUEST_CANCEL; 275 - schedule_work(&device->tape_dnr); 275 + schedule_delayed_work(&device->tape_dnr, 0); 276 276 return 0; 277 277 case -ENODEV: 278 278 DBF_EXCEPTION(2, "device gone, retry\n"); ··· 470 470 *device->modeset_byte = 0; 471 471 device->first_minor = -1; 472 472 atomic_set(&device->ref_count, 1); 473 - INIT_WORK(&device->tape_dnr, tape_delayed_next_request, device); 473 + INIT_DELAYED_WORK(&device->tape_dnr, tape_delayed_next_request); 474 474 475 475 return device; 476 476 } ··· 724 724 } else if (rc == -EBUSY) { 725 725 /* The common I/O subsystem is currently busy. Retry later. */ 726 726 request->status = TAPE_REQUEST_QUEUED; 727 - schedule_work(&device->tape_dnr); 727 + schedule_delayed_work(&device->tape_dnr, 0); 728 728 rc = 0; 729 729 } else { 730 730 /* Start failed. Remove request and indicate failure. */ ··· 790 790 } 791 791 792 792 static void 793 - tape_delayed_next_request(void *data) 793 + tape_delayed_next_request(struct work_struct *work) 794 794 { 795 - struct tape_device * device; 795 + struct tape_device *device = 796 + container_of(work, struct tape_device, tape_dnr.work); 796 797 797 - device = (struct tape_device *) data; 798 798 DBF_LH(6, "tape_delayed_next_request(%p)\n", device); 799 799 spin_lock_irq(get_ccwdev_lock(device->cdev)); 800 800 __tape_start_next_request(device);
+14 -14
drivers/s390/cio/chsc.c
··· 183 183 page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 184 184 if (!page) 185 185 return -ENOMEM; 186 - spin_lock_irq(&sch->lock); 186 + spin_lock_irq(sch->lock); 187 187 ret = chsc_get_sch_desc_irq(sch, page); 188 188 if (ret) { 189 189 static int cio_chsc_err_msg; ··· 197 197 cio_chsc_err_msg = 1; 198 198 } 199 199 } 200 - spin_unlock_irq(&sch->lock); 200 + spin_unlock_irq(sch->lock); 201 201 free_page((unsigned long)page); 202 202 if (!ret) { 203 203 int j, chpid, mask; ··· 233 233 if (j >= 8) 234 234 return 0; 235 235 236 - spin_lock_irq(&sch->lock); 236 + spin_lock_irq(sch->lock); 237 237 238 238 stsch(sch->schid, &schib); 239 239 if (!schib.pmcw.dnv) ··· 265 265 else if (sch->lpm == mask) 266 266 goto out_unreg; 267 267 out_unlock: 268 - spin_unlock_irq(&sch->lock); 268 + spin_unlock_irq(sch->lock); 269 269 return 0; 270 270 out_unreg: 271 - spin_unlock_irq(&sch->lock); 271 + spin_unlock_irq(sch->lock); 272 272 sch->lpm = 0; 273 273 if (css_enqueue_subchannel_slow(sch->schid)) { 274 274 css_clear_subchannel_slow_list(); ··· 378 378 /* Check if a subchannel is newly available. */ 379 379 return s390_process_res_acc_new_sch(schid); 380 380 381 - spin_lock_irq(&sch->lock); 381 + spin_lock_irq(sch->lock); 382 382 383 383 chp_mask = s390_process_res_acc_sch(res_data, sch); 384 384 385 385 if (chp_mask == 0) { 386 - spin_unlock_irq(&sch->lock); 386 + spin_unlock_irq(sch->lock); 387 387 put_device(&sch->dev); 388 388 return 0; 389 389 } ··· 397 397 else if (sch->driver && sch->driver->verify) 398 398 sch->driver->verify(&sch->dev); 399 399 400 - spin_unlock_irq(&sch->lock); 400 + spin_unlock_irq(sch->lock); 401 401 put_device(&sch->dev); 402 402 return 0; 403 403 } ··· 635 635 if (!sch) 636 636 /* Check if the subchannel is now available. */ 637 637 return __chp_add_new_sch(schid); 638 - spin_lock_irq(&sch->lock); 638 + spin_lock_irq(sch->lock); 639 639 for (i=0; i<8; i++) { 640 640 mask = 0x80 >> i; 641 641 if ((sch->schib.pmcw.pim & mask) && 642 642 (sch->schib.pmcw.chpid[i] == chp->id)) { 643 643 if (stsch(sch->schid, &sch->schib) != 0) { 644 644 /* Endgame. */ 645 - spin_unlock_irq(&sch->lock); 645 + spin_unlock_irq(sch->lock); 646 646 return -ENXIO; 647 647 } 648 648 break; 649 649 } 650 650 } 651 651 if (i==8) { 652 - spin_unlock_irq(&sch->lock); 652 + spin_unlock_irq(sch->lock); 653 653 return 0; 654 654 } 655 655 sch->lpm = ((sch->schib.pmcw.pim & ··· 660 660 if (sch->driver && sch->driver->verify) 661 661 sch->driver->verify(&sch->dev); 662 662 663 - spin_unlock_irq(&sch->lock); 663 + spin_unlock_irq(sch->lock); 664 664 put_device(&sch->dev); 665 665 return 0; 666 666 } ··· 750 750 if (!sch->ssd_info.valid) 751 751 return; 752 752 753 - spin_lock_irqsave(&sch->lock, flags); 753 + spin_lock_irqsave(sch->lock, flags); 754 754 old_lpm = sch->lpm; 755 755 for (chp = 0; chp < 8; chp++) { 756 756 if (sch->ssd_info.chpid[chp] != chpid) ··· 785 785 sch->driver->verify(&sch->dev); 786 786 break; 787 787 } 788 - spin_unlock_irqrestore(&sch->lock, flags); 788 + spin_unlock_irqrestore(sch->lock, flags); 789 789 } 790 790 791 791 static int
+45 -17
drivers/s390/cio/cio.c
··· 143 143 return 1; 144 144 local_bh_disable(); 145 145 irq_enter (); 146 - spin_lock(&sch->lock); 146 + spin_lock(sch->lock); 147 147 memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw)); 148 148 if (sch->driver && sch->driver->irq) 149 149 sch->driver->irq(&sch->dev); 150 - spin_unlock(&sch->lock); 150 + spin_unlock(sch->lock); 151 151 irq_exit (); 152 152 _local_bh_enable(); 153 153 return 1; ··· 415 415 CIO_TRACE_EVENT (2, "ensch"); 416 416 CIO_TRACE_EVENT (2, sch->dev.bus_id); 417 417 418 + if (sch_is_pseudo_sch(sch)) 419 + return -EINVAL; 418 420 ccode = stsch (sch->schid, &sch->schib); 419 421 if (ccode) 420 422 return -ENODEV; ··· 464 462 CIO_TRACE_EVENT (2, "dissch"); 465 463 CIO_TRACE_EVENT (2, sch->dev.bus_id); 466 464 465 + if (sch_is_pseudo_sch(sch)) 466 + return 0; 467 467 ccode = stsch (sch->schid, &sch->schib); 468 468 if (ccode == 3) /* Not operational. */ 469 469 return -ENODEV; ··· 500 496 return ret; 501 497 } 502 498 499 + int cio_create_sch_lock(struct subchannel *sch) 500 + { 501 + sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); 502 + if (!sch->lock) 503 + return -ENOMEM; 504 + spin_lock_init(sch->lock); 505 + return 0; 506 + } 507 + 503 508 /* 504 509 * cio_validate_subchannel() 505 510 * ··· 526 513 { 527 514 char dbf_txt[15]; 528 515 int ccode; 516 + int err; 529 517 530 518 sprintf (dbf_txt, "valsch%x", schid.sch_no); 531 519 CIO_TRACE_EVENT (4, dbf_txt); ··· 534 520 /* Nuke all fields. */ 535 521 memset(sch, 0, sizeof(struct subchannel)); 536 522 537 - spin_lock_init(&sch->lock); 523 + sch->schid = schid; 524 + if (cio_is_console(schid)) { 525 + sch->lock = cio_get_console_lock(); 526 + } else { 527 + err = cio_create_sch_lock(sch); 528 + if (err) 529 + goto out; 530 + } 538 531 mutex_init(&sch->reg_mutex); 539 - 540 532 /* Set a name for the subchannel */ 541 533 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", schid.ssid, 542 534 schid.sch_no); ··· 554 534 * is not valid. 555 535 */ 556 536 ccode = stsch_err (schid, &sch->schib); 557 - if (ccode) 558 - return (ccode == 3) ? -ENXIO : ccode; 559 - 560 - sch->schid = schid; 537 + if (ccode) { 538 + err = (ccode == 3) ? -ENXIO : ccode; 539 + goto out; 540 + } 561 541 /* Copy subchannel type from path management control word. */ 562 542 sch->st = sch->schib.pmcw.st; 563 543 ··· 570 550 "non-I/O subchannel type %04X\n", 571 551 sch->schid.ssid, sch->schid.sch_no, sch->st); 572 552 /* We stop here for non-io subchannels. */ 573 - return sch->st; 553 + err = sch->st; 554 + goto out; 574 555 } 575 556 576 557 /* Initialization for io subchannels. */ 577 - if (!sch->schib.pmcw.dnv) 558 + if (!sch->schib.pmcw.dnv) { 578 559 /* io subchannel but device number is invalid. */ 579 - return -ENODEV; 580 - 560 + err = -ENODEV; 561 + goto out; 562 + } 581 563 /* Devno is valid. */ 582 564 if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) { 583 565 /* ··· 589 567 CIO_MSG_EVENT(0, "Blacklisted device detected " 590 568 "at devno %04X, subchannel set %x\n", 591 569 sch->schib.pmcw.dev, sch->schid.ssid); 592 - return -ENODEV; 570 + err = -ENODEV; 571 + goto out; 593 572 } 594 573 sch->opm = 0xff; 595 574 if (!cio_is_console(sch->schid)) ··· 618 595 if ((sch->lpm & (sch->lpm - 1)) != 0) 619 596 sch->schib.pmcw.mp = 1; /* multipath mode */ 620 597 return 0; 598 + out: 599 + if (!cio_is_console(schid)) 600 + kfree(sch->lock); 601 + sch->lock = NULL; 602 + return err; 621 603 } 622 604 623 605 /* ··· 665 637 } 666 638 sch = (struct subchannel *)(unsigned long)tpi_info->intparm; 667 639 if (sch) 668 - spin_lock(&sch->lock); 640 + spin_lock(sch->lock); 669 641 /* Store interrupt response block to lowcore. */ 670 642 if (tsch (tpi_info->schid, irb) == 0 && sch) { 671 643 /* Keep subchannel information word up to date. */ ··· 676 648 sch->driver->irq(&sch->dev); 677 649 } 678 650 if (sch) 679 - spin_unlock(&sch->lock); 651 + spin_unlock(sch->lock); 680 652 /* 681 653 * Are more interrupts pending? 682 654 * If so, the tpi instruction will update the lowcore ··· 715 687 __ctl_load (cr6, 6, 6); 716 688 717 689 do { 718 - spin_unlock(&console_subchannel.lock); 690 + spin_unlock(console_subchannel.lock); 719 691 if (!cio_tpi()) 720 692 cpu_relax(); 721 - spin_lock(&console_subchannel.lock); 693 + spin_lock(console_subchannel.lock); 722 694 } while (console_subchannel.schib.scsw.actl != 0); 723 695 /* 724 696 * restore previous isc value
+5 -1
drivers/s390/cio/cio.h
··· 87 87 /* subchannel data structure used by I/O subroutines */ 88 88 struct subchannel { 89 89 struct subchannel_id schid; 90 - spinlock_t lock; /* subchannel lock */ 90 + spinlock_t *lock; /* subchannel lock */ 91 91 struct mutex reg_mutex; 92 92 enum { 93 93 SUBCHANNEL_TYPE_IO = 0, ··· 131 131 extern int cio_get_options (struct subchannel *); 132 132 extern int cio_modify (struct subchannel *); 133 133 134 + int cio_create_sch_lock(struct subchannel *); 135 + 134 136 /* Use with care. */ 135 137 #ifdef CONFIG_CCW_CONSOLE 136 138 extern struct subchannel *cio_probe_console(void); 137 139 extern void cio_release_console(void); 138 140 extern int cio_is_console(struct subchannel_id); 139 141 extern struct subchannel *cio_get_console_subchannel(void); 142 + extern spinlock_t * cio_get_console_lock(void); 140 143 #else 141 144 #define cio_is_console(schid) 0 142 145 #define cio_get_console_subchannel() NULL 146 + #define cio_get_console_lock() NULL; 143 147 #endif 144 148 145 149 extern int cio_show_msg;
+51 -18
drivers/s390/cio/css.c
··· 91 91 /* Reset intparm to zeroes. */ 92 92 sch->schib.pmcw.intparm = 0; 93 93 cio_modify(sch); 94 + kfree(sch->lock); 94 95 kfree(sch); 95 96 } 96 - 97 97 } 98 98 99 99 static void ··· 102 102 struct subchannel *sch; 103 103 104 104 sch = to_subchannel(dev); 105 - if (!cio_is_console(sch->schid)) 105 + if (!cio_is_console(sch->schid)) { 106 + kfree(sch->lock); 106 107 kfree(sch); 108 + } 107 109 } 108 110 109 111 extern int css_get_ssd_info(struct subchannel *sch); ··· 137 135 sch->dev.parent = &css[0]->device; 138 136 sch->dev.bus = &css_bus_type; 139 137 sch->dev.release = &css_subchannel_release; 140 - 138 + sch->dev.groups = subch_attr_groups; 139 + 141 140 /* make it known to the system */ 142 141 ret = css_sch_device_register(sch); 143 - if (ret) 142 + if (ret) { 144 143 printk (KERN_WARNING "%s: could not register %s\n", 145 144 __func__, sch->dev.bus_id); 146 - else 147 - css_get_ssd_info(sch); 145 + return ret; 146 + } 147 + css_get_ssd_info(sch); 148 148 return ret; 149 149 } 150 150 ··· 205 201 unsigned long flags; 206 202 enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action; 207 203 208 - spin_lock_irqsave(&sch->lock, flags); 204 + spin_lock_irqsave(sch->lock, flags); 209 205 disc = device_is_disconnected(sch); 210 206 if (disc && slow) { 211 207 /* Disconnected devices are evaluated directly only.*/ 212 - spin_unlock_irqrestore(&sch->lock, flags); 208 + spin_unlock_irqrestore(sch->lock, flags); 213 209 return 0; 214 210 } 215 211 /* No interrupt after machine check - kill pending timers. */ 216 212 device_kill_pending_timer(sch); 217 213 if (!disc && !slow) { 218 214 /* Non-disconnected devices are evaluated on the slow path. */ 219 - spin_unlock_irqrestore(&sch->lock, flags); 215 + spin_unlock_irqrestore(sch->lock, flags); 220 216 return -EAGAIN; 221 217 } 222 218 event = css_get_subchannel_status(sch); ··· 241 237 /* Ask driver what to do with device. */ 242 238 action = UNREGISTER; 243 239 if (sch->driver && sch->driver->notify) { 244 - spin_unlock_irqrestore(&sch->lock, flags); 240 + spin_unlock_irqrestore(sch->lock, flags); 245 241 ret = sch->driver->notify(&sch->dev, event); 246 - spin_lock_irqsave(&sch->lock, flags); 242 + spin_lock_irqsave(sch->lock, flags); 247 243 if (ret) 248 244 action = NONE; 249 245 } ··· 268 264 case UNREGISTER: 269 265 case UNREGISTER_PROBE: 270 266 /* Unregister device (will use subchannel lock). */ 271 - spin_unlock_irqrestore(&sch->lock, flags); 267 + spin_unlock_irqrestore(sch->lock, flags); 272 268 css_sch_device_unregister(sch); 273 - spin_lock_irqsave(&sch->lock, flags); 269 + spin_lock_irqsave(sch->lock, flags); 274 270 275 271 /* Reset intparm to zeroes. */ 276 272 sch->schib.pmcw.intparm = 0; ··· 282 278 default: 283 279 break; 284 280 } 285 - spin_unlock_irqrestore(&sch->lock, flags); 281 + spin_unlock_irqrestore(sch->lock, flags); 286 282 /* Probe if necessary. */ 287 283 if (action == UNREGISTER_PROBE) 288 284 ret = css_probe_device(sch->schid); ··· 577 573 578 574 static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store); 579 575 580 - static inline void __init 581 - setup_css(int nr) 576 + static inline int __init setup_css(int nr) 582 577 { 583 578 u32 tod_high; 579 + int ret; 584 580 585 581 memset(css[nr], 0, sizeof(struct channel_subsystem)); 582 + css[nr]->pseudo_subchannel = 583 + kzalloc(sizeof(*css[nr]->pseudo_subchannel), GFP_KERNEL); 584 + if (!css[nr]->pseudo_subchannel) 585 + return -ENOMEM; 586 + css[nr]->pseudo_subchannel->dev.parent = &css[nr]->device; 587 + css[nr]->pseudo_subchannel->dev.release = css_subchannel_release; 588 + sprintf(css[nr]->pseudo_subchannel->dev.bus_id, "defunct"); 589 + ret = cio_create_sch_lock(css[nr]->pseudo_subchannel); 590 + if (ret) { 591 + kfree(css[nr]->pseudo_subchannel); 592 + return ret; 593 + } 586 594 mutex_init(&css[nr]->mutex); 587 595 css[nr]->valid = 1; 588 596 css[nr]->cssid = nr; ··· 602 586 css[nr]->device.release = channel_subsystem_release; 603 587 tod_high = (u32) (get_clock() >> 32); 604 588 css_generate_pgid(css[nr], tod_high); 589 + return 0; 605 590 } 606 591 607 592 /* ··· 639 622 ret = -ENOMEM; 640 623 goto out_unregister; 641 624 } 642 - setup_css(i); 643 - ret = device_register(&css[i]->device); 625 + ret = setup_css(i); 644 626 if (ret) 645 627 goto out_free; 628 + ret = device_register(&css[i]->device); 629 + if (ret) 630 + goto out_free_all; 646 631 if (css_characteristics_avail && 647 632 css_chsc_characteristics.secm) { 648 633 ret = device_create_file(&css[i]->device, ··· 652 633 if (ret) 653 634 goto out_device; 654 635 } 636 + ret = device_register(&css[i]->pseudo_subchannel->dev); 637 + if (ret) 638 + goto out_file; 655 639 } 656 640 css_init_done = 1; 657 641 ··· 662 640 663 641 for_each_subchannel(__init_channel_subsystem, NULL); 664 642 return 0; 643 + out_file: 644 + device_remove_file(&css[i]->device, &dev_attr_cm_enable); 665 645 out_device: 666 646 device_unregister(&css[i]->device); 647 + out_free_all: 648 + kfree(css[i]->pseudo_subchannel->lock); 649 + kfree(css[i]->pseudo_subchannel); 667 650 out_free: 668 651 kfree(css[i]); 669 652 out_unregister: 670 653 while (i > 0) { 671 654 i--; 655 + device_unregister(&css[i]->pseudo_subchannel->dev); 672 656 if (css_characteristics_avail && css_chsc_characteristics.secm) 673 657 device_remove_file(&css[i]->device, 674 658 &dev_attr_cm_enable); ··· 684 656 bus_unregister(&css_bus_type); 685 657 out: 686 658 return ret; 659 + } 660 + 661 + int sch_is_pseudo_sch(struct subchannel *sch) 662 + { 663 + return sch == to_css(sch->dev.parent)->pseudo_subchannel; 687 664 } 688 665 689 666 /*
+9
drivers/s390/cio/css.h
··· 73 73 } __attribute__ ((packed,aligned(4))); 74 74 75 75 struct ccw_device_private { 76 + struct ccw_device *cdev; 77 + struct subchannel *sch; 76 78 int state; /* device state */ 77 79 atomic_t onoff; 78 80 unsigned long registered; ··· 160 158 int cm_enabled; 161 159 void *cub_addr1; 162 160 void *cub_addr2; 161 + /* for orphaned ccw devices */ 162 + struct subchannel *pseudo_subchannel; 163 163 }; 164 164 #define to_css(dev) container_of(dev, struct channel_subsystem, device) 165 165 ··· 189 185 int css_slow_subchannels_exist(void); 190 186 extern int need_rescan; 191 187 188 + int sch_is_pseudo_sch(struct subchannel *); 189 + 192 190 extern struct workqueue_struct *slow_path_wq; 193 191 extern struct work_struct slow_path_work; 192 + 193 + int subchannel_add_files (struct device *); 194 + extern struct attribute_group *subch_attr_groups[]; 194 195 #endif
+343 -113
drivers/s390/cio/device.c
··· 23 23 #include <asm/param.h> /* HZ */ 24 24 25 25 #include "cio.h" 26 + #include "cio_debug.h" 26 27 #include "css.h" 27 28 #include "device.h" 28 29 #include "ioasm.h" ··· 235 234 ssize_t ret = 0; 236 235 int chp; 237 236 238 - for (chp = 0; chp < 8; chp++) 239 - ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]); 240 - 237 + if (ssd) 238 + for (chp = 0; chp < 8; chp++) 239 + ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]); 240 + else 241 + ret += sprintf (buf, "n/a"); 241 242 ret += sprintf (buf+ret, "\n"); 242 243 return min((ssize_t)PAGE_SIZE, ret); 243 244 } ··· 297 294 return sprintf(buf, cdev->online ? "1\n" : "0\n"); 298 295 } 299 296 297 + int ccw_device_is_orphan(struct ccw_device *cdev) 298 + { 299 + return sch_is_pseudo_sch(to_subchannel(cdev->dev.parent)); 300 + } 301 + 302 + static void ccw_device_unregister(struct work_struct *work) 303 + { 304 + struct ccw_device_private *priv; 305 + struct ccw_device *cdev; 306 + 307 + priv = container_of(work, struct ccw_device_private, kick_work); 308 + cdev = priv->cdev; 309 + if (test_and_clear_bit(1, &cdev->private->registered)) 310 + device_unregister(&cdev->dev); 311 + put_device(&cdev->dev); 312 + } 313 + 300 314 static void 301 315 ccw_device_remove_disconnected(struct ccw_device *cdev) 302 316 { 303 317 struct subchannel *sch; 318 + unsigned long flags; 304 319 /* 305 320 * Forced offline in disconnected state means 306 321 * 'throw away device'. 307 322 */ 323 + if (ccw_device_is_orphan(cdev)) { 324 + /* Deregister ccw device. */ 325 + spin_lock_irqsave(cdev->ccwlock, flags); 326 + cdev->private->state = DEV_STATE_NOT_OPER; 327 + spin_unlock_irqrestore(cdev->ccwlock, flags); 328 + if (get_device(&cdev->dev)) { 329 + PREPARE_WORK(&cdev->private->kick_work, 330 + ccw_device_unregister); 331 + queue_work(ccw_device_work, &cdev->private->kick_work); 332 + } 333 + return ; 334 + } 308 335 sch = to_subchannel(cdev->dev.parent); 309 336 css_sch_device_unregister(sch); 310 337 /* Reset intparm to zeroes. */ ··· 495 462 struct ccw_device *cdev = to_ccwdev(dev); 496 463 struct subchannel *sch; 497 464 465 + if (ccw_device_is_orphan(cdev)) 466 + return sprintf(buf, "no device\n"); 498 467 switch (cdev->private->state) { 499 468 case DEV_STATE_BOXED: 500 469 return sprintf(buf, "boxed\n"); ··· 533 498 .attrs = subch_attrs, 534 499 }; 535 500 536 - static inline int 537 - subchannel_add_files (struct device *dev) 538 - { 539 - return sysfs_create_group(&dev->kobj, &subch_attr_group); 540 - } 501 + struct attribute_group *subch_attr_groups[] = { 502 + &subch_attr_group, 503 + NULL, 504 + }; 541 505 542 506 static struct attribute * ccwdev_attrs[] = { 543 507 &dev_attr_devtype.attr, ··· 597 563 598 564 cdev = to_ccwdev(dev); 599 565 if ((cdev->private->state == DEV_STATE_DISCONNECTED) && 566 + !ccw_device_is_orphan(cdev) && 600 567 ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) && 601 - (cdev != d->sibling)) { 602 - cdev->private->state = DEV_STATE_NOT_OPER; 568 + (cdev != d->sibling)) 603 569 return 1; 604 - } 605 570 return 0; 606 571 } 607 572 ··· 617 584 return dev ? to_ccwdev(dev) : NULL; 618 585 } 619 586 620 - static void 621 - ccw_device_add_changed(void *data) 587 + static int match_orphan(struct device *dev, void *data) 622 588 { 623 - 589 + struct ccw_dev_id *dev_id; 624 590 struct ccw_device *cdev; 625 591 626 - cdev = data; 592 + dev_id = data; 593 + cdev = to_ccwdev(dev); 594 + return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); 595 + } 596 + 597 + static struct ccw_device * 598 + get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css, 599 + struct ccw_dev_id *dev_id) 600 + { 601 + struct device *dev; 602 + 603 + dev = device_find_child(&css->pseudo_subchannel->dev, dev_id, 604 + match_orphan); 605 + 606 + return dev ? to_ccwdev(dev) : NULL; 607 + } 608 + 609 + static void 610 + ccw_device_add_changed(struct work_struct *work) 611 + { 612 + struct ccw_device_private *priv; 613 + struct ccw_device *cdev; 614 + 615 + priv = container_of(work, struct ccw_device_private, kick_work); 616 + cdev = priv->cdev; 627 617 if (device_add(&cdev->dev)) { 628 618 put_device(&cdev->dev); 629 619 return; ··· 658 602 } 659 603 } 660 604 661 - extern int css_get_ssd_info(struct subchannel *sch); 662 - 663 - void 664 - ccw_device_do_unreg_rereg(void *data) 605 + void ccw_device_do_unreg_rereg(struct work_struct *work) 665 606 { 607 + struct ccw_device_private *priv; 666 608 struct ccw_device *cdev; 667 609 struct subchannel *sch; 668 - int need_rename; 669 610 670 - cdev = data; 611 + priv = container_of(work, struct ccw_device_private, kick_work); 612 + cdev = priv->cdev; 671 613 sch = to_subchannel(cdev->dev.parent); 672 - if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) { 673 - /* 674 - * The device number has changed. This is usually only when 675 - * a device has been detached under VM and then re-appeared 676 - * on another subchannel because of a different attachment 677 - * order than before. Ideally, we should should just switch 678 - * subchannels, but unfortunately, this is not possible with 679 - * the current implementation. 680 - * Instead, we search for the old subchannel for this device 681 - * number and deregister so there are no collisions with the 682 - * newly registered ccw_device. 683 - * FIXME: Find another solution so the block layer doesn't 684 - * get possibly sick... 685 - */ 686 - struct ccw_device *other_cdev; 687 - struct ccw_dev_id dev_id; 688 614 689 - need_rename = 1; 690 - dev_id.devno = sch->schib.pmcw.dev; 691 - dev_id.ssid = sch->schid.ssid; 692 - other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); 693 - if (other_cdev) { 694 - struct subchannel *other_sch; 695 - 696 - other_sch = to_subchannel(other_cdev->dev.parent); 697 - if (get_device(&other_sch->dev)) { 698 - stsch(other_sch->schid, &other_sch->schib); 699 - if (other_sch->schib.pmcw.dnv) { 700 - other_sch->schib.pmcw.intparm = 0; 701 - cio_modify(other_sch); 702 - } 703 - css_sch_device_unregister(other_sch); 704 - } 705 - } 706 - /* Update ssd info here. */ 707 - css_get_ssd_info(sch); 708 - cdev->private->dev_id.devno = sch->schib.pmcw.dev; 709 - } else 710 - need_rename = 0; 711 615 device_remove_files(&cdev->dev); 712 616 if (test_and_clear_bit(1, &cdev->private->registered)) 713 617 device_del(&cdev->dev); 714 - if (need_rename) 715 - snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", 716 - sch->schid.ssid, sch->schib.pmcw.dev); 717 618 PREPARE_WORK(&cdev->private->kick_work, 718 - ccw_device_add_changed, cdev); 619 + ccw_device_add_changed); 719 620 queue_work(ccw_device_work, &cdev->private->kick_work); 720 621 } 721 622 ··· 686 673 kfree(cdev); 687 674 } 688 675 676 + static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch) 677 + { 678 + struct ccw_device *cdev; 679 + 680 + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 681 + if (cdev) { 682 + cdev->private = kzalloc(sizeof(struct ccw_device_private), 683 + GFP_KERNEL | GFP_DMA); 684 + if (cdev->private) 685 + return cdev; 686 + } 687 + kfree(cdev); 688 + return ERR_PTR(-ENOMEM); 689 + } 690 + 691 + static int io_subchannel_initialize_dev(struct subchannel *sch, 692 + struct ccw_device *cdev) 693 + { 694 + cdev->private->cdev = cdev; 695 + atomic_set(&cdev->private->onoff, 0); 696 + cdev->dev.parent = &sch->dev; 697 + cdev->dev.release = ccw_device_release; 698 + INIT_LIST_HEAD(&cdev->private->kick_work.entry); 699 + /* Do first half of device_register. */ 700 + device_initialize(&cdev->dev); 701 + if (!get_device(&sch->dev)) { 702 + if (cdev->dev.release) 703 + cdev->dev.release(&cdev->dev); 704 + return -ENODEV; 705 + } 706 + return 0; 707 + } 708 + 709 + static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) 710 + { 711 + struct ccw_device *cdev; 712 + int ret; 713 + 714 + cdev = io_subchannel_allocate_dev(sch); 715 + if (!IS_ERR(cdev)) { 716 + ret = io_subchannel_initialize_dev(sch, cdev); 717 + if (ret) { 718 + kfree(cdev); 719 + cdev = ERR_PTR(ret); 720 + } 721 + } 722 + return cdev; 723 + } 724 + 725 + static int io_subchannel_recog(struct ccw_device *, struct subchannel *); 726 + 727 + static void sch_attach_device(struct subchannel *sch, 728 + struct ccw_device *cdev) 729 + { 730 + spin_lock_irq(sch->lock); 731 + sch->dev.driver_data = cdev; 732 + cdev->private->schid = sch->schid; 733 + cdev->ccwlock = sch->lock; 734 + device_trigger_reprobe(sch); 735 + spin_unlock_irq(sch->lock); 736 + } 737 + 738 + static void sch_attach_disconnected_device(struct subchannel *sch, 739 + struct ccw_device *cdev) 740 + { 741 + struct subchannel *other_sch; 742 + int ret; 743 + 744 + other_sch = to_subchannel(get_device(cdev->dev.parent)); 745 + ret = device_move(&cdev->dev, &sch->dev); 746 + if (ret) { 747 + CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed " 748 + "(ret=%d)!\n", cdev->private->dev_id.ssid, 749 + cdev->private->dev_id.devno, ret); 750 + put_device(&other_sch->dev); 751 + return; 752 + } 753 + other_sch->dev.driver_data = NULL; 754 + /* No need to keep a subchannel without ccw device around. */ 755 + css_sch_device_unregister(other_sch); 756 + put_device(&other_sch->dev); 757 + sch_attach_device(sch, cdev); 758 + } 759 + 760 + static void sch_attach_orphaned_device(struct subchannel *sch, 761 + struct ccw_device *cdev) 762 + { 763 + int ret; 764 + 765 + /* Try to move the ccw device to its new subchannel. */ 766 + ret = device_move(&cdev->dev, &sch->dev); 767 + if (ret) { 768 + CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage " 769 + "failed (ret=%d)!\n", 770 + cdev->private->dev_id.ssid, 771 + cdev->private->dev_id.devno, ret); 772 + return; 773 + } 774 + sch_attach_device(sch, cdev); 775 + } 776 + 777 + static void sch_create_and_recog_new_device(struct subchannel *sch) 778 + { 779 + struct ccw_device *cdev; 780 + 781 + /* Need to allocate a new ccw device. */ 782 + cdev = io_subchannel_create_ccwdev(sch); 783 + if (IS_ERR(cdev)) { 784 + /* OK, we did everything we could... */ 785 + css_sch_device_unregister(sch); 786 + return; 787 + } 788 + spin_lock_irq(sch->lock); 789 + sch->dev.driver_data = cdev; 790 + spin_unlock_irq(sch->lock); 791 + /* Start recognition for the new ccw device. */ 792 + if (io_subchannel_recog(cdev, sch)) { 793 + spin_lock_irq(sch->lock); 794 + sch->dev.driver_data = NULL; 795 + spin_unlock_irq(sch->lock); 796 + if (cdev->dev.release) 797 + cdev->dev.release(&cdev->dev); 798 + css_sch_device_unregister(sch); 799 + } 800 + } 801 + 802 + 803 + void ccw_device_move_to_orphanage(struct work_struct *work) 804 + { 805 + struct ccw_device_private *priv; 806 + struct ccw_device *cdev; 807 + struct ccw_device *replacing_cdev; 808 + struct subchannel *sch; 809 + int ret; 810 + struct channel_subsystem *css; 811 + struct ccw_dev_id dev_id; 812 + 813 + priv = container_of(work, struct ccw_device_private, kick_work); 814 + cdev = priv->cdev; 815 + sch = to_subchannel(cdev->dev.parent); 816 + css = to_css(sch->dev.parent); 817 + dev_id.devno = sch->schib.pmcw.dev; 818 + dev_id.ssid = sch->schid.ssid; 819 + 820 + /* 821 + * Move the orphaned ccw device to the orphanage so the replacing 822 + * ccw device can take its place on the subchannel. 823 + */ 824 + ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev); 825 + if (ret) { 826 + CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed " 827 + "(ret=%d)!\n", cdev->private->dev_id.ssid, 828 + cdev->private->dev_id.devno, ret); 829 + return; 830 + } 831 + cdev->ccwlock = css->pseudo_subchannel->lock; 832 + /* 833 + * Search for the replacing ccw device 834 + * - among the disconnected devices 835 + * - in the orphanage 836 + */ 837 + replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); 838 + if (replacing_cdev) { 839 + sch_attach_disconnected_device(sch, replacing_cdev); 840 + return; 841 + } 842 + replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id); 843 + if (replacing_cdev) { 844 + sch_attach_orphaned_device(sch, replacing_cdev); 845 + return; 846 + } 847 + sch_create_and_recog_new_device(sch); 848 + } 849 + 689 850 /* 690 851 * Register recognized device. 691 852 */ 692 853 static void 693 - io_subchannel_register(void *data) 854 + io_subchannel_register(struct work_struct *work) 694 855 { 856 + struct ccw_device_private *priv; 695 857 struct ccw_device *cdev; 696 858 struct subchannel *sch; 697 859 int ret; 698 860 unsigned long flags; 699 861 700 - cdev = data; 862 + priv = container_of(work, struct ccw_device_private, kick_work); 863 + cdev = priv->cdev; 701 864 sch = to_subchannel(cdev->dev.parent); 702 865 703 866 /* ··· 898 709 printk (KERN_WARNING "%s: could not register %s\n", 899 710 __func__, cdev->dev.bus_id); 900 711 put_device(&cdev->dev); 901 - spin_lock_irqsave(&sch->lock, flags); 712 + spin_lock_irqsave(sch->lock, flags); 902 713 sch->dev.driver_data = NULL; 903 - spin_unlock_irqrestore(&sch->lock, flags); 714 + spin_unlock_irqrestore(sch->lock, flags); 904 715 kfree (cdev->private); 905 716 kfree (cdev); 906 717 put_device(&sch->dev); ··· 908 719 wake_up(&ccw_device_init_wq); 909 720 return; 910 721 } 911 - 912 - ret = subchannel_add_files(cdev->dev.parent); 913 - if (ret) 914 - printk(KERN_WARNING "%s: could not add attributes to %s\n", 915 - __func__, sch->dev.bus_id); 916 722 put_device(&cdev->dev); 917 723 out: 918 724 cdev->private->flags.recog_done = 1; ··· 918 734 } 919 735 920 736 void 921 - ccw_device_call_sch_unregister(void *data) 737 + ccw_device_call_sch_unregister(struct work_struct *work) 922 738 { 923 - struct ccw_device *cdev = data; 739 + struct ccw_device_private *priv; 740 + struct ccw_device *cdev; 924 741 struct subchannel *sch; 925 742 743 + priv = container_of(work, struct ccw_device_private, kick_work); 744 + cdev = priv->cdev; 926 745 sch = to_subchannel(cdev->dev.parent); 927 746 css_sch_device_unregister(sch); 928 747 /* Reset intparm to zeroes. */ ··· 955 768 break; 956 769 sch = to_subchannel(cdev->dev.parent); 957 770 PREPARE_WORK(&cdev->private->kick_work, 958 - ccw_device_call_sch_unregister, cdev); 771 + ccw_device_call_sch_unregister); 959 772 queue_work(slow_path_wq, &cdev->private->kick_work); 960 773 if (atomic_dec_and_test(&ccw_device_init_count)) 961 774 wake_up(&ccw_device_init_wq); ··· 970 783 if (!get_device(&cdev->dev)) 971 784 break; 972 785 PREPARE_WORK(&cdev->private->kick_work, 973 - io_subchannel_register, cdev); 786 + io_subchannel_register); 974 787 queue_work(slow_path_wq, &cdev->private->kick_work); 975 788 break; 976 789 } ··· 984 797 985 798 sch->dev.driver_data = cdev; 986 799 sch->driver = &io_subchannel_driver; 987 - cdev->ccwlock = &sch->lock; 800 + cdev->ccwlock = sch->lock; 988 801 989 802 /* Init private data. */ 990 803 priv = cdev->private; ··· 1004 817 atomic_inc(&ccw_device_init_count); 1005 818 1006 819 /* Start async. device sensing. */ 1007 - spin_lock_irq(&sch->lock); 820 + spin_lock_irq(sch->lock); 1008 821 rc = ccw_device_recognition(cdev); 1009 - spin_unlock_irq(&sch->lock); 822 + spin_unlock_irq(sch->lock); 1010 823 if (rc) { 1011 824 if (atomic_dec_and_test(&ccw_device_init_count)) 1012 825 wake_up(&ccw_device_init_wq); 1013 826 } 1014 827 return rc; 828 + } 829 + 830 + static void ccw_device_move_to_sch(struct work_struct *work) 831 + { 832 + struct ccw_device_private *priv; 833 + int rc; 834 + struct subchannel *sch; 835 + struct ccw_device *cdev; 836 + struct subchannel *former_parent; 837 + 838 + priv = container_of(work, struct ccw_device_private, kick_work); 839 + sch = priv->sch; 840 + cdev = priv->cdev; 841 + former_parent = ccw_device_is_orphan(cdev) ? 842 + NULL : to_subchannel(get_device(cdev->dev.parent)); 843 + mutex_lock(&sch->reg_mutex); 844 + /* Try to move the ccw device to its new subchannel. */ 845 + rc = device_move(&cdev->dev, &sch->dev); 846 + mutex_unlock(&sch->reg_mutex); 847 + if (rc) { 848 + CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel " 849 + "0.%x.%04x failed (ret=%d)!\n", 850 + cdev->private->dev_id.ssid, 851 + cdev->private->dev_id.devno, sch->schid.ssid, 852 + sch->schid.sch_no, rc); 853 + css_sch_device_unregister(sch); 854 + goto out; 855 + } 856 + if (former_parent) { 857 + spin_lock_irq(former_parent->lock); 858 + former_parent->dev.driver_data = NULL; 859 + spin_unlock_irq(former_parent->lock); 860 + css_sch_device_unregister(former_parent); 861 + /* Reset intparm to zeroes. */ 862 + former_parent->schib.pmcw.intparm = 0; 863 + cio_modify(former_parent); 864 + } 865 + sch_attach_device(sch, cdev); 866 + out: 867 + if (former_parent) 868 + put_device(&former_parent->dev); 869 + put_device(&cdev->dev); 1015 870 } 1016 871 1017 872 static int ··· 1062 833 struct ccw_device *cdev; 1063 834 int rc; 1064 835 unsigned long flags; 836 + struct ccw_dev_id dev_id; 1065 837 1066 838 if (sch->dev.driver_data) { 1067 839 /* ··· 1073 843 cdev = sch->dev.driver_data; 1074 844 device_initialize(&cdev->dev); 1075 845 ccw_device_register(cdev); 1076 - subchannel_add_files(&sch->dev); 1077 846 /* 1078 847 * Check if the device is already online. If it is 1079 848 * the reference count needs to be corrected ··· 1085 856 get_device(&cdev->dev); 1086 857 return 0; 1087 858 } 1088 - cdev = kzalloc (sizeof(*cdev), GFP_KERNEL); 859 + /* 860 + * First check if a fitting device may be found amongst the 861 + * disconnected devices or in the orphanage. 862 + */ 863 + dev_id.devno = sch->schib.pmcw.dev; 864 + dev_id.ssid = sch->schid.ssid; 865 + cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); 1089 866 if (!cdev) 1090 - return -ENOMEM; 1091 - cdev->private = kzalloc(sizeof(struct ccw_device_private), 1092 - GFP_KERNEL | GFP_DMA); 1093 - if (!cdev->private) { 1094 - kfree(cdev); 1095 - return -ENOMEM; 867 + cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), 868 + &dev_id); 869 + if (cdev) { 870 + /* 871 + * Schedule moving the device until when we have a registered 872 + * subchannel to move to and succeed the probe. We can 873 + * unregister later again, when the probe is through. 874 + */ 875 + cdev->private->sch = sch; 876 + PREPARE_WORK(&cdev->private->kick_work, 877 + ccw_device_move_to_sch); 878 + queue_work(slow_path_wq, &cdev->private->kick_work); 879 + return 0; 1096 880 } 1097 - atomic_set(&cdev->private->onoff, 0); 1098 - cdev->dev.parent = &sch->dev; 1099 - cdev->dev.release = ccw_device_release; 1100 - INIT_LIST_HEAD(&cdev->private->kick_work.entry); 1101 - /* Do first half of device_register. */ 1102 - device_initialize(&cdev->dev); 1103 - 1104 - if (!get_device(&sch->dev)) { 1105 - if (cdev->dev.release) 1106 - cdev->dev.release(&cdev->dev); 1107 - return -ENODEV; 1108 - } 881 + cdev = io_subchannel_create_ccwdev(sch); 882 + if (IS_ERR(cdev)) 883 + return PTR_ERR(cdev); 1109 884 1110 885 rc = io_subchannel_recog(cdev, sch); 1111 886 if (rc) { 1112 - spin_lock_irqsave(&sch->lock, flags); 887 + spin_lock_irqsave(sch->lock, flags); 1113 888 sch->dev.driver_data = NULL; 1114 - spin_unlock_irqrestore(&sch->lock, flags); 889 + spin_unlock_irqrestore(sch->lock, flags); 1115 890 if (cdev->dev.release) 1116 891 cdev->dev.release(&cdev->dev); 1117 892 } 1118 893 1119 894 return rc; 1120 - } 1121 - 1122 - static void 1123 - ccw_device_unregister(void *data) 1124 - { 1125 - struct ccw_device *cdev; 1126 - 1127 - cdev = (struct ccw_device *)data; 1128 - if (test_and_clear_bit(1, &cdev->private->registered)) 1129 - device_unregister(&cdev->dev); 1130 - put_device(&cdev->dev); 1131 895 } 1132 896 1133 897 static int ··· 1143 921 */ 1144 922 if (get_device(&cdev->dev)) { 1145 923 PREPARE_WORK(&cdev->private->kick_work, 1146 - ccw_device_unregister, cdev); 924 + ccw_device_unregister); 1147 925 queue_work(ccw_device_work, &cdev->private->kick_work); 1148 926 } 1149 927 return 0; ··· 1225 1003 static struct ccw_device_private console_private; 1226 1004 static int console_cdev_in_use; 1227 1005 1006 + static DEFINE_SPINLOCK(ccw_console_lock); 1007 + 1008 + spinlock_t * cio_get_console_lock(void) 1009 + { 1010 + return &ccw_console_lock; 1011 + } 1012 + 1228 1013 static int 1229 1014 ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch) 1230 1015 { ··· 1277 1048 memset(&console_cdev, 0, sizeof(struct ccw_device)); 1278 1049 memset(&console_private, 0, sizeof(struct ccw_device_private)); 1279 1050 console_cdev.private = &console_private; 1051 + console_private.cdev = &console_cdev; 1280 1052 ret = ccw_device_console_enable(&console_cdev, sch); 1281 1053 if (ret) { 1282 1054 cio_release_console();
+4 -2
drivers/s390/cio/device.h
··· 78 78 79 79 int ccw_device_cancel_halt_clear(struct ccw_device *); 80 80 81 - void ccw_device_do_unreg_rereg(void *); 82 - void ccw_device_call_sch_unregister(void *); 81 + void ccw_device_do_unreg_rereg(struct work_struct *); 82 + void ccw_device_call_sch_unregister(struct work_struct *); 83 + void ccw_device_move_to_orphanage(struct work_struct *); 84 + int ccw_device_is_orphan(struct ccw_device *); 83 85 84 86 int ccw_device_recognition(struct ccw_device *); 85 87 int ccw_device_online(struct ccw_device *);
+35 -23
drivers/s390/cio/device_fsm.c
··· 186 186 /* 187 187 * Check if cu type and device type still match. If 188 188 * not, it is certainly another device and we have to 189 - * de- and re-register. Also check here for non-matching devno. 189 + * de- and re-register. 190 190 */ 191 191 if (cdev->id.cu_type != cdev->private->senseid.cu_type || 192 192 cdev->id.cu_model != cdev->private->senseid.cu_model || 193 193 cdev->id.dev_type != cdev->private->senseid.dev_type || 194 - cdev->id.dev_model != cdev->private->senseid.dev_model || 195 - cdev->private->dev_id.devno != sch->schib.pmcw.dev) { 194 + cdev->id.dev_model != cdev->private->senseid.dev_model) { 196 195 PREPARE_WORK(&cdev->private->kick_work, 197 - ccw_device_do_unreg_rereg, cdev); 196 + ccw_device_do_unreg_rereg); 198 197 queue_work(ccw_device_work, &cdev->private->kick_work); 199 198 return 0; 200 199 } ··· 328 329 } 329 330 330 331 static void 331 - ccw_device_oper_notify(void *data) 332 + ccw_device_oper_notify(struct work_struct *work) 332 333 { 334 + struct ccw_device_private *priv; 333 335 struct ccw_device *cdev; 334 336 struct subchannel *sch; 335 337 int ret; 336 338 337 - cdev = data; 339 + priv = container_of(work, struct ccw_device_private, kick_work); 340 + cdev = priv->cdev; 338 341 sch = to_subchannel(cdev->dev.parent); 339 342 ret = (sch->driver && sch->driver->notify) ? 340 343 sch->driver->notify(&sch->dev, CIO_OPER) : 0; 341 344 if (!ret) 342 345 /* Driver doesn't want device back. */ 343 - ccw_device_do_unreg_rereg(cdev); 346 + ccw_device_do_unreg_rereg(work); 344 347 else { 345 348 /* Reenable channel measurements, if needed. */ 346 349 cmf_reenable(cdev); ··· 378 377 379 378 if (cdev->private->flags.donotify) { 380 379 cdev->private->flags.donotify = 0; 381 - PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify, 382 - cdev); 380 + PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify); 383 381 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 384 382 } 385 383 wake_up(&cdev->private->wait_q); ··· 528 528 529 529 530 530 static void 531 - ccw_device_nopath_notify(void *data) 531 + ccw_device_nopath_notify(struct work_struct *work) 532 532 { 533 + struct ccw_device_private *priv; 533 534 struct ccw_device *cdev; 534 535 struct subchannel *sch; 535 536 int ret; 536 537 537 - cdev = data; 538 + priv = container_of(work, struct ccw_device_private, kick_work); 539 + cdev = priv->cdev; 538 540 sch = to_subchannel(cdev->dev.parent); 539 541 /* Extra sanity. */ 540 542 if (sch->lpm) ··· 549 547 cio_disable_subchannel(sch); 550 548 if (get_device(&cdev->dev)) { 551 549 PREPARE_WORK(&cdev->private->kick_work, 552 - ccw_device_call_sch_unregister, 553 - cdev); 550 + ccw_device_call_sch_unregister); 554 551 queue_work(ccw_device_work, 555 552 &cdev->private->kick_work); 556 553 } else ··· 608 607 /* Reset oper notify indication after verify error. */ 609 608 cdev->private->flags.donotify = 0; 610 609 PREPARE_WORK(&cdev->private->kick_work, 611 - ccw_device_nopath_notify, cdev); 610 + ccw_device_nopath_notify); 612 611 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 613 612 ccw_device_done(cdev, DEV_STATE_NOT_OPER); 614 613 break; ··· 675 674 { 676 675 struct subchannel *sch; 677 676 677 + if (ccw_device_is_orphan(cdev)) { 678 + ccw_device_done(cdev, DEV_STATE_OFFLINE); 679 + return 0; 680 + } 678 681 sch = to_subchannel(cdev->dev.parent); 679 682 if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv) 680 683 return -ENODEV; ··· 743 738 sch = to_subchannel(cdev->dev.parent); 744 739 if (get_device(&cdev->dev)) { 745 740 PREPARE_WORK(&cdev->private->kick_work, 746 - ccw_device_call_sch_unregister, cdev); 741 + ccw_device_call_sch_unregister); 747 742 queue_work(ccw_device_work, &cdev->private->kick_work); 748 743 } 749 744 wake_up(&cdev->private->wait_q); ··· 774 769 } 775 770 if (get_device(&cdev->dev)) { 776 771 PREPARE_WORK(&cdev->private->kick_work, 777 - ccw_device_call_sch_unregister, cdev); 772 + ccw_device_call_sch_unregister); 778 773 queue_work(ccw_device_work, &cdev->private->kick_work); 779 774 } 780 775 wake_up(&cdev->private->wait_q); ··· 879 874 sch = to_subchannel(cdev->dev.parent); 880 875 if (!sch->lpm) { 881 876 PREPARE_WORK(&cdev->private->kick_work, 882 - ccw_device_nopath_notify, cdev); 877 + ccw_device_nopath_notify); 883 878 queue_work(ccw_device_notify_work, 884 879 &cdev->private->kick_work); 885 880 } else ··· 974 969 ERR_PTR(-EIO)); 975 970 if (!sch->lpm) { 976 971 PREPARE_WORK(&cdev->private->kick_work, 977 - ccw_device_nopath_notify, cdev); 972 + ccw_device_nopath_notify); 978 973 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 979 974 } else if (cdev->private->flags.doverify) 980 975 /* Start delayed path verification. */ ··· 997 992 sch = to_subchannel(cdev->dev.parent); 998 993 if (!sch->lpm) { 999 994 PREPARE_WORK(&cdev->private->kick_work, 1000 - ccw_device_nopath_notify, cdev); 995 + ccw_device_nopath_notify); 1001 996 queue_work(ccw_device_notify_work, 1002 997 &cdev->private->kick_work); 1003 998 } else ··· 1026 1021 if (ret == -ENODEV) { 1027 1022 if (!sch->lpm) { 1028 1023 PREPARE_WORK(&cdev->private->kick_work, 1029 - ccw_device_nopath_notify, cdev); 1024 + ccw_device_nopath_notify); 1030 1025 queue_work(ccw_device_notify_work, 1031 1026 &cdev->private->kick_work); 1032 1027 } else ··· 1038 1033 ERR_PTR(-EIO)); 1039 1034 if (!sch->lpm) { 1040 1035 PREPARE_WORK(&cdev->private->kick_work, 1041 - ccw_device_nopath_notify, cdev); 1036 + ccw_device_nopath_notify); 1042 1037 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 1043 1038 } else 1044 1039 /* Start delayed path verification. */ ··· 1109 1104 /* Update some values. */ 1110 1105 if (stsch(sch->schid, &sch->schib)) 1111 1106 return; 1112 - 1107 + if (!sch->schib.pmcw.dnv) 1108 + return; 1113 1109 /* 1114 1110 * The pim, pam, pom values may not be accurate, but they are the best 1115 1111 * we have before performing device selection :/ ··· 1124 1118 sch->schib.pmcw.mp = 1; 1125 1119 sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; 1126 1120 /* We should also udate ssd info, but this has to wait. */ 1127 - ccw_device_start_id(cdev, 0); 1121 + /* Check if this is another device which appeared on the same sch. */ 1122 + if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { 1123 + PREPARE_WORK(&cdev->private->kick_work, 1124 + ccw_device_move_to_orphanage); 1125 + queue_work(ccw_device_work, &cdev->private->kick_work); 1126 + } else 1127 + ccw_device_start_id(cdev, 0); 1128 1128 } 1129 1129 1130 1130 static void
+14 -14
drivers/s390/cio/device_ops.c
··· 316 316 ccw_device_set_timeout(cdev, 0); 317 317 if (ret == -EBUSY) { 318 318 /* Try again later. */ 319 - spin_unlock_irq(&sch->lock); 319 + spin_unlock_irq(sch->lock); 320 320 msleep(10); 321 - spin_lock_irq(&sch->lock); 321 + spin_lock_irq(sch->lock); 322 322 continue; 323 323 } 324 324 if (ret != 0) ··· 326 326 break; 327 327 /* Wait for end of request. */ 328 328 cdev->private->intparm = magic; 329 - spin_unlock_irq(&sch->lock); 329 + spin_unlock_irq(sch->lock); 330 330 wait_event(cdev->private->wait_q, 331 331 (cdev->private->intparm == -EIO) || 332 332 (cdev->private->intparm == -EAGAIN) || 333 333 (cdev->private->intparm == 0)); 334 - spin_lock_irq(&sch->lock); 334 + spin_lock_irq(sch->lock); 335 335 /* Check at least for channel end / device end */ 336 336 if (cdev->private->intparm == -EIO) { 337 337 /* Non-retryable error. */ ··· 342 342 /* Success. */ 343 343 break; 344 344 /* Try again later. */ 345 - spin_unlock_irq(&sch->lock); 345 + spin_unlock_irq(sch->lock); 346 346 msleep(10); 347 - spin_lock_irq(&sch->lock); 347 + spin_lock_irq(sch->lock); 348 348 } while (1); 349 349 350 350 return ret; ··· 389 389 return ret; 390 390 } 391 391 392 - spin_lock_irq(&sch->lock); 392 + spin_lock_irq(sch->lock); 393 393 /* Save interrupt handler. */ 394 394 handler = cdev->handler; 395 395 /* Temporarily install own handler. */ ··· 406 406 407 407 /* Restore interrupt handler. */ 408 408 cdev->handler = handler; 409 - spin_unlock_irq(&sch->lock); 409 + spin_unlock_irq(sch->lock); 410 410 411 411 clear_normalized_cda (rdc_ccw); 412 412 kfree(rdc_ccw); ··· 463 463 rcd_ccw->count = ciw->count; 464 464 rcd_ccw->flags = CCW_FLAG_SLI; 465 465 466 - spin_lock_irq(&sch->lock); 466 + spin_lock_irq(sch->lock); 467 467 /* Save interrupt handler. */ 468 468 handler = cdev->handler; 469 469 /* Temporarily install own handler. */ ··· 480 480 481 481 /* Restore interrupt handler. */ 482 482 cdev->handler = handler; 483 - spin_unlock_irq(&sch->lock); 483 + spin_unlock_irq(sch->lock); 484 484 485 485 /* 486 486 * on success we update the user input parms ··· 537 537 kfree(buf); 538 538 return -ENOMEM; 539 539 } 540 - spin_lock_irqsave(&sch->lock, flags); 540 + spin_lock_irqsave(sch->lock, flags); 541 541 ret = cio_enable_subchannel(sch, 3); 542 542 if (ret) 543 543 goto out_unlock; ··· 559 559 goto out_unlock; 560 560 } 561 561 cdev->private->irb.scsw.actl |= SCSW_ACTL_START_PEND; 562 - spin_unlock_irqrestore(&sch->lock, flags); 562 + spin_unlock_irqrestore(sch->lock, flags); 563 563 wait_event(cdev->private->wait_q, cdev->private->irb.scsw.actl == 0); 564 - spin_lock_irqsave(&sch->lock, flags); 564 + spin_lock_irqsave(sch->lock, flags); 565 565 cio_disable_subchannel(sch); //FIXME: return code? 566 566 if ((cdev->private->irb.scsw.dstat != 567 567 (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) || ··· 572 572 out_unlock: 573 573 kfree(buf); 574 574 kfree(buf2); 575 - spin_unlock_irqrestore(&sch->lock, flags); 575 + spin_unlock_irqrestore(sch->lock, flags); 576 576 return ret; 577 577 } 578 578
+129 -105
drivers/s390/cio/qdio.c
··· 46 46 #include <asm/timex.h> 47 47 48 48 #include <asm/debug.h> 49 + #include <asm/s390_rdev.h> 49 50 #include <asm/qdio.h> 50 51 51 52 #include "cio.h" ··· 66 65 /******************** HERE WE GO ***********************************/ 67 66 68 67 static const char version[] = "QDIO base support version 2"; 68 + extern struct bus_type ccw_bus_type; 69 69 70 - #ifdef QDIO_PERFORMANCE_STATS 70 + static int qdio_performance_stats = 0; 71 71 static int proc_perf_file_registration; 72 72 static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; 73 73 static struct qdio_perf_stats perf_stats; 74 - #endif /* QDIO_PERFORMANCE_STATS */ 75 74 76 75 static int hydra_thinints; 77 76 static int is_passthrough = 0; ··· 276 275 QDIO_DBF_TEXT4(0,trace,"sigasync"); 277 276 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 278 277 279 - #ifdef QDIO_PERFORMANCE_STATS 280 - perf_stats.siga_syncs++; 281 - #endif /* QDIO_PERFORMANCE_STATS */ 278 + if (qdio_performance_stats) 279 + perf_stats.siga_syncs++; 282 280 283 281 cc = do_siga_sync(q->schid, gpr2, gpr3); 284 282 if (cc) ··· 322 322 __u32 busy_bit; 323 323 __u64 start_time=0; 324 324 325 - #ifdef QDIO_PERFORMANCE_STATS 326 - perf_stats.siga_outs++; 327 - #endif /* QDIO_PERFORMANCE_STATS */ 325 + if (qdio_performance_stats) 326 + perf_stats.siga_outs++; 328 327 329 328 QDIO_DBF_TEXT4(0,trace,"sigaout"); 330 329 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); ··· 357 358 QDIO_DBF_TEXT4(0,trace,"sigain"); 358 359 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 359 360 360 - #ifdef QDIO_PERFORMANCE_STATS 361 - perf_stats.siga_ins++; 362 - #endif /* QDIO_PERFORMANCE_STATS */ 361 + if (qdio_performance_stats) 362 + perf_stats.siga_ins++; 363 363 364 364 cc = do_siga_input(q->schid, q->mask); 365 365 ··· 952 954 953 955 if (unlikely(qdio_reserve_q(q))) { 954 956 qdio_release_q(q); 955 - #ifdef QDIO_PERFORMANCE_STATS 956 - o_p_c++; 957 - #endif /* QDIO_PERFORMANCE_STATS */ 957 + if (qdio_performance_stats) 958 + o_p_c++; 958 959 /* as we're sissies, we'll check next time */ 959 960 if (likely(!atomic_read(&q->is_in_shutdown))) { 960 961 qdio_mark_q(q); ··· 961 964 } 962 965 return; 963 966 } 964 - #ifdef QDIO_PERFORMANCE_STATS 965 - o_p_nc++; 966 - perf_stats.tl_runs++; 967 - #endif /* QDIO_PERFORMANCE_STATS */ 967 + if (qdio_performance_stats) { 968 + o_p_nc++; 969 + perf_stats.tl_runs++; 970 + } 968 971 969 972 /* see comment in qdio_kick_outbound_q */ 970 973 siga_attempts=atomic_read(&q->busy_siga_counter); ··· 1139 1142 { 1140 1143 int i; 1141 1144 1142 - #ifdef QDIO_PERFORMANCE_STATS 1143 1145 static int old_pcis=0; 1144 1146 static int old_thinints=0; 1145 1147 1146 - if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints)) 1147 - perf_stats.start_time_inbound=NOW; 1148 - else 1149 - old_pcis=perf_stats.pcis; 1150 - #endif /* QDIO_PERFORMANCE_STATS */ 1148 + if (qdio_performance_stats) { 1149 + if ((old_pcis==perf_stats.pcis)&& 1150 + (old_thinints==perf_stats.thinints)) 1151 + perf_stats.start_time_inbound=NOW; 1152 + else 1153 + old_pcis=perf_stats.pcis; 1154 + } 1151 1155 1152 1156 i=qdio_get_inbound_buffer_frontier(q); 1153 1157 if ( (i!=GET_SAVED_FRONTIER(q)) || ··· 1338 1340 q->siga_error=0; 1339 1341 q->error_status_flags=0; 1340 1342 1341 - #ifdef QDIO_PERFORMANCE_STATS 1342 - perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; 1343 - perf_stats.inbound_cnt++; 1344 - #endif /* QDIO_PERFORMANCE_STATS */ 1343 + if (qdio_performance_stats) { 1344 + perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; 1345 + perf_stats.inbound_cnt++; 1346 + } 1345 1347 } 1346 1348 1347 1349 static inline void ··· 1361 1363 */ 1362 1364 if (unlikely(qdio_reserve_q(q))) { 1363 1365 qdio_release_q(q); 1364 - #ifdef QDIO_PERFORMANCE_STATS 1365 - ii_p_c++; 1366 - #endif /* QDIO_PERFORMANCE_STATS */ 1366 + if (qdio_performance_stats) 1367 + ii_p_c++; 1367 1368 /* 1368 1369 * as we might just be about to stop polling, we make 1369 1370 * sure that we check again at least once more ··· 1370 1373 tiqdio_sched_tl(); 1371 1374 return; 1372 1375 } 1373 - #ifdef QDIO_PERFORMANCE_STATS 1374 - ii_p_nc++; 1375 - #endif /* QDIO_PERFORMANCE_STATS */ 1376 + if (qdio_performance_stats) 1377 + ii_p_nc++; 1376 1378 if (unlikely(atomic_read(&q->is_in_shutdown))) { 1377 1379 qdio_unmark_q(q); 1378 1380 goto out; ··· 1412 1416 irq_ptr = (struct qdio_irq*)q->irq_ptr; 1413 1417 for (i=0;i<irq_ptr->no_output_qs;i++) { 1414 1418 oq = irq_ptr->output_qs[i]; 1415 - #ifdef QDIO_PERFORMANCE_STATS 1416 - perf_stats.tl_runs--; 1417 - #endif /* QDIO_PERFORMANCE_STATS */ 1418 - if (!qdio_is_outbound_q_done(oq)) 1419 + if (!qdio_is_outbound_q_done(oq)) { 1420 + if (qdio_performance_stats) 1421 + perf_stats.tl_runs--; 1419 1422 __qdio_outbound_processing(oq); 1423 + } 1420 1424 } 1421 1425 } 1422 1426 ··· 1453 1457 1454 1458 if (unlikely(qdio_reserve_q(q))) { 1455 1459 qdio_release_q(q); 1456 - #ifdef QDIO_PERFORMANCE_STATS 1457 - i_p_c++; 1458 - #endif /* QDIO_PERFORMANCE_STATS */ 1460 + if (qdio_performance_stats) 1461 + i_p_c++; 1459 1462 /* as we're sissies, we'll check next time */ 1460 1463 if (likely(!atomic_read(&q->is_in_shutdown))) { 1461 1464 qdio_mark_q(q); ··· 1462 1467 } 1463 1468 return; 1464 1469 } 1465 - #ifdef QDIO_PERFORMANCE_STATS 1466 - i_p_nc++; 1467 - perf_stats.tl_runs++; 1468 - #endif /* QDIO_PERFORMANCE_STATS */ 1470 + if (qdio_performance_stats) { 1471 + i_p_nc++; 1472 + perf_stats.tl_runs++; 1473 + } 1469 1474 1470 1475 again: 1471 1476 if (qdio_has_inbound_q_moved(q)) { ··· 1511 1516 1512 1517 if (unlikely(qdio_reserve_q(q))) { 1513 1518 qdio_release_q(q); 1514 - #ifdef QDIO_PERFORMANCE_STATS 1515 - ii_p_c++; 1516 - #endif /* QDIO_PERFORMANCE_STATS */ 1519 + if (qdio_performance_stats) 1520 + ii_p_c++; 1517 1521 /* 1518 1522 * as we might just be about to stop polling, we make 1519 1523 * sure that we check again at least once more ··· 1603 1609 { 1604 1610 QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); 1605 1611 1606 - #ifdef QDIO_PERFORMANCE_STATS 1607 - perf_stats.tl_runs++; 1608 - #endif /* QDIO_PERFORMANCE_STATS */ 1612 + if (qdio_performance_stats) 1613 + perf_stats.tl_runs++; 1609 1614 1610 1615 tiqdio_inbound_checks(); 1611 1616 } ··· 1911 1918 { 1912 1919 QDIO_DBF_TEXT4(0,trace,"thin_int"); 1913 1920 1914 - #ifdef QDIO_PERFORMANCE_STATS 1915 - perf_stats.thinints++; 1916 - perf_stats.start_time_inbound=NOW; 1917 - #endif /* QDIO_PERFORMANCE_STATS */ 1921 + if (qdio_performance_stats) { 1922 + perf_stats.thinints++; 1923 + perf_stats.start_time_inbound=NOW; 1924 + } 1918 1925 1919 1926 /* SVS only when needed: 1920 1927 * issue SVS to benefit from iqdio interrupt avoidance ··· 1969 1976 int i; 1970 1977 struct qdio_q *q; 1971 1978 1972 - #ifdef QDIO_PERFORMANCE_STATS 1973 - perf_stats.pcis++; 1974 - perf_stats.start_time_inbound=NOW; 1975 - #endif /* QDIO_PERFORMANCE_STATS */ 1979 + if (qdio_performance_stats) { 1980 + perf_stats.pcis++; 1981 + perf_stats.start_time_inbound=NOW; 1982 + } 1976 1983 for (i=0;i<irq_ptr->no_input_qs;i++) { 1977 1984 q=irq_ptr->input_qs[i]; 1978 1985 if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) 1979 1986 qdio_mark_q(q); 1980 1987 else { 1981 - #ifdef QDIO_PERFORMANCE_STATS 1982 - perf_stats.tl_runs--; 1983 - #endif /* QDIO_PERFORMANCE_STATS */ 1988 + if (qdio_performance_stats) 1989 + perf_stats.tl_runs--; 1984 1990 __qdio_inbound_processing(q); 1985 1991 } 1986 1992 } ··· 1987 1995 return; 1988 1996 for (i=0;i<irq_ptr->no_output_qs;i++) { 1989 1997 q=irq_ptr->output_qs[i]; 1990 - #ifdef QDIO_PERFORMANCE_STATS 1991 - perf_stats.tl_runs--; 1992 - #endif /* QDIO_PERFORMANCE_STATS */ 1993 1998 if (qdio_is_outbound_q_done(q)) 1994 1999 continue; 2000 + if (qdio_performance_stats) 2001 + perf_stats.tl_runs--; 1995 2002 if (!irq_ptr->sync_done_on_outb_pcis) 1996 2003 SYNC_MEMORY; 1997 2004 __qdio_outbound_processing(q); ··· 2036 2045 } 2037 2046 2038 2047 static void 2039 - qdio_call_shutdown(void *data) 2048 + qdio_call_shutdown(struct work_struct *work) 2040 2049 { 2050 + struct ccw_device_private *priv; 2041 2051 struct ccw_device *cdev; 2042 2052 2043 - cdev = (struct ccw_device *)data; 2053 + priv = container_of(work, struct ccw_device_private, kick_work); 2054 + cdev = priv->cdev; 2044 2055 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); 2045 2056 put_device(&cdev->dev); 2046 2057 } ··· 2084 2091 if (get_device(&cdev->dev)) { 2085 2092 /* Can't call shutdown from interrupt context. */ 2086 2093 PREPARE_WORK(&cdev->private->kick_work, 2087 - qdio_call_shutdown, (void *)cdev); 2094 + qdio_call_shutdown); 2088 2095 queue_work(ccw_device_work, &cdev->private->kick_work); 2089 2096 } 2090 2097 break; ··· 3451 3458 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; 3452 3459 3453 3460 /* This is the outbound handling of queues */ 3454 - #ifdef QDIO_PERFORMANCE_STATS 3455 - perf_stats.start_time_outbound=NOW; 3456 - #endif /* QDIO_PERFORMANCE_STATS */ 3461 + if (qdio_performance_stats) 3462 + perf_stats.start_time_outbound=NOW; 3457 3463 3458 3464 qdio_do_qdio_fill_output(q,qidx,count,buffers); 3459 3465 3460 3466 used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; 3461 3467 3462 3468 if (callflags&QDIO_FLAG_DONT_SIGA) { 3463 - #ifdef QDIO_PERFORMANCE_STATS 3464 - perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; 3465 - perf_stats.outbound_cnt++; 3466 - #endif /* QDIO_PERFORMANCE_STATS */ 3469 + if (qdio_performance_stats) { 3470 + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; 3471 + perf_stats.outbound_cnt++; 3472 + } 3467 3473 return; 3468 3474 } 3469 3475 if (q->is_iqdio_q) { ··· 3492 3500 qdio_kick_outbound_q(q); 3493 3501 } else { 3494 3502 QDIO_DBF_TEXT3(0,trace, "fast-req"); 3495 - #ifdef QDIO_PERFORMANCE_STATS 3496 - perf_stats.fast_reqs++; 3497 - #endif /* QDIO_PERFORMANCE_STATS */ 3503 + if (qdio_performance_stats) 3504 + perf_stats.fast_reqs++; 3498 3505 } 3499 3506 } 3500 3507 /* ··· 3504 3513 __qdio_outbound_processing(q); 3505 3514 } 3506 3515 3507 - #ifdef QDIO_PERFORMANCE_STATS 3508 - perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; 3509 - perf_stats.outbound_cnt++; 3510 - #endif /* QDIO_PERFORMANCE_STATS */ 3516 + if (qdio_performance_stats) { 3517 + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; 3518 + perf_stats.outbound_cnt++; 3519 + } 3511 3520 } 3512 3521 3513 3522 /* count must be 1 in iqdio */ ··· 3565 3574 return 0; 3566 3575 } 3567 3576 3568 - #ifdef QDIO_PERFORMANCE_STATS 3569 3577 static int 3570 3578 qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, 3571 3579 int buffer_length, int *eof, void *data) ··· 3580 3590 _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); 3581 3591 _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); 3582 3592 _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); 3583 - _OUTP_IT("Number of tasklet runs (total) : %u\n", 3593 + _OUTP_IT("Number of tasklet runs (total) : %lu\n", 3584 3594 perf_stats.tl_runs); 3585 3595 _OUTP_IT("\n"); 3586 - _OUTP_IT("Number of SIGA sync's issued : %u\n", 3596 + _OUTP_IT("Number of SIGA sync's issued : %lu\n", 3587 3597 perf_stats.siga_syncs); 3588 - _OUTP_IT("Number of SIGA in's issued : %u\n", 3598 + _OUTP_IT("Number of SIGA in's issued : %lu\n", 3589 3599 perf_stats.siga_ins); 3590 - _OUTP_IT("Number of SIGA out's issued : %u\n", 3600 + _OUTP_IT("Number of SIGA out's issued : %lu\n", 3591 3601 perf_stats.siga_outs); 3592 - _OUTP_IT("Number of PCIs caught : %u\n", 3602 + _OUTP_IT("Number of PCIs caught : %lu\n", 3593 3603 perf_stats.pcis); 3594 - _OUTP_IT("Number of adapter interrupts caught : %u\n", 3604 + _OUTP_IT("Number of adapter interrupts caught : %lu\n", 3595 3605 perf_stats.thinints); 3596 - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %u\n", 3606 + _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n", 3597 3607 perf_stats.fast_reqs); 3598 3608 _OUTP_IT("\n"); 3599 - _OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n", 3609 + _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n", 3600 3610 perf_stats.inbound_time); 3601 - _OUTP_IT("Number of inbound transfers : %u\n", 3611 + _OUTP_IT("Number of inbound transfers : %lu\n", 3602 3612 perf_stats.inbound_cnt); 3603 - _OUTP_IT("Total time of all outbound do_QDIOs (us) : %u\n", 3613 + _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n", 3604 3614 perf_stats.outbound_time); 3605 - _OUTP_IT("Number of do_QDIOs outbound : %u\n", 3615 + _OUTP_IT("Number of do_QDIOs outbound : %lu\n", 3606 3616 perf_stats.outbound_cnt); 3607 3617 _OUTP_IT("\n"); 3608 3618 ··· 3610 3620 } 3611 3621 3612 3622 static struct proc_dir_entry *qdio_perf_proc_file; 3613 - #endif /* QDIO_PERFORMANCE_STATS */ 3614 3623 3615 3624 static void 3616 3625 qdio_add_procfs_entry(void) 3617 3626 { 3618 - #ifdef QDIO_PERFORMANCE_STATS 3619 3627 proc_perf_file_registration=0; 3620 3628 qdio_perf_proc_file=create_proc_entry(QDIO_PERF, 3621 3629 S_IFREG|0444,&proc_root); ··· 3625 3637 QDIO_PRINT_WARN("was not able to register perf. " \ 3626 3638 "proc-file (%i).\n", 3627 3639 proc_perf_file_registration); 3628 - #endif /* QDIO_PERFORMANCE_STATS */ 3629 3640 } 3630 3641 3631 3642 static void 3632 3643 qdio_remove_procfs_entry(void) 3633 3644 { 3634 - #ifdef QDIO_PERFORMANCE_STATS 3635 3645 perf_stats.tl_runs=0; 3636 3646 3637 3647 if (!proc_perf_file_registration) /* means if it went ok earlier */ 3638 3648 remove_proc_entry(QDIO_PERF,&proc_root); 3639 - #endif /* QDIO_PERFORMANCE_STATS */ 3640 3649 } 3650 + 3651 + /** 3652 + * attributes in sysfs 3653 + *****************************************************************************/ 3654 + 3655 + static ssize_t 3656 + qdio_performance_stats_show(struct bus_type *bus, char *buf) 3657 + { 3658 + return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); 3659 + } 3660 + 3661 + static ssize_t 3662 + qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count) 3663 + { 3664 + char *tmp; 3665 + int i; 3666 + 3667 + i = simple_strtoul(buf, &tmp, 16); 3668 + if ((i == 0) || (i == 1)) { 3669 + if (i == qdio_performance_stats) 3670 + return count; 3671 + qdio_performance_stats = i; 3672 + if (i==0) { 3673 + /* reset perf. stat. info */ 3674 + i_p_nc = 0; 3675 + i_p_c = 0; 3676 + ii_p_nc = 0; 3677 + ii_p_c = 0; 3678 + o_p_nc = 0; 3679 + o_p_c = 0; 3680 + memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); 3681 + } 3682 + } else { 3683 + QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); 3684 + return -EINVAL; 3685 + } 3686 + return count; 3687 + } 3688 + 3689 + static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show, 3690 + qdio_performance_stats_store); 3641 3691 3642 3692 static void 3643 3693 tiqdio_register_thinints(void) ··· 3720 3694 { 3721 3695 kfree(indicators); 3722 3696 } 3697 + 3723 3698 3724 3699 static void 3725 3700 qdio_unregister_dbf_views(void) ··· 3823 3796 init_QDIO(void) 3824 3797 { 3825 3798 int res; 3826 - #ifdef QDIO_PERFORMANCE_STATS 3827 3799 void *ptr; 3828 - #endif /* QDIO_PERFORMANCE_STATS */ 3829 3800 3830 3801 printk("qdio: loading %s\n",version); 3831 3802 ··· 3836 3811 return res; 3837 3812 3838 3813 QDIO_DBF_TEXT0(0,setup,"initQDIO"); 3814 + res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); 3839 3815 3840 - #ifdef QDIO_PERFORMANCE_STATS 3841 - memset((void*)&perf_stats,0,sizeof(perf_stats)); 3816 + memset((void*)&perf_stats,0,sizeof(perf_stats)); 3842 3817 QDIO_DBF_TEXT0(0,setup,"perfstat"); 3843 3818 ptr=&perf_stats; 3844 3819 QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); 3845 - #endif /* QDIO_PERFORMANCE_STATS */ 3846 3820 3847 3821 qdio_add_procfs_entry(); 3848 3822 ··· 3865 3841 qdio_release_qdio_memory(); 3866 3842 qdio_unregister_dbf_views(); 3867 3843 mempool_destroy(qdio_mempool_scssc); 3868 - 3844 + bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); 3869 3845 printk("qdio: %s: module removed\n",version); 3870 3846 } 3871 3847
+11 -17
drivers/s390/cio/qdio.h
··· 12 12 #endif /* CONFIG_QDIO_DEBUG */ 13 13 #define QDIO_USE_PROCESSING_STATE 14 14 15 - #ifdef CONFIG_QDIO_PERF_STATS 16 - #define QDIO_PERFORMANCE_STATS 17 - #endif /* CONFIG_QDIO_PERF_STATS */ 18 - 19 15 #define QDIO_MINIMAL_BH_RELIEF_TIME 16 20 16 #define QDIO_TIMER_POLL_VALUE 1 21 17 #define IQDIO_TIMER_POLL_VALUE 1 ··· 405 409 #define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08 406 410 #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 407 411 408 - #ifdef QDIO_PERFORMANCE_STATS 409 412 struct qdio_perf_stats { 410 - unsigned int tl_runs; 413 + unsigned long tl_runs; 411 414 412 - unsigned int siga_outs; 413 - unsigned int siga_ins; 414 - unsigned int siga_syncs; 415 - unsigned int pcis; 416 - unsigned int thinints; 417 - unsigned int fast_reqs; 415 + unsigned long siga_outs; 416 + unsigned long siga_ins; 417 + unsigned long siga_syncs; 418 + unsigned long pcis; 419 + unsigned long thinints; 420 + unsigned long fast_reqs; 418 421 419 422 __u64 start_time_outbound; 420 - unsigned int outbound_cnt; 421 - unsigned int outbound_time; 423 + unsigned long outbound_cnt; 424 + unsigned long outbound_time; 422 425 __u64 start_time_inbound; 423 - unsigned int inbound_cnt; 424 - unsigned int inbound_time; 426 + unsigned long inbound_cnt; 427 + unsigned long inbound_time; 425 428 }; 426 - #endif /* QDIO_PERFORMANCE_STATS */ 427 429 428 430 /* unlikely as the later the better */ 429 431 #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q)
+17
drivers/s390/crypto/ap_bus.c
··· 33 33 #include <linux/kthread.h> 34 34 #include <linux/mutex.h> 35 35 #include <asm/s390_rdev.h> 36 + #include <asm/reset.h> 36 37 37 38 #include "ap_bus.h" 38 39 ··· 1129 1128 mutex_unlock(&ap_poll_thread_mutex); 1130 1129 } 1131 1130 1131 + static void ap_reset(void) 1132 + { 1133 + int i, j; 1134 + 1135 + for (i = 0; i < AP_DOMAINS; i++) 1136 + for (j = 0; j < AP_DEVICES; j++) 1137 + ap_reset_queue(AP_MKQID(j, i)); 1138 + } 1139 + 1140 + static struct reset_call ap_reset_call = { 1141 + .fn = ap_reset, 1142 + }; 1143 + 1132 1144 /** 1133 1145 * The module initialization code. 1134 1146 */ ··· 1158 1144 printk(KERN_WARNING "AP instructions not installed.\n"); 1159 1145 return -ENODEV; 1160 1146 } 1147 + register_reset_call(&ap_reset_call); 1161 1148 1162 1149 /* Create /sys/bus/ap. */ 1163 1150 rc = bus_register(&ap_bus_type); ··· 1212 1197 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); 1213 1198 bus_unregister(&ap_bus_type); 1214 1199 out: 1200 + unregister_reset_call(&ap_reset_call); 1215 1201 return rc; 1216 1202 } 1217 1203 ··· 1243 1227 for (i = 0; ap_bus_attrs[i]; i++) 1244 1228 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); 1245 1229 bus_unregister(&ap_bus_type); 1230 + unregister_reset_call(&ap_reset_call); 1246 1231 } 1247 1232 1248 1233 #ifndef CONFIG_ZCRYPT_MONOLITHIC
+2
include/asm-s390/dasd.h
··· 69 69 * 0x01: readonly (ro) 70 70 * 0x02: use diag discipline (diag) 71 71 * 0x04: set the device initially online (internal use only) 72 + * 0x08: enable ERP related logging 72 73 */ 73 74 #define DASD_FEATURE_DEFAULT 0x00 74 75 #define DASD_FEATURE_READONLY 0x01 75 76 #define DASD_FEATURE_USEDIAG 0x02 76 77 #define DASD_FEATURE_INITIAL_ONLINE 0x04 78 + #define DASD_FEATURE_ERPLOG 0x08 77 79 78 80 #define DASD_PARTN_BITS 2 79 81
+20 -2
include/asm-s390/page.h
··· 127 127 return skey; 128 128 } 129 129 130 + extern unsigned long max_pfn; 131 + 132 + static inline int pfn_valid(unsigned long pfn) 133 + { 134 + unsigned long dummy; 135 + int ccode; 136 + 137 + if (pfn >= max_pfn) 138 + return 0; 139 + 140 + asm volatile( 141 + " lra %0,0(%2)\n" 142 + " ipm %1\n" 143 + " srl %1,28\n" 144 + : "=d" (dummy), "=d" (ccode) 145 + : "a" (pfn << PAGE_SHIFT) 146 + : "cc"); 147 + return !ccode; 148 + } 149 + 130 150 #endif /* !__ASSEMBLY__ */ 131 151 132 152 /* to align the pointer to the (next) page boundary */ ··· 158 138 #define __va(x) (void *)(unsigned long)(x) 159 139 #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 160 140 #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 161 - 162 - #define pfn_valid(pfn) ((pfn) < max_mapnr) 163 141 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 164 142 165 143 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+3
include/asm-s390/pgalloc.h
··· 25 25 * Page allocation orders. 26 26 */ 27 27 #ifndef __s390x__ 28 + # define PTE_ALLOC_ORDER 0 29 + # define PMD_ALLOC_ORDER 0 28 30 # define PGD_ALLOC_ORDER 1 29 31 #else /* __s390x__ */ 32 + # define PTE_ALLOC_ORDER 0 30 33 # define PMD_ALLOC_ORDER 2 31 34 # define PGD_ALLOC_ORDER 2 32 35 #endif /* __s390x__ */
+12 -4
include/asm-s390/pgtable.h
··· 107 107 * The vmalloc() routines leaves a hole of 4kB between each vmalloced 108 108 * area for the same reason. ;) 109 109 */ 110 + extern unsigned long vmalloc_end; 110 111 #define VMALLOC_OFFSET (8*1024*1024) 111 112 #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \ 112 113 & ~(VMALLOC_OFFSET-1)) 114 + #define VMALLOC_END vmalloc_end 113 115 114 116 /* 115 117 * We need some free virtual space to be able to do vmalloc. 116 118 * VMALLOC_MIN_SIZE defines the minimum size of the vmalloc 117 119 * area. On a machine with 2GB memory we make sure that we 118 120 * have at least 128MB free space for vmalloc. On a machine 119 - * with 4TB we make sure we have at least 1GB. 121 + * with 4TB we make sure we have at least 128GB. 120 122 */ 121 123 #ifndef __s390x__ 122 124 #define VMALLOC_MIN_SIZE 0x8000000UL 123 - #define VMALLOC_END 0x80000000UL 125 + #define VMALLOC_END_INIT 0x80000000UL 124 126 #else /* __s390x__ */ 125 - #define VMALLOC_MIN_SIZE 0x40000000UL 126 - #define VMALLOC_END 0x40000000000UL 127 + #define VMALLOC_MIN_SIZE 0x2000000000UL 128 + #define VMALLOC_END_INIT 0x40000000000UL 127 129 #endif /* __s390x__ */ 128 130 129 131 /* ··· 817 815 818 816 #define kern_addr_valid(addr) (1) 819 817 818 + extern int add_shared_memory(unsigned long start, unsigned long size); 819 + extern int remove_shared_memory(unsigned long start, unsigned long size); 820 + 820 821 /* 821 822 * No page table caches to initialise 822 823 */ 823 824 #define pgtable_cache_init() do { } while (0) 825 + 826 + #define __HAVE_ARCH_MEMMAP_INIT 827 + extern void memmap_init(unsigned long, int, unsigned long, unsigned long); 824 828 825 829 #define __HAVE_ARCH_PTEP_ESTABLISH 826 830 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS