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: (27 commits)
  [S390] Fix checkstack for s390
  [S390] fix initialization of stp
  [S390] 3215: Remove tasklet.
  [S390] console flush on panic / reboot
  [S390] introduce dirty bit for kvm live migration
  [S390] Add ioctl support for EMC Symmetrix Subsystem Control I/O
  [S390] xpram: per device block request queues.
  [S390] dasd: fix message flood for unsolicited interrupts
  [S390] Move private simple udelay function to arch/s390/lib/delay.c.
  [S390] dcssblk: add >2G DCSSs support and stacked contiguous DCSSs support.
  [S390] ptrace changes
  [S390] s390: use sys_pause for 31bit pause entry point
  [S390] qdio enhanced SIGA (iqdio) support.
  [S390] cio: fix cio_tpi.
  [S390] cio: Correct use of ! and &
  [S390] cio: inline assembly cleanup
  [S390] bus_id -> dev_set_name() for css and ccw busses
  [S390] bus_id ->dev_name() conversions in qdio
  [S390] Use s390_root_dev_* in kvm_virtio.
  [S390] more bus_id -> dev_name conversions
  ...
This commit is contained in:
Linus Torvalds 2008-10-11 08:50:01 -07:00
commit 37d9869ed9
74 changed files with 1559 additions and 629 deletions

View file

@ -70,13 +70,19 @@ Command line parameters
Note: While already known devices can be added to the list of devices to be Note: While already known devices can be added to the list of devices to be
ignored, there will be no effect on then. However, if such a device ignored, there will be no effect on then. However, if such a device
disappears and then reappears, it will then be ignored. disappears and then reappears, it will then be ignored. To make
known devices go away, you need the "purge" command (see below).
For example, For example,
"echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore" "echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore"
will add 0.0.a000-0.0.accc and 0.0.af00-0.0.afff to the list of ignored will add 0.0.a000-0.0.accc and 0.0.af00-0.0.afff to the list of ignored
devices. devices.
You can remove already known but now ignored devices via
"echo purge > /proc/cio_ignore"
All devices ignored but still registered and not online (= not in use)
will be deregistered and thus removed from the system.
The devices can be specified either by bus id (0.x.abcd) or, for 2.4 backward The devices can be specified either by bus id (0.x.abcd) or, for 2.4 backward
compatibility, by the device number in hexadecimal (0xabcd or abcd). Device compatibility, by the device number in hexadecimal (0xabcd or abcd). Device
numbers given as 0xabcd will be interpreted as 0.0.abcd. numbers given as 0xabcd will be interpreted as 0.0.abcd.
@ -98,8 +104,7 @@ debugfs entries
handling). handling).
- /sys/kernel/debug/s390dbf/cio_msg/sprintf - /sys/kernel/debug/s390dbf/cio_msg/sprintf
Various debug messages from the common I/O-layer, including messages Various debug messages from the common I/O-layer.
printed when cio_msg=yes.
- /sys/kernel/debug/s390dbf/cio_trace/hex_ascii - /sys/kernel/debug/s390dbf/cio_trace/hex_ascii
Logs the calling of functions in the common I/O-layer and, if applicable, Logs the calling of functions in the common I/O-layer and, if applicable,

View file

@ -74,6 +74,7 @@ config S390
select HAVE_KPROBES select HAVE_KPROBES
select HAVE_KRETPROBES select HAVE_KRETPROBES
select HAVE_KVM if 64BIT select HAVE_KVM if 64BIT
select HAVE_ARCH_TRACEHOOK
source "init/Kconfig" source "init/Kconfig"

View file

@ -3,6 +3,8 @@
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
* EMC Symmetrix ioctl Copyright EMC Corporation, 2008
* Author.........: Nigel Hislop <hislop_nigel@emc.com>
* *
* This file is the interface of the DASD device driver, which is exported to user space * This file is the interface of the DASD device driver, which is exported to user space
* any future changes wrt the API will result in a change of the APIVERSION reported * any future changes wrt the API will result in a change of the APIVERSION reported
@ -202,6 +204,16 @@ typedef struct attrib_data_t {
#define DASD_SEQ_PRESTAGE 0x4 #define DASD_SEQ_PRESTAGE 0x4
#define DASD_REC_ACCESS 0x5 #define DASD_REC_ACCESS 0x5
/*
* Perform EMC Symmetrix I/O
*/
typedef struct dasd_symmio_parms {
unsigned char reserved[8]; /* compat with older releases */
unsigned long long psf_data; /* char * cast to u64 */
unsigned long long rssd_result; /* char * cast to u64 */
int psf_data_len;
int rssd_result_len;
} __attribute__ ((packed)) dasd_symmio_parms_t;
/******************************************************************************** /********************************************************************************
* SECTION: Definition of IOCTLs * SECTION: Definition of IOCTLs
@ -247,6 +259,7 @@ typedef struct attrib_data_t {
/* Set Attributes (cache operations) */ /* Set Attributes (cache operations) */
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
#endif /* DASD_H */ #endif /* DASD_H */

View file

@ -15,6 +15,7 @@
#define _S390_DELAY_H #define _S390_DELAY_H
extern void __udelay(unsigned long usecs); extern void __udelay(unsigned long usecs);
extern void udelay_simple(unsigned long usecs);
extern void __delay(unsigned long loops); extern void __delay(unsigned long loops);
#define udelay(n) __udelay(n) #define udelay(n) __udelay(n)

View file

@ -281,6 +281,9 @@ extern char empty_zero_page[PAGE_SIZE];
#define RCP_GR_BIT 50 #define RCP_GR_BIT 50
#define RCP_GC_BIT 49 #define RCP_GC_BIT 49
/* User dirty bit for KVM's migration feature */
#define KVM_UD_BIT 47
#ifndef __s390x__ #ifndef __s390x__
/* Bits in the segment table address-space-control-element */ /* Bits in the segment table address-space-control-element */
@ -575,12 +578,16 @@ static inline void ptep_rcp_copy(pte_t *ptep)
unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
skey = page_get_storage_key(page_to_phys(page)); skey = page_get_storage_key(page_to_phys(page));
if (skey & _PAGE_CHANGED) if (skey & _PAGE_CHANGED) {
set_bit_simple(RCP_GC_BIT, pgste); set_bit_simple(RCP_GC_BIT, pgste);
set_bit_simple(KVM_UD_BIT, pgste);
}
if (skey & _PAGE_REFERENCED) if (skey & _PAGE_REFERENCED)
set_bit_simple(RCP_GR_BIT, pgste); set_bit_simple(RCP_GR_BIT, pgste);
if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) {
SetPageDirty(page); SetPageDirty(page);
set_bit_simple(KVM_UD_BIT, pgste);
}
if (test_and_clear_bit_simple(RCP_HR_BIT, pgste)) if (test_and_clear_bit_simple(RCP_HR_BIT, pgste))
SetPageReferenced(page); SetPageReferenced(page);
#endif #endif
@ -744,6 +751,40 @@ static inline pte_t pte_mkspecial(pte_t pte)
return pte; return pte;
} }
#ifdef CONFIG_PGSTE
/*
* Get (and clear) the user dirty bit for a PTE.
*/
static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm,
pte_t *ptep)
{
int dirty;
unsigned long *pgste;
struct page *page;
unsigned int skey;
if (!mm->context.pgstes)
return -EINVAL;
rcp_lock(ptep);
pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
page = virt_to_page(pte_val(*ptep));
skey = page_get_storage_key(page_to_phys(page));
if (skey & _PAGE_CHANGED) {
set_bit_simple(RCP_GC_BIT, pgste);
set_bit_simple(KVM_UD_BIT, pgste);
}
if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) {
SetPageDirty(page);
set_bit_simple(KVM_UD_BIT, pgste);
}
dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste);
if (skey & _PAGE_CHANGED)
page_clear_dirty(page);
rcp_unlock(ptep);
return dirty;
}
#endif
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep) unsigned long addr, pte_t *ptep)

View file

@ -490,6 +490,7 @@ extern void user_disable_single_step(struct task_struct *);
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define user_stack_pointer(regs)((regs)->gprs[15])
#define regs_return_value(regs)((regs)->gprs[2]) #define regs_return_value(regs)((regs)->gprs[2])
#define profile_pc(regs) instruction_pointer(regs) #define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs * regs); extern void show_regs(struct pt_regs * regs);

View file

@ -299,7 +299,13 @@ struct qdio_ssqd_desc {
u8 mbccnt; u8 mbccnt;
u16 qdioac2; u16 qdioac2;
u64 sch_token; u64 sch_token;
u64:64; u8 mro;
u8 mri;
u8:8;
u8 sbalic;
u16:16;
u8:8;
u8 mmwc;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* params are: ccw_device, qdio_error, queue_number, /* params are: ccw_device, qdio_error, queue_number,

View file

@ -0,0 +1,80 @@
/*
* Access to user system call parameters and results
*
* Copyright IBM Corp. 2008
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (version 2 only)
* as published by the Free Software Foundation.
*/
#ifndef _ASM_SYSCALL_H
#define _ASM_SYSCALL_H 1
#include <asm/ptrace.h>
static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
{
if (regs->trap != __LC_SVC_OLD_PSW)
return -1;
return regs->gprs[2];
}
static inline void syscall_rollback(struct task_struct *task,
struct pt_regs *regs)
{
regs->gprs[2] = regs->orig_gpr2;
}
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,
struct pt_regs *regs)
{
return regs->gprs[2];
}
static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
regs->gprs[2] = error ? -error : val;
}
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned int i, unsigned int n,
unsigned long *args)
{
BUG_ON(i + n > 6);
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT)) {
if (i + n == 6)
args[--n] = (u32) regs->args[0];
while (n-- > 0)
args[n] = (u32) regs->gprs[2 + i + n];
}
#endif
if (i + n == 6)
args[--n] = regs->args[0];
memcpy(args, &regs->gprs[2 + i], n * sizeof(args[0]));
}
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned int i, unsigned int n,
const unsigned long *args)
{
BUG_ON(i + n > 6);
if (i + n == 6)
regs->args[0] = args[--n];
memcpy(&regs->gprs[2 + i], args, n * sizeof(args[0]));
}
#endif /* _ASM_SYSCALL_H */

View file

@ -86,6 +86,7 @@ static inline struct thread_info *current_thread_info(void)
* thread information flags bit numbers * thread information flags bit numbers
*/ */
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTART_SVC 4 /* restart svc with new svc number */ #define TIF_RESTART_SVC 4 /* restart svc with new svc number */
@ -100,6 +101,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)

View file

@ -608,14 +608,6 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct time
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
} }
/* These are here just in case some old sparc32 binary calls it. */
asmlinkage long sys32_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
schedule();
return -ERESTARTNOHAND;
}
asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
size_t count, u32 poshi, u32 poslo) size_t count, u32 poshi, u32 poslo)
{ {

View file

@ -206,7 +206,6 @@ long sys32_gettimeofday(struct compat_timeval __user *tv,
struct timezone __user *tz); struct timezone __user *tz);
long sys32_settimeofday(struct compat_timeval __user *tv, long sys32_settimeofday(struct compat_timeval __user *tv,
struct timezone __user *tz); struct timezone __user *tz);
long sys32_pause(void);
long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count,
u32 poshi, u32 poslo); u32 poshi, u32 poslo);
long sys32_pwrite64(unsigned int fd, const char __user *ubuf, long sys32_pwrite64(unsigned int fd, const char __user *ubuf,

View file

@ -128,8 +128,6 @@ sys32_alarm_wrapper:
llgfr %r2,%r2 # unsigned int llgfr %r2,%r2 # unsigned int
jg sys_alarm # branch to system call jg sys_alarm # branch to system call
#sys32_pause_wrapper # void
.globl compat_sys_utime_wrapper .globl compat_sys_utime_wrapper
compat_sys_utime_wrapper: compat_sys_utime_wrapper:
llgtr %r2,%r2 # char * llgtr %r2,%r2 # char *

View file

@ -49,9 +49,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING) _TIF_MCCK_PENDING)
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
@ -318,6 +318,8 @@ sysc_work:
bo BASED(sysc_reschedule) bo BASED(sysc_reschedule)
tm __TI_flags+3(%r9),_TIF_SIGPENDING tm __TI_flags+3(%r9),_TIF_SIGPENDING
bnz BASED(sysc_sigpending) bnz BASED(sysc_sigpending)
tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
bnz BASED(sysc_notify_resume)
tm __TI_flags+3(%r9),_TIF_RESTART_SVC tm __TI_flags+3(%r9),_TIF_RESTART_SVC
bo BASED(sysc_restart) bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
@ -355,6 +357,16 @@ sysc_sigpending:
bo BASED(sysc_singlestep) bo BASED(sysc_singlestep)
b BASED(sysc_work_loop) b BASED(sysc_work_loop)
#
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
#
sysc_notify_resume:
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_notify_resume)
la %r14,BASED(sysc_work_loop)
br %r1 # call do_notify_resume
# #
# _TIF_RESTART_SVC is set, set up registers and restart svc # _TIF_RESTART_SVC is set, set up registers and restart svc
# #
@ -378,20 +390,21 @@ sysc_singlestep:
br %r1 # branch to do_single_step br %r1 # branch to do_single_step
# #
# call trace before and after sys_call # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
# and after the system call
# #
sysc_tracesys: sysc_tracesys:
l %r1,BASED(.Ltrace) l %r1,BASED(.Ltrace_entry)
la %r2,SP_PTREGS(%r15) # load pt_regs la %r2,SP_PTREGS(%r15) # load pt_regs
la %r3,0 la %r3,0
srl %r7,2 srl %r7,2
st %r7,SP_R2(%r15) st %r7,SP_R2(%r15)
basr %r14,%r1 basr %r14,%r1
clc SP_R2(4,%r15),BASED(.Lnr_syscalls) cl %r2,BASED(.Lnr_syscalls)
bnl BASED(sysc_tracenogo) bnl BASED(sysc_tracenogo)
l %r8,BASED(.Lsysc_table) l %r8,BASED(.Lsysc_table)
l %r7,SP_R2(%r15) # strace might have changed the lr %r7,%r2
sll %r7,2 # system call sll %r7,2 # *4
l %r8,0(%r7,%r8) l %r8,0(%r7,%r8)
sysc_tracego: sysc_tracego:
lm %r3,%r6,SP_R3(%r15) lm %r3,%r6,SP_R3(%r15)
@ -401,9 +414,8 @@ sysc_tracego:
sysc_tracenogo: sysc_tracenogo:
tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
bz BASED(sysc_return) bz BASED(sysc_return)
l %r1,BASED(.Ltrace) l %r1,BASED(.Ltrace_exit)
la %r2,SP_PTREGS(%r15) # load pt_regs la %r2,SP_PTREGS(%r15) # load pt_regs
la %r3,1
la %r14,BASED(sysc_return) la %r14,BASED(sysc_return)
br %r1 br %r1
@ -666,6 +678,8 @@ io_work_loop:
bo BASED(io_reschedule) bo BASED(io_reschedule)
tm __TI_flags+3(%r9),_TIF_SIGPENDING tm __TI_flags+3(%r9),_TIF_SIGPENDING
bnz BASED(io_sigpending) bnz BASED(io_sigpending)
tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
bnz BASED(io_notify_resume)
b BASED(io_restore) b BASED(io_restore)
io_work_done: io_work_done:
@ -704,6 +718,19 @@ io_sigpending:
TRACE_IRQS_OFF TRACE_IRQS_OFF
b BASED(io_work_loop) b BASED(io_work_loop)
#
# _TIF_SIGPENDING is set, call do_signal
#
io_notify_resume:
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_notify_resume)
basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
b BASED(io_work_loop)
/* /*
* External interrupt handler routine * External interrupt handler routine
*/ */
@ -1070,6 +1097,8 @@ cleanup_io_leave_insn:
.Ldo_IRQ: .long do_IRQ .Ldo_IRQ: .long do_IRQ
.Ldo_extint: .long do_extint .Ldo_extint: .long do_extint
.Ldo_signal: .long do_signal .Ldo_signal: .long do_signal
.Ldo_notify_resume:
.long do_notify_resume
.Lhandle_per: .long do_single_step .Lhandle_per: .long do_single_step
.Ldo_execve: .long do_execve .Ldo_execve: .long do_execve
.Lexecve_tail: .long execve_tail .Lexecve_tail: .long execve_tail
@ -1079,7 +1108,8 @@ cleanup_io_leave_insn:
.Lpreempt_schedule_irq: .Lpreempt_schedule_irq:
.long preempt_schedule_irq .long preempt_schedule_irq
#endif #endif
.Ltrace: .long syscall_trace .Ltrace_entry: .long do_syscall_trace_enter
.Ltrace_exit: .long do_syscall_trace_exit
.Lschedtail: .long schedule_tail .Lschedtail: .long schedule_tail
.Lsysc_table: .long sys_call_table .Lsysc_table: .long sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS

View file

@ -52,9 +52,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
STACK_SIZE = 1 << STACK_SHIFT STACK_SIZE = 1 << STACK_SHIFT
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING) _TIF_MCCK_PENDING)
#define BASED(name) name-system_call(%r13) #define BASED(name) name-system_call(%r13)
@ -310,6 +310,8 @@ sysc_work:
jo sysc_reschedule jo sysc_reschedule
tm __TI_flags+7(%r9),_TIF_SIGPENDING tm __TI_flags+7(%r9),_TIF_SIGPENDING
jnz sysc_sigpending jnz sysc_sigpending
tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
jnz sysc_notify_resume
tm __TI_flags+7(%r9),_TIF_RESTART_SVC tm __TI_flags+7(%r9),_TIF_RESTART_SVC
jo sysc_restart jo sysc_restart
tm __TI_flags+7(%r9),_TIF_SINGLE_STEP tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
@ -344,6 +346,14 @@ sysc_sigpending:
jo sysc_singlestep jo sysc_singlestep
j sysc_work_loop j sysc_work_loop
#
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
#
sysc_notify_resume:
la %r2,SP_PTREGS(%r15) # load pt_regs
larl %r14,sysc_work_loop
jg do_notify_resume # call do_notify_resume
# #
# _TIF_RESTART_SVC is set, set up registers and restart svc # _TIF_RESTART_SVC is set, set up registers and restart svc
# #
@ -367,20 +377,19 @@ sysc_singlestep:
jg do_single_step # branch to do_sigtrap jg do_single_step # branch to do_sigtrap
# #
# call syscall_trace before and after system call # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
# special linkage: %r12 contains the return address for trace_svc # and after the system call
# #
sysc_tracesys: sysc_tracesys:
la %r2,SP_PTREGS(%r15) # load pt_regs la %r2,SP_PTREGS(%r15) # load pt_regs
la %r3,0 la %r3,0
srl %r7,2 srl %r7,2
stg %r7,SP_R2(%r15) stg %r7,SP_R2(%r15)
brasl %r14,syscall_trace brasl %r14,do_syscall_trace_enter
lghi %r0,NR_syscalls lghi %r0,NR_syscalls
clg %r0,SP_R2(%r15) clgr %r0,%r2
jnh sysc_tracenogo jnh sysc_tracenogo
lg %r7,SP_R2(%r15) # strace might have changed the slag %r7,%r2,2 # *4
sll %r7,2 # system call
lgf %r8,0(%r7,%r10) lgf %r8,0(%r7,%r10)
sysc_tracego: sysc_tracego:
lmg %r3,%r6,SP_R3(%r15) lmg %r3,%r6,SP_R3(%r15)
@ -391,9 +400,8 @@ sysc_tracenogo:
tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
jz sysc_return jz sysc_return
la %r2,SP_PTREGS(%r15) # load pt_regs la %r2,SP_PTREGS(%r15) # load pt_regs
la %r3,1
larl %r14,sysc_return # return point is sysc_return larl %r14,sysc_return # return point is sysc_return
jg syscall_trace jg do_syscall_trace_exit
# #
# a new process exits the kernel with ret_from_fork # a new process exits the kernel with ret_from_fork
@ -672,6 +680,8 @@ io_work_loop:
jo io_reschedule jo io_reschedule
tm __TI_flags+7(%r9),_TIF_SIGPENDING tm __TI_flags+7(%r9),_TIF_SIGPENDING
jnz io_sigpending jnz io_sigpending
tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
jnz io_notify_resume
j io_restore j io_restore
io_work_done: io_work_done:
@ -712,6 +722,18 @@ io_sigpending:
TRACE_IRQS_OFF TRACE_IRQS_OFF
j io_work_loop j io_work_loop
#
# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
#
io_notify_resume:
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
brasl %r14,do_notify_resume # call do_notify_resume
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
j io_work_loop
/* /*
* External interrupt handler routine * External interrupt handler routine
*/ */

View file

@ -35,6 +35,7 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/tracehook.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/page.h> #include <asm/page.h>
@ -639,40 +640,44 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
} }
#endif #endif
asmlinkage void asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
syscall_trace(struct pt_regs *regs, int entryexit)
{ {
if (unlikely(current->audit_context) && entryexit) long ret;
audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
if (!test_thread_flag(TIF_SYSCALL_TRACE))
goto out;
if (!(current->ptrace & PT_PTRACED))
goto out;
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/* /*
* If the debuffer has set an invalid system call number, * The sysc_tracesys code in entry.S stored the system
* we prepare to skip the system call restart handling. * call number to gprs[2].
*/ */
if (!entryexit && regs->gprs[2] >= NR_syscalls) ret = regs->gprs[2];
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
(tracehook_report_syscall_entry(regs) ||
regs->gprs[2] >= NR_syscalls)) {
/*
* Tracing decided this syscall should not happen or the
* debugger stored an invalid system call number. Skip
* the system call and the system call restart handling.
*/
regs->trap = -1; regs->trap = -1;
ret = -1;
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
if (current->exit_code) {
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
} }
out:
if (unlikely(current->audit_context) && !entryexit) if (unlikely(current->audit_context))
audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, audit_syscall_entry(test_thread_flag(TIF_31BIT) ?
regs->gprs[2], regs->orig_gpr2, regs->gprs[3], AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
regs->gprs[4], regs->gprs[5]); regs->gprs[2], regs->orig_gpr2,
regs->gprs[3], regs->gprs[4],
regs->gprs[5]);
return ret;
}
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
{
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
regs->gprs[2]);
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0);
} }
/* /*

View file

@ -24,6 +24,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/tracehook.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/lowcore.h> #include <asm/lowcore.h>
@ -507,6 +508,12 @@ void do_signal(struct pt_regs *regs)
*/ */
if (current->thread.per_info.single_step) if (current->thread.per_info.single_step)
set_thread_flag(TIF_SINGLE_STEP); set_thread_flag(TIF_SINGLE_STEP);
/*
* Let tracing know that we've done the handler setup.
*/
tracehook_signal_handler(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLE_STEP));
} }
return; return;
} }
@ -526,3 +533,9 @@ void do_signal(struct pt_regs *regs)
set_thread_flag(TIF_RESTART_SVC); set_thread_flag(TIF_RESTART_SVC);
} }
} }
void do_notify_resume(struct pt_regs *regs)
{
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
}

View file

@ -37,7 +37,7 @@ SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall *
SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper)
SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper) SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper)
NI_SYSCALL /* old fstat syscall */ NI_SYSCALL /* old fstat syscall */
SYSCALL(sys_pause,sys_pause,sys32_pause) SYSCALL(sys_pause,sys_pause,sys_pause)
SYSCALL(sys_utime,sys_utime,compat_sys_utime_wrapper) /* 30 */ SYSCALL(sys_utime,sys_utime,compat_sys_utime_wrapper) /* 30 */
NI_SYSCALL /* old stty syscall */ NI_SYSCALL /* old stty syscall */
NI_SYSCALL /* old gtty syscall */ NI_SYSCALL /* old gtty syscall */

View file

@ -1356,7 +1356,7 @@ static void __init stp_reset(void)
stp_page = alloc_bootmem_pages(PAGE_SIZE); stp_page = alloc_bootmem_pages(PAGE_SIZE);
rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000);
if (rc == 1) if (rc == 0)
set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags); set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags);
else if (stp_online) { else if (stp_online) {
printk(KERN_WARNING "Running on non STP capable machine.\n"); printk(KERN_WARNING "Running on non STP capable machine.\n");

View file

@ -92,3 +92,16 @@ out:
local_irq_restore(flags); local_irq_restore(flags);
preempt_enable(); preempt_enable();
} }
/*
* Simple udelay variant. To be used on startup and reboot
* when the interrupt handler isn't working.
*/
void udelay_simple(unsigned long usecs)
{
u64 end;
end = get_clock() + ((u64) usecs << 12);
while (get_clock() < end)
cpu_relax();
}

View file

@ -43,21 +43,41 @@
#define DCSS_FINDSEG 0x0c #define DCSS_FINDSEG 0x0c
#define DCSS_LOADNOLY 0x10 #define DCSS_LOADNOLY 0x10
#define DCSS_SEGEXT 0x18 #define DCSS_SEGEXT 0x18
#define DCSS_LOADSHRX 0x20
#define DCSS_LOADNSRX 0x24
#define DCSS_FINDSEGX 0x2c
#define DCSS_SEGEXTX 0x38
#define DCSS_FINDSEGA 0x0c #define DCSS_FINDSEGA 0x0c
struct qrange { struct qrange {
unsigned int start; // 3byte start address, 1 byte type unsigned long start; /* last byte type */
unsigned int end; // 3byte end address, 1 byte reserved unsigned long end; /* last byte reserved */
}; };
struct qout64 { struct qout64 {
int segstart; unsigned long segstart;
int segend; unsigned long segend;
int segcnt; int segcnt;
int segrcnt; int segrcnt;
struct qrange range[6]; struct qrange range[6];
}; };
#ifdef CONFIG_64BIT
struct qrange_old {
unsigned int start; /* last byte type */
unsigned int end; /* last byte reserved */
};
/* output area format for the Diag x'64' old subcode x'18' */
struct qout64_old {
int segstart;
int segend;
int segcnt;
int segrcnt;
struct qrange_old range[6];
};
#endif
struct qin64 { struct qin64 {
char qopcode; char qopcode;
char rsrv1[3]; char rsrv1[3];
@ -86,6 +106,55 @@ static DEFINE_MUTEX(dcss_lock);
static LIST_HEAD(dcss_list); static LIST_HEAD(dcss_list);
static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
"EW/EN-MIXED" }; "EW/EN-MIXED" };
static int loadshr_scode, loadnsr_scode, findseg_scode;
static int segext_scode, purgeseg_scode;
static int scode_set;
/* set correct Diag x'64' subcodes. */
static int
dcss_set_subcodes(void)
{
#ifdef CONFIG_64BIT
char *name = kmalloc(8 * sizeof(char), GFP_DMA);
unsigned long rx, ry;
int rc;
if (name == NULL)
return -ENOMEM;
rx = (unsigned long) name;
ry = DCSS_FINDSEGX;
strcpy(name, "dummy");
asm volatile(
" diag %0,%1,0x64\n"
"0: ipm %2\n"
" srl %2,28\n"
" j 2f\n"
"1: la %2,3\n"
"2:\n"
EX_TABLE(0b, 1b)
: "+d" (rx), "+d" (ry), "=d" (rc) : : "cc");
kfree(name);
/* Diag x'64' new subcodes are supported, set to new subcodes */
if (rc != 3) {
loadshr_scode = DCSS_LOADSHRX;
loadnsr_scode = DCSS_LOADNSRX;
purgeseg_scode = DCSS_PURGESEG;
findseg_scode = DCSS_FINDSEGX;
segext_scode = DCSS_SEGEXTX;
return 0;
}
#endif
/* Diag x'64' new subcodes are not supported, set to old subcodes */
loadshr_scode = DCSS_LOADNOLY;
loadnsr_scode = DCSS_LOADNSR;
purgeseg_scode = DCSS_PURGESEG;
findseg_scode = DCSS_FINDSEG;
segext_scode = DCSS_SEGEXT;
return 0;
}
/* /*
* Create the 8 bytes, ebcdic VM segment name from * Create the 8 bytes, ebcdic VM segment name from
@ -135,25 +204,45 @@ segment_by_name (char *name)
* Perform a function on a dcss segment. * Perform a function on a dcss segment.
*/ */
static inline int static inline int
dcss_diag (__u8 func, void *parameter, dcss_diag(int *func, void *parameter,
unsigned long *ret1, unsigned long *ret2) unsigned long *ret1, unsigned long *ret2)
{ {
unsigned long rx, ry; unsigned long rx, ry;
int rc; int rc;
if (scode_set == 0) {
rc = dcss_set_subcodes();
if (rc < 0)
return rc;
scode_set = 1;
}
rx = (unsigned long) parameter; rx = (unsigned long) parameter;
ry = (unsigned long) func; ry = (unsigned long) *func;
asm volatile(
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
" sam31\n" /* 64-bit Diag x'64' new subcode, keep in 64-bit addressing mode */
" diag %0,%1,0x64\n" if (*func > DCSS_SEGEXT)
" sam64\n" asm volatile(
" diag %0,%1,0x64\n"
" ipm %2\n"
" srl %2,28\n"
: "+d" (rx), "+d" (ry), "=d" (rc) : : "cc");
/* 31-bit Diag x'64' old subcode, switch to 31-bit addressing mode */
else
asm volatile(
" sam31\n"
" diag %0,%1,0x64\n"
" sam64\n"
" ipm %2\n"
" srl %2,28\n"
: "+d" (rx), "+d" (ry), "=d" (rc) : : "cc");
#else #else
asm volatile(
" diag %0,%1,0x64\n" " diag %0,%1,0x64\n"
#endif
" ipm %2\n" " ipm %2\n"
" srl %2,28\n" " srl %2,28\n"
: "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc");
#endif
*ret1 = rx; *ret1 = rx;
*ret2 = ry; *ret2 = ry;
return rc; return rc;
@ -190,14 +279,45 @@ query_segment_type (struct dcss_segment *seg)
qin->qoutlen = sizeof(struct qout64); qin->qoutlen = sizeof(struct qout64);
memcpy (qin->qname, seg->dcss_name, 8); memcpy (qin->qname, seg->dcss_name, 8);
diag_cc = dcss_diag (DCSS_SEGEXT, qin, &dummy, &vmrc); diag_cc = dcss_diag(&segext_scode, qin, &dummy, &vmrc);
if (diag_cc < 0) {
rc = diag_cc;
goto out_free;
}
if (diag_cc > 1) { if (diag_cc > 1) {
PRINT_WARN ("segment_type: diag returned error %ld\n", vmrc); PRINT_WARN ("segment_type: diag returned error %ld\n", vmrc);
rc = dcss_diag_translate_rc (vmrc); rc = dcss_diag_translate_rc (vmrc);
goto out_free; goto out_free;
} }
#ifdef CONFIG_64BIT
/* Only old format of output area of Diagnose x'64' is supported,
copy data for the new format. */
if (segext_scode == DCSS_SEGEXT) {
struct qout64_old *qout_old;
qout_old = kzalloc(sizeof(struct qout64_old), GFP_DMA);
if (qout_old == NULL) {
rc = -ENOMEM;
goto out_free;
}
memcpy(qout_old, qout, sizeof(struct qout64_old));
qout->segstart = (unsigned long) qout_old->segstart;
qout->segend = (unsigned long) qout_old->segend;
qout->segcnt = qout_old->segcnt;
qout->segrcnt = qout_old->segrcnt;
if (qout->segcnt > 6)
qout->segrcnt = 6;
for (i = 0; i < qout->segrcnt; i++) {
qout->range[i].start =
(unsigned long) qout_old->range[i].start;
qout->range[i].end =
(unsigned long) qout_old->range[i].end;
}
kfree(qout_old);
}
#endif
if (qout->segcnt > 6) { if (qout->segcnt > 6) {
rc = -ENOTSUPP; rc = -ENOTSUPP;
goto out_free; goto out_free;
@ -268,6 +388,30 @@ segment_type (char* name)
return seg.vm_segtype; return seg.vm_segtype;
} }
/*
* check if segment collides with other segments that are currently loaded
* returns 1 if this is the case, 0 if no collision was found
*/
static int
segment_overlaps_others (struct dcss_segment *seg)
{
struct list_head *l;
struct dcss_segment *tmp;
BUG_ON(!mutex_is_locked(&dcss_lock));
list_for_each(l, &dcss_list) {
tmp = list_entry(l, struct dcss_segment, list);
if ((tmp->start_addr >> 20) > (seg->end >> 20))
continue;
if ((tmp->end >> 20) < (seg->start_addr >> 20))
continue;
if (seg == tmp)
continue;
return 1;
}
return 0;
}
/* /*
* real segment loading function, called from segment_load * real segment loading function, called from segment_load
*/ */
@ -276,7 +420,8 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
{ {
struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment), struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment),
GFP_DMA); GFP_DMA);
int dcss_command, rc, diag_cc; int rc, diag_cc;
unsigned long start_addr, end_addr, dummy;
if (seg == NULL) { if (seg == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
@ -287,6 +432,13 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
if (rc < 0) if (rc < 0)
goto out_free; goto out_free;
if (loadshr_scode == DCSS_LOADSHRX) {
if (segment_overlaps_others(seg)) {
rc = -EBUSY;
goto out_free;
}
}
rc = vmem_add_mapping(seg->start_addr, seg->end - seg->start_addr + 1); rc = vmem_add_mapping(seg->start_addr, seg->end - seg->start_addr + 1);
if (rc) if (rc)
@ -316,20 +468,28 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
} }
if (do_nonshared) if (do_nonshared)
dcss_command = DCSS_LOADNSR; diag_cc = dcss_diag(&loadnsr_scode, seg->dcss_name,
&start_addr, &end_addr);
else else
dcss_command = DCSS_LOADNOLY; diag_cc = dcss_diag(&loadshr_scode, seg->dcss_name,
&start_addr, &end_addr);
diag_cc = dcss_diag(dcss_command, seg->dcss_name, if (diag_cc < 0) {
&seg->start_addr, &seg->end); dcss_diag(&purgeseg_scode, seg->dcss_name,
if (diag_cc > 1) { &dummy, &dummy);
PRINT_WARN ("segment_load: could not load segment %s - " rc = diag_cc;
"diag returned error (%ld)\n",name,seg->end);
rc = dcss_diag_translate_rc (seg->end);
dcss_diag(DCSS_PURGESEG, seg->dcss_name,
&seg->start_addr, &seg->end);
goto out_resource; goto out_resource;
} }
if (diag_cc > 1) {
PRINT_WARN ("segment_load: could not load segment %s - "
"diag returned error (%ld)\n",
name, end_addr);
rc = dcss_diag_translate_rc(end_addr);
dcss_diag(&purgeseg_scode, seg->dcss_name,
&dummy, &dummy);
goto out_resource;
}
seg->start_addr = start_addr;
seg->end = end_addr;
seg->do_nonshared = do_nonshared; seg->do_nonshared = do_nonshared;
atomic_set(&seg->ref_count, 1); atomic_set(&seg->ref_count, 1);
list_add(&seg->list, &dcss_list); list_add(&seg->list, &dcss_list);
@ -423,8 +583,8 @@ int
segment_modify_shared (char *name, int do_nonshared) segment_modify_shared (char *name, int do_nonshared)
{ {
struct dcss_segment *seg; struct dcss_segment *seg;
unsigned long dummy; unsigned long start_addr, end_addr, dummy;
int dcss_command, rc, diag_cc; int rc, diag_cc;
mutex_lock(&dcss_lock); mutex_lock(&dcss_lock);
seg = segment_by_name (name); seg = segment_by_name (name);
@ -445,38 +605,51 @@ segment_modify_shared (char *name, int do_nonshared)
goto out_unlock; goto out_unlock;
} }
release_resource(seg->res); release_resource(seg->res);
if (do_nonshared) { if (do_nonshared)
dcss_command = DCSS_LOADNSR;
seg->res->flags &= ~IORESOURCE_READONLY; seg->res->flags &= ~IORESOURCE_READONLY;
} else { else
dcss_command = DCSS_LOADNOLY;
if (seg->vm_segtype == SEG_TYPE_SR || if (seg->vm_segtype == SEG_TYPE_SR ||
seg->vm_segtype == SEG_TYPE_ER) seg->vm_segtype == SEG_TYPE_ER)
seg->res->flags |= IORESOURCE_READONLY; seg->res->flags |= IORESOURCE_READONLY;
}
if (request_resource(&iomem_resource, seg->res)) { if (request_resource(&iomem_resource, seg->res)) {
PRINT_WARN("segment_modify_shared: could not reload segment %s" PRINT_WARN("segment_modify_shared: could not reload segment %s"
" - overlapping resources\n", name); " - overlapping resources\n", name);
rc = -EBUSY; rc = -EBUSY;
kfree(seg->res); kfree(seg->res);
goto out_del; goto out_del_mem;
}
dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy);
if (do_nonshared)
diag_cc = dcss_diag(&loadnsr_scode, seg->dcss_name,
&start_addr, &end_addr);
else
diag_cc = dcss_diag(&loadshr_scode, seg->dcss_name,
&start_addr, &end_addr);
if (diag_cc < 0) {
rc = diag_cc;
goto out_del_res;
} }
dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy);
diag_cc = dcss_diag(dcss_command, seg->dcss_name,
&seg->start_addr, &seg->end);
if (diag_cc > 1) { if (diag_cc > 1) {
PRINT_WARN ("segment_modify_shared: could not reload segment %s" PRINT_WARN ("segment_modify_shared: could not reload segment %s"
" - diag returned error (%ld)\n",name,seg->end); " - diag returned error (%ld)\n",
rc = dcss_diag_translate_rc (seg->end); name, end_addr);
goto out_del; rc = dcss_diag_translate_rc(end_addr);
goto out_del_res;
} }
seg->start_addr = start_addr;
seg->end = end_addr;
seg->do_nonshared = do_nonshared; seg->do_nonshared = do_nonshared;
rc = 0; rc = 0;
goto out_unlock; goto out_unlock;
out_del: out_del_res:
release_resource(seg->res);
kfree(seg->res);
out_del_mem:
vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1); vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1);
list_del(&seg->list); list_del(&seg->list);
dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy);
kfree(seg); kfree(seg);
out_unlock: out_unlock:
mutex_unlock(&dcss_lock); mutex_unlock(&dcss_lock);
@ -510,7 +683,7 @@ segment_unload(char *name)
kfree(seg->res); kfree(seg->res);
vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1); vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1);
list_del(&seg->list); list_del(&seg->list);
dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy);
kfree(seg); kfree(seg);
out_unlock: out_unlock:
mutex_unlock(&dcss_lock); mutex_unlock(&dcss_lock);
@ -545,7 +718,7 @@ segment_save(char *name)
endpfn = (seg->end) >> PAGE_SHIFT; endpfn = (seg->end) >> PAGE_SHIFT;
sprintf(cmd1, "DEFSEG %s", name); sprintf(cmd1, "DEFSEG %s", name);
for (i=0; i<seg->segcnt; i++) { for (i=0; i<seg->segcnt; i++) {
sprintf(cmd1+strlen(cmd1), " %X-%X %s", sprintf(cmd1+strlen(cmd1), " %lX-%lX %s",
seg->range[i].start >> PAGE_SHIFT, seg->range[i].start >> PAGE_SHIFT,
seg->range[i].end >> PAGE_SHIFT, seg->range[i].end >> PAGE_SHIFT,
segtype_string[seg->range[i].start & 0xff]); segtype_string[seg->range[i].start & 0xff]);

View file

@ -215,7 +215,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device)
return rc; return rc;
} }
/* register 'device' debug area, used for all DBF_DEV_XXX calls */ /* register 'device' debug area, used for all DBF_DEV_XXX calls */
device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 1, device->debug_area = debug_register(dev_name(&device->cdev->dev), 1, 1,
8 * sizeof(long)); 8 * sizeof(long));
debug_register_view(device->debug_area, &debug_sprintf_view); debug_register_view(device->debug_area, &debug_sprintf_view);
debug_set_level(device->debug_area, DBF_WARNING); debug_set_level(device->debug_area, DBF_WARNING);
@ -933,7 +933,7 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
MESSAGE(KERN_DEBUG, MESSAGE(KERN_DEBUG,
"invalid status in handle_killed_request: " "invalid status in handle_killed_request: "
"bus_id %s, status %02x", "bus_id %s, status %02x",
cdev->dev.bus_id, cqr->status); dev_name(&cdev->dev), cqr->status);
return; return;
} }
@ -942,7 +942,7 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
device != dasd_device_from_cdev_locked(cdev) || device != dasd_device_from_cdev_locked(cdev) ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
cdev->dev.bus_id); dev_name(&cdev->dev));
return; return;
} }
@ -982,11 +982,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
break; break;
case -ETIMEDOUT: case -ETIMEDOUT:
printk(KERN_WARNING"%s(%s): request timed out\n", printk(KERN_WARNING"%s(%s): request timed out\n",
__func__, cdev->dev.bus_id); __func__, dev_name(&cdev->dev));
break; break;
default: default:
printk(KERN_WARNING"%s(%s): unknown error %ld\n", printk(KERN_WARNING"%s(%s): unknown error %ld\n",
__func__, cdev->dev.bus_id, PTR_ERR(irb)); __func__, dev_name(&cdev->dev), PTR_ERR(irb));
} }
dasd_handle_killed_request(cdev, intparm); dasd_handle_killed_request(cdev, intparm);
return; return;
@ -995,7 +995,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
now = get_clock(); now = get_clock();
DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x", DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
cdev->dev.bus_id, ((irb->scsw.cmd.cstat << 8) | dev_name(&cdev->dev), ((irb->scsw.cmd.cstat << 8) |
irb->scsw.cmd.dstat), (unsigned int) intparm); irb->scsw.cmd.dstat), (unsigned int) intparm);
/* check for unsolicited interrupts */ /* check for unsolicited interrupts */
@ -1019,7 +1019,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
if (!device || if (!device ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
cdev->dev.bus_id); dev_name(&cdev->dev));
return; return;
} }
@ -1037,7 +1037,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
if (cqr->status != DASD_CQR_IN_IO) { if (cqr->status != DASD_CQR_IN_IO) {
MESSAGE(KERN_DEBUG, MESSAGE(KERN_DEBUG,
"invalid status: bus_id %s, status %02x", "invalid status: bus_id %s, status %02x",
cdev->dev.bus_id, cqr->status); dev_name(&cdev->dev), cqr->status);
return; return;
} }
DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p", DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
@ -2134,14 +2134,14 @@ int dasd_generic_probe(struct ccw_device *cdev,
if (ret) { if (ret) {
printk(KERN_WARNING printk(KERN_WARNING
"dasd_generic_probe: could not set ccw-device options " "dasd_generic_probe: could not set ccw-device options "
"for %s\n", cdev->dev.bus_id); "for %s\n", dev_name(&cdev->dev));
return ret; return ret;
} }
ret = dasd_add_sysfs_files(cdev); ret = dasd_add_sysfs_files(cdev);
if (ret) { if (ret) {
printk(KERN_WARNING printk(KERN_WARNING
"dasd_generic_probe: could not add sysfs entries " "dasd_generic_probe: could not add sysfs entries "
"for %s\n", cdev->dev.bus_id); "for %s\n", dev_name(&cdev->dev));
return ret; return ret;
} }
cdev->handler = &dasd_int_handler; cdev->handler = &dasd_int_handler;
@ -2152,13 +2152,13 @@ int dasd_generic_probe(struct ccw_device *cdev,
* initial probe. * initial probe.
*/ */
if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
(dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0)) (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
ret = ccw_device_set_online(cdev); ret = ccw_device_set_online(cdev);
if (ret) if (ret)
printk(KERN_WARNING printk(KERN_WARNING
"dasd_generic_probe: could not initially " "dasd_generic_probe: could not initially "
"online ccw-device %s; return code: %d\n", "online ccw-device %s; return code: %d\n",
cdev->dev.bus_id, ret); dev_name(&cdev->dev), ret);
return 0; return 0;
} }
@ -2224,7 +2224,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
printk (KERN_WARNING printk (KERN_WARNING
"dasd_generic couldn't online device %s " "dasd_generic couldn't online device %s "
"- discipline DIAG not available\n", "- discipline DIAG not available\n",
cdev->dev.bus_id); dev_name(&cdev->dev));
dasd_delete_device(device); dasd_delete_device(device);
return -ENODEV; return -ENODEV;
} }
@ -2248,7 +2248,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
printk (KERN_WARNING printk (KERN_WARNING
"dasd_generic couldn't online device %s " "dasd_generic couldn't online device %s "
"with discipline %s rc=%i\n", "with discipline %s rc=%i\n",
cdev->dev.bus_id, discipline->name, rc); dev_name(&cdev->dev), discipline->name, rc);
module_put(discipline->owner); module_put(discipline->owner);
module_put(base_discipline->owner); module_put(base_discipline->owner);
dasd_delete_device(device); dasd_delete_device(device);
@ -2259,7 +2259,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
if (device->state <= DASD_STATE_KNOWN) { if (device->state <= DASD_STATE_KNOWN) {
printk (KERN_WARNING printk (KERN_WARNING
"dasd_generic discipline not found for %s\n", "dasd_generic discipline not found for %s\n",
cdev->dev.bus_id); dev_name(&cdev->dev));
rc = -ENODEV; rc = -ENODEV;
dasd_set_target_state(device, DASD_STATE_NEW); dasd_set_target_state(device, DASD_STATE_NEW);
if (device->block) if (device->block)
@ -2267,7 +2267,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
dasd_delete_device(device); dasd_delete_device(device);
} else } else
pr_debug("dasd_generic device %s found\n", pr_debug("dasd_generic device %s found\n",
cdev->dev.bus_id); dev_name(&cdev->dev));
/* FIXME: we have to wait for the root device but we don't want /* FIXME: we have to wait for the root device but we don't want
* to wait for each single device but for all at once. */ * to wait for each single device but for all at once. */

View file

@ -1397,7 +1397,7 @@ static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
DEV_MESSAGE(KERN_ERR, cqr->startdev, DEV_MESSAGE(KERN_ERR, cqr->startdev,
"ERP on alias device for request %p," "ERP on alias device for request %p,"
" recover on base device %s", cqr, " recover on base device %s", cqr,
cqr->block->base->cdev->dev.bus_id); dev_name(&cqr->block->base->cdev->dev));
} }
dasd_eckd_reset_ccw_to_base_io(cqr); dasd_eckd_reset_ccw_to_base_io(cqr);
erp->startdev = cqr->block->base; erp->startdev = cqr->block->base;

View file

@ -515,9 +515,9 @@ dasd_devmap_from_cdev(struct ccw_device *cdev)
{ {
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
devmap = dasd_find_busid(cdev->dev.bus_id); devmap = dasd_find_busid(dev_name(&cdev->dev));
if (IS_ERR(devmap)) if (IS_ERR(devmap))
devmap = dasd_add_busid(cdev->dev.bus_id, devmap = dasd_add_busid(dev_name(&cdev->dev),
DASD_FEATURE_DEFAULT); DASD_FEATURE_DEFAULT);
return devmap; return devmap;
} }
@ -584,7 +584,7 @@ dasd_delete_device(struct dasd_device *device)
unsigned long flags; unsigned long flags;
/* First remove device pointer from devmap. */ /* First remove device pointer from devmap. */
devmap = dasd_find_busid(device->cdev->dev.bus_id); devmap = dasd_find_busid(dev_name(&device->cdev->dev));
BUG_ON(IS_ERR(devmap)); BUG_ON(IS_ERR(devmap));
spin_lock(&dasd_devmap_lock); spin_lock(&dasd_devmap_lock);
if (devmap->device != device) { if (devmap->device != device) {
@ -674,7 +674,7 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
int ro_flag; int ro_flag;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
if (!IS_ERR(devmap)) if (!IS_ERR(devmap))
ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0; ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
else else
@ -723,7 +723,7 @@ dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
int erplog; int erplog;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
if (!IS_ERR(devmap)) if (!IS_ERR(devmap))
erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0; erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
else else
@ -770,7 +770,7 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
int use_diag; int use_diag;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
if (!IS_ERR(devmap)) if (!IS_ERR(devmap))
use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0; use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
else else
@ -876,7 +876,7 @@ dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
int alias; int alias;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
spin_lock(&dasd_devmap_lock); spin_lock(&dasd_devmap_lock);
if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
spin_unlock(&dasd_devmap_lock); spin_unlock(&dasd_devmap_lock);
@ -899,7 +899,7 @@ dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
char *vendor; char *vendor;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
spin_lock(&dasd_devmap_lock); spin_lock(&dasd_devmap_lock);
if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
vendor = devmap->uid.vendor; vendor = devmap->uid.vendor;
@ -924,7 +924,7 @@ dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
char ua_string[3]; char ua_string[3];
struct dasd_uid *uid; struct dasd_uid *uid;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
spin_lock(&dasd_devmap_lock); spin_lock(&dasd_devmap_lock);
if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
spin_unlock(&dasd_devmap_lock); spin_unlock(&dasd_devmap_lock);
@ -972,7 +972,7 @@ dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
int eer_flag; int eer_flag;
devmap = dasd_find_busid(dev->bus_id); devmap = dasd_find_busid(dev_name(dev));
if (!IS_ERR(devmap) && devmap->device) if (!IS_ERR(devmap) && devmap->device)
eer_flag = dasd_eer_enabled(devmap->device); eer_flag = dasd_eer_enabled(devmap->device);
else else
@ -1034,7 +1034,7 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
{ {
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
devmap = dasd_find_busid(cdev->dev.bus_id); devmap = dasd_find_busid(dev_name(&cdev->dev));
if (IS_ERR(devmap)) if (IS_ERR(devmap))
return PTR_ERR(devmap); return PTR_ERR(devmap);
spin_lock(&dasd_devmap_lock); spin_lock(&dasd_devmap_lock);
@ -1057,7 +1057,7 @@ dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
{ {
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
devmap = dasd_find_busid(cdev->dev.bus_id); devmap = dasd_find_busid(dev_name(&cdev->dev));
if (IS_ERR(devmap)) if (IS_ERR(devmap))
return PTR_ERR(devmap); return PTR_ERR(devmap);
@ -1077,7 +1077,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature)
{ {
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
devmap = dasd_find_busid(cdev->dev.bus_id); devmap = dasd_find_busid(dev_name(&cdev->dev));
if (IS_ERR(devmap)) if (IS_ERR(devmap))
return PTR_ERR(devmap); return PTR_ERR(devmap);
@ -1093,7 +1093,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
{ {
struct dasd_devmap *devmap; struct dasd_devmap *devmap;
devmap = dasd_find_busid(cdev->dev.bus_id); devmap = dasd_find_busid(dev_name(&cdev->dev));
if (IS_ERR(devmap)) if (IS_ERR(devmap))
return PTR_ERR(devmap); return PTR_ERR(devmap);

View file

@ -6,6 +6,8 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com>
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
* EMC Symmetrix ioctl Copyright EMC Corporation, 2008
* Author.........: Nigel Hislop <hislop_nigel@emc.com>
* *
*/ */
@ -84,7 +86,7 @@ dasd_eckd_probe (struct ccw_device *cdev)
if (ret) { if (ret) {
printk(KERN_WARNING printk(KERN_WARNING
"dasd_eckd_probe: could not set ccw-device options " "dasd_eckd_probe: could not set ccw-device options "
"for %s\n", cdev->dev.bus_id); "for %s\n", dev_name(&cdev->dev));
return ret; return ret;
} }
ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
@ -1501,12 +1503,27 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
return; return;
} }
/* just report other unsolicited interrupts */ if ((irb->scsw.cmd.cc == 1) &&
DEV_MESSAGE(KERN_DEBUG, device, "%s", (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
"unsolicited interrupt received"); (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) &&
device->discipline->dump_sense(device, NULL, irb); (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) {
dasd_schedule_device_bh(device); /* fake irb do nothing, they are handled elsewhere */
dasd_schedule_device_bh(device);
return;
}
if (!(irb->esw.esw0.erw.cons)) {
/* just report other unsolicited interrupts */
DEV_MESSAGE(KERN_ERR, device, "%s",
"unsolicited interrupt received");
} else {
DEV_MESSAGE(KERN_ERR, device, "%s",
"unsolicited interrupt received "
"(sense available)");
device->discipline->dump_sense(device, NULL, irb);
}
dasd_schedule_device_bh(device);
return; return;
}; };
@ -2068,6 +2085,103 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
return 0; return 0;
} }
/*
* Issue syscall I/O to EMC Symmetrix array.
* CCWs are PSF and RSSD
*/
static int dasd_symm_io(struct dasd_device *device, void __user *argp)
{
struct dasd_symmio_parms usrparm;
char *psf_data, *rssd_result;
struct dasd_ccw_req *cqr;
struct ccw1 *ccw;
int rc;
/* Copy parms from caller */
rc = -EFAULT;
if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
goto out;
#ifndef CONFIG_64BIT
/* Make sure pointers are sane even on 31 bit. */
if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) {
rc = -EINVAL;
goto out;
}
#endif
/* alloc I/O data area */
psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);
rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);
if (!psf_data || !rssd_result) {
rc = -ENOMEM;
goto out_free;
}
/* get syscall header from user space */
rc = -EFAULT;
if (copy_from_user(psf_data,
(void __user *)(unsigned long) usrparm.psf_data,
usrparm.psf_data_len))
goto out_free;
/* sanity check on syscall header */
if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
rc = -EINVAL;
goto out_free;
}
/* setup CCWs for PSF + RSSD */
cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
if (IS_ERR(cqr)) {
DEV_MESSAGE(KERN_WARNING, device, "%s",
"Could not allocate initialization request");
rc = PTR_ERR(cqr);
goto out_free;
}
cqr->startdev = device;
cqr->memdev = device;
cqr->retries = 3;
cqr->expires = 10 * HZ;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
/* Build the ccws */
ccw = cqr->cpaddr;
/* PSF ccw */
ccw->cmd_code = DASD_ECKD_CCW_PSF;
ccw->count = usrparm.psf_data_len;
ccw->flags |= CCW_FLAG_CC;
ccw->cda = (__u32)(addr_t) psf_data;
ccw++;
/* RSSD ccw */
ccw->cmd_code = DASD_ECKD_CCW_RSSD;
ccw->count = usrparm.rssd_result_len;
ccw->flags = CCW_FLAG_SLI ;
ccw->cda = (__u32)(addr_t) rssd_result;
rc = dasd_sleep_on(cqr);
if (rc)
goto out_sfree;
rc = -EFAULT;
if (copy_to_user((void __user *)(unsigned long) usrparm.rssd_result,
rssd_result, usrparm.rssd_result_len))
goto out_sfree;
rc = 0;
out_sfree:
dasd_sfree_request(cqr, cqr->memdev);
out_free:
kfree(rssd_result);
kfree(psf_data);
out:
DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc);
return rc;
}
static int static int
dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp) dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
{ {
@ -2086,6 +2200,8 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
return dasd_eckd_reserve(device); return dasd_eckd_reserve(device);
case BIODASDSLCK: case BIODASDSLCK:
return dasd_eckd_steal_lock(device); return dasd_eckd_steal_lock(device);
case BIODASDSYMMIO:
return dasd_symm_io(device, argp);
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
@ -2145,13 +2261,13 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
/* dump the sense data */ /* dump the sense data */
len = sprintf(page, KERN_ERR PRINTK_HEADER len = sprintf(page, KERN_ERR PRINTK_HEADER
" I/O status report for device %s:\n", " I/O status report for device %s:\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X\n", req, " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n", " device %s: Failing CCW: %p\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
(void *) (addr_t) irb->scsw.cmd.cpa); (void *) (addr_t) irb->scsw.cmd.cpa);
if (irb->esw.esw0.erw.cons) { if (irb->esw.esw0.erw.cons) {
for (sl = 0; sl < 4; sl++) { for (sl = 0; sl < 4; sl++) {

View file

@ -309,7 +309,8 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
do_gettimeofday(&tv); do_gettimeofday(&tv);
header.tv_sec = tv.tv_sec; header.tv_sec = tv.tv_sec;
header.tv_usec = tv.tv_usec; header.tv_usec = tv.tv_usec;
strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); strncpy(header.busid, dev_name(&device->cdev->dev),
DASD_EER_BUSID_SIZE);
spin_lock_irqsave(&bufferlock, flags); spin_lock_irqsave(&bufferlock, flags);
list_for_each_entry(eerb, &bufferlist, list) { list_for_each_entry(eerb, &bufferlist, list) {
@ -349,7 +350,8 @@ static void dasd_eer_write_snss_trigger(struct dasd_device *device,
do_gettimeofday(&tv); do_gettimeofday(&tv);
header.tv_sec = tv.tv_sec; header.tv_sec = tv.tv_sec;
header.tv_usec = tv.tv_usec; header.tv_usec = tv.tv_usec;
strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); strncpy(header.busid, dev_name(&device->cdev->dev),
DASD_EER_BUSID_SIZE);
spin_lock_irqsave(&bufferlock, flags); spin_lock_irqsave(&bufferlock, flags);
list_for_each_entry(eerb, &bufferlist, list) { list_for_each_entry(eerb, &bufferlist, list) {

View file

@ -451,13 +451,13 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
} }
len = sprintf(page, KERN_ERR PRINTK_HEADER len = sprintf(page, KERN_ERR PRINTK_HEADER
" I/O status report for device %s:\n", " I/O status report for device %s:\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X\n", req, " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n", " device %s: Failing CCW: %p\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
(void *) (addr_t) irb->scsw.cmd.cpa); (void *) (addr_t) irb->scsw.cmd.cpa);
if (irb->esw.esw0.erw.cons) { if (irb->esw.esw0.erw.cons) {
for (sl = 0; sl < 4; sl++) { for (sl = 0; sl < 4; sl++) {

View file

@ -126,7 +126,7 @@ do { \
#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\ #define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
do { \ do { \
printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \ printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
d_device->cdev->dev.bus_id, d_args); \ dev_name(&d_device->cdev->dev), d_args); \
DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \ DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \
} while(0) } while(0)
@ -140,7 +140,7 @@ do { \
#define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\ #define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\
do { \ do { \
printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \ printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
d_device->cdev->dev.bus_id, d_args); \ dev_name(&d_device->cdev->dev), d_args); \
} while(0) } while(0)
#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\ #define MESSAGE_LOG(d_loglevel,d_string,d_args...)\

View file

@ -67,7 +67,7 @@ dasd_devices_show(struct seq_file *m, void *v)
return 0; return 0;
} }
/* Print device number. */ /* Print device number. */
seq_printf(m, "%s", device->cdev->dev.bus_id); seq_printf(m, "%s", dev_name(&device->cdev->dev));
/* Print discipline string. */ /* Print discipline string. */
if (device != NULL && device->discipline != NULL) if (device != NULL && device->discipline != NULL)
seq_printf(m, "(%s)", device->discipline->name); seq_printf(m, "(%s)", device->discipline->name);

View file

@ -31,7 +31,6 @@
#define PRINT_WARN(x...) printk(KERN_WARNING DCSSBLK_NAME " warning: " x) #define PRINT_WARN(x...) printk(KERN_WARNING DCSSBLK_NAME " warning: " x)
#define PRINT_ERR(x...) printk(KERN_ERR DCSSBLK_NAME " error: " x) #define PRINT_ERR(x...) printk(KERN_ERR DCSSBLK_NAME " error: " x)
static int dcssblk_open(struct inode *inode, struct file *filp); static int dcssblk_open(struct inode *inode, struct file *filp);
static int dcssblk_release(struct inode *inode, struct file *filp); static int dcssblk_release(struct inode *inode, struct file *filp);
static int dcssblk_make_request(struct request_queue *q, struct bio *bio); static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
@ -48,26 +47,6 @@ static struct block_device_operations dcssblk_devops = {
.direct_access = dcssblk_direct_access, .direct_access = dcssblk_direct_access,
}; };
static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
static DEVICE_ATTR(save, S_IWUSR | S_IRUGO, dcssblk_save_show,
dcssblk_save_store);
static DEVICE_ATTR(shared, S_IWUSR | S_IRUGO, dcssblk_shared_show,
dcssblk_shared_store);
static struct device *dcssblk_root_dev;
struct dcssblk_dev_info { struct dcssblk_dev_info {
struct list_head lh; struct list_head lh;
struct device dev; struct device dev;
@ -80,8 +59,42 @@ struct dcssblk_dev_info {
unsigned char save_pending; unsigned char save_pending;
unsigned char is_shared; unsigned char is_shared;
struct request_queue *dcssblk_queue; struct request_queue *dcssblk_queue;
int num_of_segments;
struct list_head seg_list;
}; };
struct segment_info {
struct list_head lh;
char segment_name[BUS_ID_SIZE];
unsigned long start;
unsigned long end;
int segment_type;
};
static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t dcssblk_seglist_show(struct device *dev,
struct device_attribute *attr,
char *buf);
static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
dcssblk_save_store);
static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
dcssblk_shared_store);
static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
static struct device *dcssblk_root_dev;
static LIST_HEAD(dcssblk_devices); static LIST_HEAD(dcssblk_devices);
static struct rw_semaphore dcssblk_devices_sem; static struct rw_semaphore dcssblk_devices_sem;
@ -91,8 +104,15 @@ static struct rw_semaphore dcssblk_devices_sem;
static void static void
dcssblk_release_segment(struct device *dev) dcssblk_release_segment(struct device *dev)
{ {
PRINT_DEBUG("segment release fn called for %s\n", dev->bus_id); struct dcssblk_dev_info *dev_info;
kfree(container_of(dev, struct dcssblk_dev_info, dev)); struct segment_info *entry, *temp;
dev_info = container_of(dev, struct dcssblk_dev_info, dev);
list_for_each_entry_safe(entry, temp, &dev_info->seg_list, lh) {
list_del(&entry->lh);
kfree(entry);
}
kfree(dev_info);
module_put(THIS_MODULE); module_put(THIS_MODULE);
} }
@ -142,6 +162,169 @@ dcssblk_get_device_by_name(char *name)
return NULL; return NULL;
} }
/*
* get the struct segment_info from seg_list
* for the given name.
* down_read(&dcssblk_devices_sem) must be held.
*/
static struct segment_info *
dcssblk_get_segment_by_name(char *name)
{
struct dcssblk_dev_info *dev_info;
struct segment_info *entry;
list_for_each_entry(dev_info, &dcssblk_devices, lh) {
list_for_each_entry(entry, &dev_info->seg_list, lh) {
if (!strcmp(name, entry->segment_name))
return entry;
}
}
return NULL;
}
/*
* get the highest address of the multi-segment block.
*/
static unsigned long
dcssblk_find_highest_addr(struct dcssblk_dev_info *dev_info)
{
unsigned long highest_addr;
struct segment_info *entry;
highest_addr = 0;
list_for_each_entry(entry, &dev_info->seg_list, lh) {
if (highest_addr < entry->end)
highest_addr = entry->end;
}
return highest_addr;
}
/*
* get the lowest address of the multi-segment block.
*/
static unsigned long
dcssblk_find_lowest_addr(struct dcssblk_dev_info *dev_info)
{
int set_first;
unsigned long lowest_addr;
struct segment_info *entry;
set_first = 0;
lowest_addr = 0;
list_for_each_entry(entry, &dev_info->seg_list, lh) {
if (set_first == 0) {
lowest_addr = entry->start;
set_first = 1;
} else {
if (lowest_addr > entry->start)
lowest_addr = entry->start;
}
}
return lowest_addr;
}
/*
* Check continuity of segments.
*/
static int
dcssblk_is_continuous(struct dcssblk_dev_info *dev_info)
{
int i, j, rc;
struct segment_info *sort_list, *entry, temp;
if (dev_info->num_of_segments <= 1)
return 0;
sort_list = kzalloc(
sizeof(struct segment_info) * dev_info->num_of_segments,
GFP_KERNEL);
if (sort_list == NULL)
return -ENOMEM;
i = 0;
list_for_each_entry(entry, &dev_info->seg_list, lh) {
memcpy(&sort_list[i], entry, sizeof(struct segment_info));
i++;
}
/* sort segments */
for (i = 0; i < dev_info->num_of_segments; i++)
for (j = 0; j < dev_info->num_of_segments; j++)
if (sort_list[j].start > sort_list[i].start) {
memcpy(&temp, &sort_list[i],
sizeof(struct segment_info));
memcpy(&sort_list[i], &sort_list[j],
sizeof(struct segment_info));
memcpy(&sort_list[j], &temp,
sizeof(struct segment_info));
}
/* check continuity */
for (i = 0; i < dev_info->num_of_segments - 1; i++) {
if ((sort_list[i].end + 1) != sort_list[i+1].start) {
PRINT_ERR("Segment %s is not contiguous with "
"segment %s\n",
sort_list[i].segment_name,
sort_list[i+1].segment_name);
rc = -EINVAL;
goto out;
}
/* EN and EW are allowed in a block device */
if (sort_list[i].segment_type != sort_list[i+1].segment_type) {
if (!(sort_list[i].segment_type & SEGMENT_EXCLUSIVE) ||
(sort_list[i].segment_type == SEG_TYPE_ER) ||
!(sort_list[i+1].segment_type &
SEGMENT_EXCLUSIVE) ||
(sort_list[i+1].segment_type == SEG_TYPE_ER)) {
PRINT_ERR("Segment %s has different type from "
"segment %s\n",
sort_list[i].segment_name,
sort_list[i+1].segment_name);
rc = -EINVAL;
goto out;
}
}
}
rc = 0;
out:
kfree(sort_list);
return rc;
}
/*
* Load a segment
*/
static int
dcssblk_load_segment(char *name, struct segment_info **seg_info)
{
int rc;
/* already loaded? */
down_read(&dcssblk_devices_sem);
*seg_info = dcssblk_get_segment_by_name(name);
up_read(&dcssblk_devices_sem);
if (*seg_info != NULL)
return -EEXIST;
/* get a struct segment_info */
*seg_info = kzalloc(sizeof(struct segment_info), GFP_KERNEL);
if (*seg_info == NULL)
return -ENOMEM;
strcpy((*seg_info)->segment_name, name);
/* load the segment */
rc = segment_load(name, SEGMENT_SHARED,
&(*seg_info)->start, &(*seg_info)->end);
if (rc < 0) {
segment_warning(rc, (*seg_info)->segment_name);
kfree(*seg_info);
} else {
INIT_LIST_HEAD(&(*seg_info)->lh);
(*seg_info)->segment_type = rc;
}
return rc;
}
static void dcssblk_unregister_callback(struct device *dev) static void dcssblk_unregister_callback(struct device *dev)
{ {
device_unregister(dev); device_unregister(dev);
@ -165,6 +348,7 @@ static ssize_t
dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count) dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count)
{ {
struct dcssblk_dev_info *dev_info; struct dcssblk_dev_info *dev_info;
struct segment_info *entry, *temp;
int rc; int rc;
if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0'))
@ -172,46 +356,46 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
down_write(&dcssblk_devices_sem); down_write(&dcssblk_devices_sem);
dev_info = container_of(dev, struct dcssblk_dev_info, dev); dev_info = container_of(dev, struct dcssblk_dev_info, dev);
if (atomic_read(&dev_info->use_count)) { if (atomic_read(&dev_info->use_count)) {
PRINT_ERR("share: segment %s is busy!\n",
dev_info->segment_name);
rc = -EBUSY; rc = -EBUSY;
goto out; goto out;
} }
if (inbuf[0] == '1') { if (inbuf[0] == '1') {
// reload segment in shared mode /* reload segments in shared mode */
rc = segment_modify_shared(dev_info->segment_name, list_for_each_entry(entry, &dev_info->seg_list, lh) {
SEGMENT_SHARED); rc = segment_modify_shared(entry->segment_name,
if (rc < 0) { SEGMENT_SHARED);
BUG_ON(rc == -EINVAL); if (rc < 0) {
if (rc != -EAGAIN) BUG_ON(rc == -EINVAL);
goto removeseg; if (rc != -EAGAIN)
} else { goto removeseg;
dev_info->is_shared = 1;
switch (dev_info->segment_type) {
case SEG_TYPE_SR:
case SEG_TYPE_ER:
case SEG_TYPE_SC:
set_disk_ro(dev_info->gd,1);
} }
} }
dev_info->is_shared = 1;
switch (dev_info->segment_type) {
case SEG_TYPE_SR:
case SEG_TYPE_ER:
case SEG_TYPE_SC:
set_disk_ro(dev_info->gd, 1);
}
} else if (inbuf[0] == '0') { } else if (inbuf[0] == '0') {
// reload segment in exclusive mode /* reload segments in exclusive mode */
if (dev_info->segment_type == SEG_TYPE_SC) { if (dev_info->segment_type == SEG_TYPE_SC) {
PRINT_ERR("Segment type SC (%s) cannot be loaded in " PRINT_ERR("Segment type SC (%s) cannot be loaded in "
"non-shared mode\n", dev_info->segment_name); "non-shared mode\n", dev_info->segment_name);
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }
rc = segment_modify_shared(dev_info->segment_name, list_for_each_entry(entry, &dev_info->seg_list, lh) {
SEGMENT_EXCLUSIVE); rc = segment_modify_shared(entry->segment_name,
if (rc < 0) { SEGMENT_EXCLUSIVE);
BUG_ON(rc == -EINVAL); if (rc < 0) {
if (rc != -EAGAIN) BUG_ON(rc == -EINVAL);
goto removeseg; if (rc != -EAGAIN)
} else { goto removeseg;
dev_info->is_shared = 0; }
set_disk_ro(dev_info->gd, 0);
} }
dev_info->is_shared = 0;
set_disk_ro(dev_info->gd, 0);
} else { } else {
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
@ -220,8 +404,14 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
goto out; goto out;
removeseg: removeseg:
PRINT_ERR("Could not reload segment %s, removing it now!\n", PRINT_ERR("Could not reload segment(s) of the device %s, removing "
dev_info->segment_name); "segment(s) now!\n",
dev_info->segment_name);
temp = entry;
list_for_each_entry(entry, &dev_info->seg_list, lh) {
if (entry != temp)
segment_unload(entry->segment_name);
}
list_del(&dev_info->lh); list_del(&dev_info->lh);
del_gendisk(dev_info->gd); del_gendisk(dev_info->gd);
@ -254,6 +444,7 @@ static ssize_t
dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count) dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count)
{ {
struct dcssblk_dev_info *dev_info; struct dcssblk_dev_info *dev_info;
struct segment_info *entry;
if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0'))
return -EINVAL; return -EINVAL;
@ -263,14 +454,16 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
if (inbuf[0] == '1') { if (inbuf[0] == '1') {
if (atomic_read(&dev_info->use_count) == 0) { if (atomic_read(&dev_info->use_count) == 0) {
// device is idle => we save immediately // device is idle => we save immediately
PRINT_INFO("Saving segment %s\n", PRINT_INFO("Saving segment(s) of the device %s\n",
dev_info->segment_name); dev_info->segment_name);
segment_save(dev_info->segment_name); list_for_each_entry(entry, &dev_info->seg_list, lh) {
segment_save(entry->segment_name);
}
} else { } else {
// device is busy => we save it when it becomes // device is busy => we save it when it becomes
// idle in dcssblk_release // idle in dcssblk_release
PRINT_INFO("Segment %s is currently busy, it will " PRINT_INFO("Device %s is currently busy, segment(s) "
"be saved when it becomes idle...\n", "will be saved when it becomes idle...\n",
dev_info->segment_name); dev_info->segment_name);
dev_info->save_pending = 1; dev_info->save_pending = 1;
} }
@ -279,7 +472,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
// device is busy & the user wants to undo his save // device is busy & the user wants to undo his save
// request // request
dev_info->save_pending = 0; dev_info->save_pending = 0;
PRINT_INFO("Pending save for segment %s deactivated\n", PRINT_INFO("Pending save for segment(s) of the device "
"%s deactivated\n",
dev_info->segment_name); dev_info->segment_name);
} }
} else { } else {
@ -290,67 +484,124 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
return count; return count;
} }
/*
* device attribute for showing all segments in a device
*/
static ssize_t
dcssblk_seglist_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
int i;
struct dcssblk_dev_info *dev_info;
struct segment_info *entry;
down_read(&dcssblk_devices_sem);
dev_info = container_of(dev, struct dcssblk_dev_info, dev);
i = 0;
buf[0] = '\0';
list_for_each_entry(entry, &dev_info->seg_list, lh) {
strcpy(&buf[i], entry->segment_name);
i += strlen(entry->segment_name);
buf[i] = '\n';
i++;
}
up_read(&dcssblk_devices_sem);
return i;
}
/* /*
* device attribute for adding devices * device attribute for adding devices
*/ */
static ssize_t static ssize_t
dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
int rc, i; int rc, i, j, num_of_segments;
struct dcssblk_dev_info *dev_info; struct dcssblk_dev_info *dev_info;
struct segment_info *seg_info, *temp;
char *local_buf; char *local_buf;
unsigned long seg_byte_size; unsigned long seg_byte_size;
dev_info = NULL; dev_info = NULL;
seg_info = NULL;
if (dev != dcssblk_root_dev) { if (dev != dcssblk_root_dev) {
rc = -EINVAL; rc = -EINVAL;
goto out_nobuf; goto out_nobuf;
} }
if ((count < 1) || (buf[0] == '\0') || (buf[0] == '\n')) {
rc = -ENAMETOOLONG;
goto out_nobuf;
}
local_buf = kmalloc(count + 1, GFP_KERNEL); local_buf = kmalloc(count + 1, GFP_KERNEL);
if (local_buf == NULL) { if (local_buf == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto out_nobuf; goto out_nobuf;
} }
/* /*
* parse input * parse input
*/ */
num_of_segments = 0;
for (i = 0; ((buf[i] != '\0') && (buf[i] != '\n') && i < count); i++) { for (i = 0; ((buf[i] != '\0') && (buf[i] != '\n') && i < count); i++) {
local_buf[i] = toupper(buf[i]); for (j = i; (buf[j] != ':') &&
} (buf[j] != '\0') &&
local_buf[i] = '\0'; (buf[j] != '\n') &&
if ((i == 0) || (i > 8)) { j < count; j++) {
rc = -ENAMETOOLONG; local_buf[j-i] = toupper(buf[j]);
goto out; }
} local_buf[j-i] = '\0';
/* if (((j - i) == 0) || ((j - i) > 8)) {
* already loaded? rc = -ENAMETOOLONG;
*/ goto seg_list_del;
down_read(&dcssblk_devices_sem); }
dev_info = dcssblk_get_device_by_name(local_buf);
up_read(&dcssblk_devices_sem); rc = dcssblk_load_segment(local_buf, &seg_info);
if (dev_info != NULL) { if (rc < 0)
PRINT_WARN("Segment %s already loaded!\n", local_buf); goto seg_list_del;
rc = -EEXIST; /*
goto out; * get a struct dcssblk_dev_info
} */
/* if (num_of_segments == 0) {
* get a struct dcssblk_dev_info dev_info = kzalloc(sizeof(struct dcssblk_dev_info),
*/ GFP_KERNEL);
dev_info = kzalloc(sizeof(struct dcssblk_dev_info), GFP_KERNEL); if (dev_info == NULL) {
if (dev_info == NULL) { rc = -ENOMEM;
rc = -ENOMEM; goto out;
goto out; }
strcpy(dev_info->segment_name, local_buf);
dev_info->segment_type = seg_info->segment_type;
INIT_LIST_HEAD(&dev_info->seg_list);
}
list_add_tail(&seg_info->lh, &dev_info->seg_list);
num_of_segments++;
i = j;
if ((buf[j] == '\0') || (buf[j] == '\n'))
break;
} }
strcpy(dev_info->segment_name, local_buf); /* no trailing colon at the end of the input */
strlcpy(dev_info->dev.bus_id, local_buf, BUS_ID_SIZE); if ((i > 0) && (buf[i-1] == ':')) {
rc = -ENAMETOOLONG;
goto seg_list_del;
}
strlcpy(local_buf, buf, i + 1);
dev_info->num_of_segments = num_of_segments;
rc = dcssblk_is_continuous(dev_info);
if (rc < 0)
goto seg_list_del;
dev_info->start = dcssblk_find_lowest_addr(dev_info);
dev_info->end = dcssblk_find_highest_addr(dev_info);
dev_set_name(&dev_info->dev, dev_info->segment_name);
dev_info->dev.release = dcssblk_release_segment; dev_info->dev.release = dcssblk_release_segment;
INIT_LIST_HEAD(&dev_info->lh); INIT_LIST_HEAD(&dev_info->lh);
dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK); dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK);
if (dev_info->gd == NULL) { if (dev_info->gd == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto free_dev_info; goto seg_list_del;
} }
dev_info->gd->major = dcssblk_major; dev_info->gd->major = dcssblk_major;
dev_info->gd->fops = &dcssblk_devops; dev_info->gd->fops = &dcssblk_devops;
@ -360,65 +611,52 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
dev_info->gd->driverfs_dev = &dev_info->dev; dev_info->gd->driverfs_dev = &dev_info->dev;
blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request); blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request);
blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096); blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096);
/*
* load the segment
*/
rc = segment_load(local_buf, SEGMENT_SHARED,
&dev_info->start, &dev_info->end);
if (rc < 0) {
segment_warning(rc, dev_info->segment_name);
goto dealloc_gendisk;
}
seg_byte_size = (dev_info->end - dev_info->start + 1); seg_byte_size = (dev_info->end - dev_info->start + 1);
set_capacity(dev_info->gd, seg_byte_size >> 9); // size in sectors set_capacity(dev_info->gd, seg_byte_size >> 9); // size in sectors
PRINT_INFO("Loaded segment %s, size = %lu Byte, " PRINT_INFO("Loaded segment(s) %s, size = %lu Byte, "
"capacity = %lu (512 Byte) sectors\n", local_buf, "capacity = %lu (512 Byte) sectors\n", local_buf,
seg_byte_size, seg_byte_size >> 9); seg_byte_size, seg_byte_size >> 9);
dev_info->segment_type = rc;
dev_info->save_pending = 0; dev_info->save_pending = 0;
dev_info->is_shared = 1; dev_info->is_shared = 1;
dev_info->dev.parent = dcssblk_root_dev; dev_info->dev.parent = dcssblk_root_dev;
/* /*
* get minor, add to list *get minor, add to list
*/ */
down_write(&dcssblk_devices_sem); down_write(&dcssblk_devices_sem);
if (dcssblk_get_device_by_name(local_buf)) { if (dcssblk_get_segment_by_name(local_buf)) {
up_write(&dcssblk_devices_sem);
rc = -EEXIST; rc = -EEXIST;
goto unload_seg; goto release_gd;
} }
rc = dcssblk_assign_free_minor(dev_info); rc = dcssblk_assign_free_minor(dev_info);
if (rc) { if (rc)
up_write(&dcssblk_devices_sem); goto release_gd;
PRINT_ERR("No free minor number available! "
"Unloading segment...\n");
goto unload_seg;
}
sprintf(dev_info->gd->disk_name, "dcssblk%d", sprintf(dev_info->gd->disk_name, "dcssblk%d",
MINOR(disk_devt(dev_info->gd))); MINOR(disk_devt(dev_info->gd)));
list_add_tail(&dev_info->lh, &dcssblk_devices); list_add_tail(&dev_info->lh, &dcssblk_devices);
if (!try_module_get(THIS_MODULE)) { if (!try_module_get(THIS_MODULE)) {
rc = -ENODEV; rc = -ENODEV;
goto list_del; goto dev_list_del;
} }
/* /*
* register the device * register the device
*/ */
rc = device_register(&dev_info->dev); rc = device_register(&dev_info->dev);
if (rc) { if (rc) {
PRINT_ERR("Segment %s could not be registered RC=%d\n",
local_buf, rc);
module_put(THIS_MODULE); module_put(THIS_MODULE);
goto list_del; goto dev_list_del;
} }
get_device(&dev_info->dev); get_device(&dev_info->dev);
rc = device_create_file(&dev_info->dev, &dev_attr_shared); rc = device_create_file(&dev_info->dev, &dev_attr_shared);
if (rc) if (rc)
goto unregister_dev; goto unregister_dev;
rc = device_create_file(&dev_info->dev, &dev_attr_save); rc = device_create_file(&dev_info->dev, &dev_attr_save);
if (rc)
goto unregister_dev;
rc = device_create_file(&dev_info->dev, &dev_attr_seglist);
if (rc) if (rc)
goto unregister_dev; goto unregister_dev;
@ -434,7 +672,6 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
set_disk_ro(dev_info->gd,0); set_disk_ro(dev_info->gd,0);
break; break;
} }
PRINT_DEBUG("Segment %s loaded successfully\n", local_buf);
up_write(&dcssblk_devices_sem); up_write(&dcssblk_devices_sem);
rc = count; rc = count;
goto out; goto out;
@ -445,20 +682,27 @@ unregister_dev:
dev_info->gd->queue = NULL; dev_info->gd->queue = NULL;
put_disk(dev_info->gd); put_disk(dev_info->gd);
device_unregister(&dev_info->dev); device_unregister(&dev_info->dev);
segment_unload(dev_info->segment_name); list_for_each_entry(seg_info, &dev_info->seg_list, lh) {
segment_unload(seg_info->segment_name);
}
put_device(&dev_info->dev); put_device(&dev_info->dev);
up_write(&dcssblk_devices_sem); up_write(&dcssblk_devices_sem);
goto out; goto out;
list_del: dev_list_del:
list_del(&dev_info->lh); list_del(&dev_info->lh);
up_write(&dcssblk_devices_sem); release_gd:
unload_seg:
segment_unload(local_buf);
dealloc_gendisk:
blk_cleanup_queue(dev_info->dcssblk_queue); blk_cleanup_queue(dev_info->dcssblk_queue);
dev_info->gd->queue = NULL; dev_info->gd->queue = NULL;
put_disk(dev_info->gd); put_disk(dev_info->gd);
free_dev_info: up_write(&dcssblk_devices_sem);
seg_list_del:
if (dev_info == NULL)
goto out;
list_for_each_entry_safe(seg_info, temp, &dev_info->seg_list, lh) {
list_del(&seg_info->lh);
segment_unload(seg_info->segment_name);
kfree(seg_info);
}
kfree(dev_info); kfree(dev_info);
out: out:
kfree(local_buf); kfree(local_buf);
@ -473,6 +717,7 @@ static ssize_t
dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct dcssblk_dev_info *dev_info; struct dcssblk_dev_info *dev_info;
struct segment_info *entry;
int rc, i; int rc, i;
char *local_buf; char *local_buf;
@ -499,26 +744,28 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch
dev_info = dcssblk_get_device_by_name(local_buf); dev_info = dcssblk_get_device_by_name(local_buf);
if (dev_info == NULL) { if (dev_info == NULL) {
up_write(&dcssblk_devices_sem); up_write(&dcssblk_devices_sem);
PRINT_WARN("Segment %s is not loaded!\n", local_buf); PRINT_WARN("Device %s is not loaded!\n", local_buf);
rc = -ENODEV; rc = -ENODEV;
goto out_buf; goto out_buf;
} }
if (atomic_read(&dev_info->use_count) != 0) { if (atomic_read(&dev_info->use_count) != 0) {
up_write(&dcssblk_devices_sem); up_write(&dcssblk_devices_sem);
PRINT_WARN("Segment %s is in use!\n", local_buf); PRINT_WARN("Device %s is in use!\n", local_buf);
rc = -EBUSY; rc = -EBUSY;
goto out_buf; goto out_buf;
} }
list_del(&dev_info->lh);
list_del(&dev_info->lh);
del_gendisk(dev_info->gd); del_gendisk(dev_info->gd);
blk_cleanup_queue(dev_info->dcssblk_queue); blk_cleanup_queue(dev_info->dcssblk_queue);
dev_info->gd->queue = NULL; dev_info->gd->queue = NULL;
put_disk(dev_info->gd); put_disk(dev_info->gd);
device_unregister(&dev_info->dev); device_unregister(&dev_info->dev);
segment_unload(dev_info->segment_name);
PRINT_DEBUG("Segment %s unloaded successfully\n", /* unload all related segments */
dev_info->segment_name); list_for_each_entry(entry, &dev_info->seg_list, lh)
segment_unload(entry->segment_name);
put_device(&dev_info->dev); put_device(&dev_info->dev);
up_write(&dcssblk_devices_sem); up_write(&dcssblk_devices_sem);
@ -550,6 +797,7 @@ static int
dcssblk_release(struct inode *inode, struct file *filp) dcssblk_release(struct inode *inode, struct file *filp)
{ {
struct dcssblk_dev_info *dev_info; struct dcssblk_dev_info *dev_info;
struct segment_info *entry;
int rc; int rc;
dev_info = inode->i_bdev->bd_disk->private_data; dev_info = inode->i_bdev->bd_disk->private_data;
@ -560,9 +808,11 @@ dcssblk_release(struct inode *inode, struct file *filp)
down_write(&dcssblk_devices_sem); down_write(&dcssblk_devices_sem);
if (atomic_dec_and_test(&dev_info->use_count) if (atomic_dec_and_test(&dev_info->use_count)
&& (dev_info->save_pending)) { && (dev_info->save_pending)) {
PRINT_INFO("Segment %s became idle and is being saved now\n", PRINT_INFO("Device %s became idle and is being saved now\n",
dev_info->segment_name); dev_info->segment_name);
segment_save(dev_info->segment_name); list_for_each_entry(entry, &dev_info->seg_list, lh) {
segment_save(entry->segment_name);
}
dev_info->save_pending = 0; dev_info->save_pending = 0;
} }
up_write(&dcssblk_devices_sem); up_write(&dcssblk_devices_sem);
@ -602,7 +852,8 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
case SEG_TYPE_SC: case SEG_TYPE_SC:
/* cannot write to these segments */ /* cannot write to these segments */
if (bio_data_dir(bio) == WRITE) { if (bio_data_dir(bio) == WRITE) {
PRINT_WARN("rejecting write to ro segment %s\n", dev_info->dev.bus_id); PRINT_WARN("rejecting write to ro device %s\n",
dev_name(&dev_info->dev));
goto fail; goto fail;
} }
} }
@ -657,7 +908,7 @@ static void
dcssblk_check_params(void) dcssblk_check_params(void)
{ {
int rc, i, j, k; int rc, i, j, k;
char buf[9]; char buf[DCSSBLK_PARM_LEN + 1];
struct dcssblk_dev_info *dev_info; struct dcssblk_dev_info *dev_info;
for (i = 0; (i < DCSSBLK_PARM_LEN) && (dcssblk_segments[i] != '\0'); for (i = 0; (i < DCSSBLK_PARM_LEN) && (dcssblk_segments[i] != '\0');
@ -665,15 +916,16 @@ dcssblk_check_params(void)
for (j = i; (dcssblk_segments[j] != ',') && for (j = i; (dcssblk_segments[j] != ',') &&
(dcssblk_segments[j] != '\0') && (dcssblk_segments[j] != '\0') &&
(dcssblk_segments[j] != '(') && (dcssblk_segments[j] != '(') &&
(j - i) < 8; j++) (j < DCSSBLK_PARM_LEN); j++)
{ {
buf[j-i] = dcssblk_segments[j]; buf[j-i] = dcssblk_segments[j];
} }
buf[j-i] = '\0'; buf[j-i] = '\0';
rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i); rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i);
if ((rc >= 0) && (dcssblk_segments[j] == '(')) { if ((rc >= 0) && (dcssblk_segments[j] == '(')) {
for (k = 0; buf[k] != '\0'; k++) for (k = 0; (buf[k] != ':') && (buf[k] != '\0'); k++)
buf[k] = toupper(buf[k]); buf[k] = toupper(buf[k]);
buf[k] = '\0';
if (!strncmp(&dcssblk_segments[j], "(local)", 7)) { if (!strncmp(&dcssblk_segments[j], "(local)", 7)) {
down_read(&dcssblk_devices_sem); down_read(&dcssblk_devices_sem);
dev_info = dcssblk_get_device_by_name(buf); dev_info = dcssblk_get_device_by_name(buf);
@ -740,10 +992,12 @@ module_exit(dcssblk_exit);
module_param_string(segments, dcssblk_segments, DCSSBLK_PARM_LEN, 0444); module_param_string(segments, dcssblk_segments, DCSSBLK_PARM_LEN, 0444);
MODULE_PARM_DESC(segments, "Name of DCSS segment(s) to be loaded, " MODULE_PARM_DESC(segments, "Name of DCSS segment(s) to be loaded, "
"comma-separated list, each name max. 8 chars.\n" "comma-separated list, names in each set separated "
"Adding \"(local)\" to segment name equals echoing 0 to " "by commas are separated by colons, each set contains "
"/sys/devices/dcssblk/<segment name>/shared after loading " "names of contiguous segments and each name max. 8 chars.\n"
"the segment - \n" "Adding \"(local)\" to the end of each set equals echoing 0 "
"e.g. segments=\"mydcss1,mydcss2,mydcss3(local)\""); "to /sys/devices/dcssblk/<device name>/shared after loading "
"the contiguous segments - \n"
"e.g. segments=\"mydcss1,mydcss2:mydcss3,mydcss4(local)\"");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View file

@ -56,6 +56,7 @@ typedef struct {
static xpram_device_t xpram_devices[XPRAM_MAX_DEVS]; static xpram_device_t xpram_devices[XPRAM_MAX_DEVS];
static unsigned int xpram_sizes[XPRAM_MAX_DEVS]; static unsigned int xpram_sizes[XPRAM_MAX_DEVS];
static struct gendisk *xpram_disks[XPRAM_MAX_DEVS]; static struct gendisk *xpram_disks[XPRAM_MAX_DEVS];
static struct request_queue *xpram_queues[XPRAM_MAX_DEVS];
static unsigned int xpram_pages; static unsigned int xpram_pages;
static int xpram_devs; static int xpram_devs;
@ -330,18 +331,22 @@ static int __init xpram_setup_sizes(unsigned long pages)
return 0; return 0;
} }
static struct request_queue *xpram_queue;
static int __init xpram_setup_blkdev(void) static int __init xpram_setup_blkdev(void)
{ {
unsigned long offset; unsigned long offset;
int i, rc = -ENOMEM; int i, rc = -ENOMEM;
for (i = 0; i < xpram_devs; i++) { for (i = 0; i < xpram_devs; i++) {
struct gendisk *disk = alloc_disk(1); xpram_disks[i] = alloc_disk(1);
if (!disk) if (!xpram_disks[i])
goto out; goto out;
xpram_disks[i] = disk; xpram_queues[i] = blk_alloc_queue(GFP_KERNEL);
if (!xpram_queues[i]) {
put_disk(xpram_disks[i]);
goto out;
}
blk_queue_make_request(xpram_queues[i], xpram_make_request);
blk_queue_hardsect_size(xpram_queues[i], 4096);
} }
/* /*
@ -351,18 +356,6 @@ static int __init xpram_setup_blkdev(void)
if (rc < 0) if (rc < 0)
goto out; goto out;
/*
* Assign the other needed values: make request function, sizes and
* hardsect size. All the minor devices feature the same value.
*/
xpram_queue = blk_alloc_queue(GFP_KERNEL);
if (!xpram_queue) {
rc = -ENOMEM;
goto out_unreg;
}
blk_queue_make_request(xpram_queue, xpram_make_request);
blk_queue_hardsect_size(xpram_queue, 4096);
/* /*
* Setup device structures. * Setup device structures.
*/ */
@ -377,18 +370,18 @@ static int __init xpram_setup_blkdev(void)
disk->first_minor = i; disk->first_minor = i;
disk->fops = &xpram_devops; disk->fops = &xpram_devops;
disk->private_data = &xpram_devices[i]; disk->private_data = &xpram_devices[i];
disk->queue = xpram_queue; disk->queue = xpram_queues[i];
sprintf(disk->disk_name, "slram%d", i); sprintf(disk->disk_name, "slram%d", i);
set_capacity(disk, xpram_sizes[i] << 1); set_capacity(disk, xpram_sizes[i] << 1);
add_disk(disk); add_disk(disk);
} }
return 0; return 0;
out_unreg:
unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
out: out:
while (i--) while (i--) {
blk_cleanup_queue(xpram_queues[i]);
put_disk(xpram_disks[i]); put_disk(xpram_disks[i]);
}
return rc; return rc;
} }
@ -400,10 +393,10 @@ static void __exit xpram_exit(void)
int i; int i;
for (i = 0; i < xpram_devs; i++) { for (i = 0; i < xpram_devs; i++) {
del_gendisk(xpram_disks[i]); del_gendisk(xpram_disks[i]);
blk_cleanup_queue(xpram_queues[i]);
put_disk(xpram_disks[i]); put_disk(xpram_disks[i]);
} }
unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
blk_cleanup_queue(xpram_queue);
} }
static int __init xpram_init(void) static int __init xpram_init(void)

View file

@ -21,6 +21,7 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/reboot.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
@ -88,7 +89,6 @@ struct raw3215_info {
int count; /* number of bytes in output buffer */ int count; /* number of bytes in output buffer */
int written; /* number of bytes in write requests */ int written; /* number of bytes in write requests */
struct tty_struct *tty; /* pointer to tty structure if present */ struct tty_struct *tty; /* pointer to tty structure if present */
struct tasklet_struct tasklet;
struct raw3215_req *queued_read; /* pointer to queued read requests */ struct raw3215_req *queued_read; /* pointer to queued read requests */
struct raw3215_req *queued_write;/* pointer to queued write requests */ struct raw3215_req *queued_write;/* pointer to queued write requests */
wait_queue_head_t empty_wait; /* wait queue for flushing */ wait_queue_head_t empty_wait; /* wait queue for flushing */
@ -341,21 +341,14 @@ raw3215_try_io(struct raw3215_info *raw)
} }
/* /*
* The bottom half handler routine for 3215 devices. It tries to start * Try to start the next IO and wake up processes waiting on the tty.
* the next IO and wakes up processes waiting on the tty.
*/ */
static void static void raw3215_next_io(struct raw3215_info *raw)
raw3215_tasklet(void *data)
{ {
struct raw3215_info *raw;
struct tty_struct *tty; struct tty_struct *tty;
unsigned long flags;
raw = (struct raw3215_info *) data;
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_mk_write_req(raw); raw3215_mk_write_req(raw);
raw3215_try_io(raw); raw3215_try_io(raw);
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
tty = raw->tty; tty = raw->tty;
if (tty != NULL && if (tty != NULL &&
RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
@ -380,7 +373,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
cstat = irb->scsw.cmd.cstat; cstat = irb->scsw.cmd.cstat;
dstat = irb->scsw.cmd.dstat; dstat = irb->scsw.cmd.dstat;
if (cstat != 0) if (cstat != 0)
tasklet_schedule(&raw->tasklet); raw3215_next_io(raw);
if (dstat & 0x01) { /* we got a unit exception */ if (dstat & 0x01) { /* we got a unit exception */
dstat &= ~0x01; /* we can ignore it */ dstat &= ~0x01; /* we can ignore it */
} }
@ -390,7 +383,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
break; break;
/* Attention interrupt, someone hit the enter key */ /* Attention interrupt, someone hit the enter key */
raw3215_mk_read_req(raw); raw3215_mk_read_req(raw);
tasklet_schedule(&raw->tasklet); raw3215_next_io(raw);
break; break;
case 0x08: case 0x08:
case 0x0C: case 0x0C:
@ -448,7 +441,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
raw->queued_read == NULL) { raw->queued_read == NULL) {
wake_up_interruptible(&raw->empty_wait); wake_up_interruptible(&raw->empty_wait);
} }
tasklet_schedule(&raw->tasklet); raw3215_next_io(raw);
break; break;
default: default:
/* Strange interrupt, I'll do my best to clean up */ /* Strange interrupt, I'll do my best to clean up */
@ -460,7 +453,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
raw->flags &= ~RAW3215_WORKING; raw->flags &= ~RAW3215_WORKING;
raw3215_free_req(req); raw3215_free_req(req);
} }
tasklet_schedule(&raw->tasklet); raw3215_next_io(raw);
} }
return; return;
} }
@ -674,9 +667,6 @@ raw3215_probe (struct ccw_device *cdev)
kfree(raw); kfree(raw);
return -ENOMEM; return -ENOMEM;
} }
tasklet_init(&raw->tasklet,
(void (*)(unsigned long)) raw3215_tasklet,
(unsigned long) raw);
init_waitqueue_head(&raw->empty_wait); init_waitqueue_head(&raw->empty_wait);
cdev->dev.driver_data = raw; cdev->dev.driver_data = raw;
@ -775,11 +765,11 @@ static struct tty_driver *con3215_device(struct console *c, int *index)
} }
/* /*
* panic() calls console_unblank before the system enters a * panic() calls con3215_flush through a panic_notifier
* disabled, endless loop. * before the system enters a disabled, endless loop.
*/ */
static void static void
con3215_unblank(void) con3215_flush(void)
{ {
struct raw3215_info *raw; struct raw3215_info *raw;
unsigned long flags; unsigned long flags;
@ -790,6 +780,23 @@ con3215_unblank(void)
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
} }
static int con3215_notify(struct notifier_block *self,
unsigned long event, void *data)
{
con3215_flush();
return NOTIFY_OK;
}
static struct notifier_block on_panic_nb = {
.notifier_call = con3215_notify,
.priority = 0,
};
static struct notifier_block on_reboot_nb = {
.notifier_call = con3215_notify,
.priority = 0,
};
/* /*
* The console structure for the 3215 console * The console structure for the 3215 console
*/ */
@ -797,7 +804,6 @@ static struct console con3215 = {
.name = "ttyS", .name = "ttyS",
.write = con3215_write, .write = con3215_write,
.device = con3215_device, .device = con3215_device,
.unblank = con3215_unblank,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
}; };
@ -846,9 +852,6 @@ con3215_init(void)
cdev->handler = raw3215_irq; cdev->handler = raw3215_irq;
raw->flags |= RAW3215_FIXED; raw->flags |= RAW3215_FIXED;
tasklet_init(&raw->tasklet,
(void (*)(unsigned long)) raw3215_tasklet,
(unsigned long) raw);
init_waitqueue_head(&raw->empty_wait); init_waitqueue_head(&raw->empty_wait);
/* Request the console irq */ /* Request the console irq */
@ -859,6 +862,8 @@ con3215_init(void)
raw3215[0] = NULL; raw3215[0] = NULL;
return -ENODEV; return -ENODEV;
} }
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
register_reboot_notifier(&on_reboot_nb);
register_console(&con3215); register_console(&con3215);
return 0; return 0;
} }

View file

@ -15,6 +15,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/reboot.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#include <asm/cio.h> #include <asm/cio.h>
@ -528,11 +529,11 @@ con3270_wait_write(struct con3270 *cp)
} }
/* /*
* panic() calls console_unblank before the system enters a * panic() calls con3270_flush through a panic_notifier
* disabled, endless loop. * before the system enters a disabled, endless loop.
*/ */
static void static void
con3270_unblank(void) con3270_flush(void)
{ {
struct con3270 *cp; struct con3270 *cp;
unsigned long flags; unsigned long flags;
@ -554,6 +555,23 @@ con3270_unblank(void)
spin_unlock_irqrestore(&cp->view.lock, flags); spin_unlock_irqrestore(&cp->view.lock, flags);
} }
static int con3270_notify(struct notifier_block *self,
unsigned long event, void *data)
{
con3270_flush();
return NOTIFY_OK;
}
static struct notifier_block on_panic_nb = {
.notifier_call = con3270_notify,
.priority = 0,
};
static struct notifier_block on_reboot_nb = {
.notifier_call = con3270_notify,
.priority = 0,
};
/* /*
* The console structure for the 3270 console * The console structure for the 3270 console
*/ */
@ -561,7 +579,6 @@ static struct console con3270 = {
.name = "tty3270", .name = "tty3270",
.write = con3270_write, .write = con3270_write,
.device = con3270_device, .device = con3270_device,
.unblank = con3270_unblank,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
}; };
@ -623,6 +640,8 @@ con3270_init(void)
condev->cline->len = 0; condev->cline->len = 0;
con3270_create_status(condev); con3270_create_status(condev);
condev->input = alloc_string(&condev->freemem, 80); condev->input = alloc_string(&condev->freemem, 80);
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
register_reboot_notifier(&on_reboot_nb);
register_console(&con3270); register_console(&con3270);
return 0; return 0;
} }

View file

@ -1171,7 +1171,7 @@ static int raw3270_create_attributes(struct raw3270 *rp)
rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev, rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev,
MKDEV(IBM_TTY3270_MAJOR, rp->minor), MKDEV(IBM_TTY3270_MAJOR, rp->minor),
NULL, NULL,
"tty%s", rp->cdev->dev.bus_id); "tty%s", dev_name(&rp->cdev->dev));
if (IS_ERR(rp->clttydev)) { if (IS_ERR(rp->clttydev)) {
rc = PTR_ERR(rp->clttydev); rc = PTR_ERR(rp->clttydev);
goto out_ttydev; goto out_ttydev;
@ -1180,7 +1180,7 @@ static int raw3270_create_attributes(struct raw3270 *rp)
rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev, rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev,
MKDEV(IBM_FS3270_MAJOR, rp->minor), MKDEV(IBM_FS3270_MAJOR, rp->minor),
NULL, NULL,
"tub%s", rp->cdev->dev.bus_id); "tub%s", dev_name(&rp->cdev->dev));
if (!IS_ERR(rp->cltubdev)) if (!IS_ERR(rp->cltubdev))
goto out; goto out;

View file

@ -16,6 +16,7 @@
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/termios.h> #include <linux/termios.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/reboot.h>
#include "sclp.h" #include "sclp.h"
#include "sclp_rw.h" #include "sclp_rw.h"
@ -172,7 +173,7 @@ sclp_console_device(struct console *c, int *index)
* will be flushed to the SCLP. * will be flushed to the SCLP.
*/ */
static void static void
sclp_console_unblank(void) sclp_console_flush(void)
{ {
unsigned long flags; unsigned long flags;
@ -188,6 +189,24 @@ sclp_console_unblank(void)
spin_unlock_irqrestore(&sclp_con_lock, flags); spin_unlock_irqrestore(&sclp_con_lock, flags);
} }
static int
sclp_console_notify(struct notifier_block *self,
unsigned long event, void *data)
{
sclp_console_flush();
return NOTIFY_OK;
}
static struct notifier_block on_panic_nb = {
.notifier_call = sclp_console_notify,
.priority = 1,
};
static struct notifier_block on_reboot_nb = {
.notifier_call = sclp_console_notify,
.priority = 1,
};
/* /*
* used to register the SCLP console to the kernel and to * used to register the SCLP console to the kernel and to
* give printk necessary information * give printk necessary information
@ -197,7 +216,6 @@ static struct console sclp_console =
.name = sclp_console_name, .name = sclp_console_name,
.write = sclp_console_write, .write = sclp_console_write,
.device = sclp_console_device, .device = sclp_console_device,
.unblank = sclp_console_unblank,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
.index = 0 /* ttyS0 */ .index = 0 /* ttyS0 */
}; };
@ -241,6 +259,8 @@ sclp_console_init(void)
sclp_con_width_htab = 8; sclp_con_width_htab = 8;
/* enable printk-access to this driver */ /* enable printk-access to this driver */
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
register_reboot_notifier(&on_reboot_nb);
register_console(&sclp_console); register_console(&sclp_console);
return 0; return 0;
} }

View file

@ -24,6 +24,8 @@
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/reboot.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "sclp.h" #include "sclp.h"
@ -743,24 +745,30 @@ sclp_vt220_con_device(struct console *c, int *index)
return sclp_vt220_driver; return sclp_vt220_driver;
} }
/* static int
* This routine is called from panic when the kernel is going to give up. sclp_vt220_notify(struct notifier_block *self,
* We have to make sure that all buffers will be flushed to the SCLP. unsigned long event, void *data)
* Note that this function may be called from within an interrupt context.
*/
static void
sclp_vt220_con_unblank(void)
{ {
__sclp_vt220_flush_buffer(); __sclp_vt220_flush_buffer();
return NOTIFY_OK;
} }
static struct notifier_block on_panic_nb = {
.notifier_call = sclp_vt220_notify,
.priority = 1,
};
static struct notifier_block on_reboot_nb = {
.notifier_call = sclp_vt220_notify,
.priority = 1,
};
/* Structure needed to register with printk */ /* Structure needed to register with printk */
static struct console sclp_vt220_console = static struct console sclp_vt220_console =
{ {
.name = SCLP_VT220_CONSOLE_NAME, .name = SCLP_VT220_CONSOLE_NAME,
.write = sclp_vt220_con_write, .write = sclp_vt220_con_write,
.device = sclp_vt220_con_device, .device = sclp_vt220_con_device,
.unblank = sclp_vt220_con_unblank,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
.index = SCLP_VT220_CONSOLE_INDEX .index = SCLP_VT220_CONSOLE_INDEX
}; };
@ -776,6 +784,8 @@ sclp_vt220_con_init(void)
if (rc) if (rc)
return rc; return rc;
/* Attach linux console */ /* Attach linux console */
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
register_reboot_notifier(&on_reboot_nb);
register_console(&sclp_vt220_console); register_console(&sclp_vt220_console);
return 0; return 0;
} }

View file

@ -910,7 +910,7 @@ tape_3590_erp_swap(struct tape_device *device, struct tape_request *request,
* should proceed with the new tape... this * should proceed with the new tape... this
* should probably be done in user space! * should probably be done in user space!
*/ */
PRINT_WARN("(%s): Swap Tape Device!\n", device->cdev->dev.bus_id); PRINT_WARN("(%s): Swap Tape Device!\n", dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EIO); return tape_3590_erp_basic(device, request, irb, -EIO);
} }
@ -1003,40 +1003,43 @@ tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
/* Exception Message */ /* Exception Message */
switch (sense->fmt.f70.emc) { switch (sense->fmt.f70.emc) {
case 0x02: case 0x02:
PRINT_WARN("(%s): Data degraded\n", device->cdev->dev.bus_id); PRINT_WARN("(%s): Data degraded\n",
dev_name(&device->cdev->dev));
break; break;
case 0x03: case 0x03:
PRINT_WARN("(%s): Data degraded in partion %i\n", PRINT_WARN("(%s): Data degraded in partion %i\n",
device->cdev->dev.bus_id, sense->fmt.f70.mp); dev_name(&device->cdev->dev), sense->fmt.f70.mp);
break; break;
case 0x04: case 0x04:
PRINT_WARN("(%s): Medium degraded\n", device->cdev->dev.bus_id); PRINT_WARN("(%s): Medium degraded\n",
dev_name(&device->cdev->dev));
break; break;
case 0x05: case 0x05:
PRINT_WARN("(%s): Medium degraded in partition %i\n", PRINT_WARN("(%s): Medium degraded in partition %i\n",
device->cdev->dev.bus_id, sense->fmt.f70.mp); dev_name(&device->cdev->dev), sense->fmt.f70.mp);
break; break;
case 0x06: case 0x06:
PRINT_WARN("(%s): Block 0 Error\n", device->cdev->dev.bus_id); PRINT_WARN("(%s): Block 0 Error\n",
dev_name(&device->cdev->dev));
break; break;
case 0x07: case 0x07:
PRINT_WARN("(%s): Medium Exception 0x%02x\n", PRINT_WARN("(%s): Medium Exception 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f70.md); dev_name(&device->cdev->dev), sense->fmt.f70.md);
break; break;
default: default:
PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n", PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f70.emc); dev_name(&device->cdev->dev), sense->fmt.f70.emc);
break; break;
} }
/* Service Message */ /* Service Message */
switch (sense->fmt.f70.smc) { switch (sense->fmt.f70.smc) {
case 0x02: case 0x02:
PRINT_WARN("(%s): Reference Media maintenance procedure %i\n", PRINT_WARN("(%s): Reference Media maintenance procedure %i\n",
device->cdev->dev.bus_id, sense->fmt.f70.md); dev_name(&device->cdev->dev), sense->fmt.f70.md);
break; break;
default: default:
PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n", PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f70.smc); dev_name(&device->cdev->dev), sense->fmt.f70.smc);
break; break;
} }
} }
@ -1054,101 +1057,101 @@ tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
switch (sense->fmt.f71.emc) { switch (sense->fmt.f71.emc) {
case 0x01: case 0x01:
PRINT_WARN("(%s): Effect of failure is unknown\n", PRINT_WARN("(%s): Effect of failure is unknown\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x02: case 0x02:
PRINT_WARN("(%s): CU Exception - no performance impact\n", PRINT_WARN("(%s): CU Exception - no performance impact\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x03: case 0x03:
PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n", PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x04: case 0x04:
PRINT_WARN("(%s): CU Exception on device path 0x%02x\n", PRINT_WARN("(%s): CU Exception on device path 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x05: case 0x05:
PRINT_WARN("(%s): CU Exception on library path 0x%02x\n", PRINT_WARN("(%s): CU Exception on library path 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x06: case 0x06:
PRINT_WARN("(%s): CU Exception on node 0x%02x\n", PRINT_WARN("(%s): CU Exception on node 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x07: case 0x07:
PRINT_WARN("(%s): CU Exception on partition 0x%02x\n", PRINT_WARN("(%s): CU Exception on partition 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
default: default:
PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n", PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.emc); dev_name(&device->cdev->dev), sense->fmt.f71.emc);
} }
/* Service Message */ /* Service Message */
switch (sense->fmt.f71.smc) { switch (sense->fmt.f71.smc) {
case 0x01: case 0x01:
PRINT_WARN("(%s): Repair impact is unknown\n", PRINT_WARN("(%s): Repair impact is unknown\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x02: case 0x02:
PRINT_WARN("(%s): Repair will not impact cu performance\n", PRINT_WARN("(%s): Repair will not impact cu performance\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x03: case 0x03:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable node " PRINT_WARN("(%s): Repair will disable node "
"0x%x on CU\n", "0x%x on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable nodes " PRINT_WARN("(%s): Repair will disable nodes "
"(0x%x-0x%x) on CU\n", "(0x%x-0x%x) on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x04: case 0x04:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable cannel path " PRINT_WARN("(%s): Repair will disable cannel path "
"0x%x on CU\n", "0x%x on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable cannel paths " PRINT_WARN("(%s): Repair will disable cannel paths "
"(0x%x-0x%x) on CU\n", "(0x%x-0x%x) on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x05: case 0x05:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable device path " PRINT_WARN("(%s): Repair will disable device path "
"0x%x on CU\n", "0x%x on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable device paths " PRINT_WARN("(%s): Repair will disable device paths "
"(0x%x-0x%x) on CU\n", "(0x%x-0x%x) on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x06: case 0x06:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable library path " PRINT_WARN("(%s): Repair will disable library path "
"0x%x on CU\n", "0x%x on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable library paths " PRINT_WARN("(%s): Repair will disable library paths "
"(0x%x-0x%x) on CU\n", "(0x%x-0x%x) on CU\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x07: case 0x07:
PRINT_WARN("(%s): Repair will disable access to CU\n", PRINT_WARN("(%s): Repair will disable access to CU\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
default: default:
PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n", PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.smc); dev_name(&device->cdev->dev), sense->fmt.f71.smc);
} }
} }
@ -1165,104 +1168,104 @@ tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
switch (sense->fmt.f71.emc) { switch (sense->fmt.f71.emc) {
case 0x01: case 0x01:
PRINT_WARN("(%s): Effect of failure is unknown\n", PRINT_WARN("(%s): Effect of failure is unknown\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x02: case 0x02:
PRINT_WARN("(%s): DV Exception - no performance impact\n", PRINT_WARN("(%s): DV Exception - no performance impact\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x03: case 0x03:
PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n", PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x04: case 0x04:
PRINT_WARN("(%s): DV Exception on loader 0x%02x\n", PRINT_WARN("(%s): DV Exception on loader 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x05: case 0x05:
PRINT_WARN("(%s): DV Exception on message display 0x%02x\n", PRINT_WARN("(%s): DV Exception on message display 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.md[0]); dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
break; break;
case 0x06: case 0x06:
PRINT_WARN("(%s): DV Exception in tape path\n", PRINT_WARN("(%s): DV Exception in tape path\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x07: case 0x07:
PRINT_WARN("(%s): DV Exception in drive\n", PRINT_WARN("(%s): DV Exception in drive\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
default: default:
PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n", PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.emc); dev_name(&device->cdev->dev), sense->fmt.f71.emc);
} }
/* Service Message */ /* Service Message */
switch (sense->fmt.f71.smc) { switch (sense->fmt.f71.smc) {
case 0x01: case 0x01:
PRINT_WARN("(%s): Repair impact is unknown\n", PRINT_WARN("(%s): Repair impact is unknown\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x02: case 0x02:
PRINT_WARN("(%s): Repair will not impact device performance\n", PRINT_WARN("(%s): Repair will not impact device performance\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x03: case 0x03:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable channel path " PRINT_WARN("(%s): Repair will disable channel path "
"0x%x on DV\n", "0x%x on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable channel path " PRINT_WARN("(%s): Repair will disable channel path "
"(0x%x-0x%x) on DV\n", "(0x%x-0x%x) on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x04: case 0x04:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable interface 0x%x " PRINT_WARN("(%s): Repair will disable interface 0x%x "
"on DV\n", "on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable interfaces " PRINT_WARN("(%s): Repair will disable interfaces "
"(0x%x-0x%x) on DV\n", "(0x%x-0x%x) on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x05: case 0x05:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable loader 0x%x " PRINT_WARN("(%s): Repair will disable loader 0x%x "
"on DV\n", "on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable loader " PRINT_WARN("(%s): Repair will disable loader "
"(0x%x-0x%x) on DV\n", "(0x%x-0x%x) on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x07: case 0x07:
PRINT_WARN("(%s): Repair will disable access to DV\n", PRINT_WARN("(%s): Repair will disable access to DV\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case 0x08: case 0x08:
if (sense->fmt.f71.mdf == 0) if (sense->fmt.f71.mdf == 0)
PRINT_WARN("(%s): Repair will disable message " PRINT_WARN("(%s): Repair will disable message "
"display 0x%x on DV\n", "display 0x%x on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1]); sense->fmt.f71.md[1]);
else else
PRINT_WARN("(%s): Repair will disable message " PRINT_WARN("(%s): Repair will disable message "
"displays (0x%x-0x%x) on DV\n", "displays (0x%x-0x%x) on DV\n",
device->cdev->dev.bus_id, dev_name(&device->cdev->dev),
sense->fmt.f71.md[1], sense->fmt.f71.md[2]); sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break; break;
case 0x09: case 0x09:
PRINT_WARN("(%s): Clean DV\n", device->cdev->dev.bus_id); PRINT_WARN("(%s): Clean DV\n", dev_name(&device->cdev->dev));
break; break;
default: default:
PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n", PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n",
device->cdev->dev.bus_id, sense->fmt.f71.smc); dev_name(&device->cdev->dev), sense->fmt.f71.smc);
} }
} }
@ -1279,18 +1282,18 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
return; return;
if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) { if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
if (tape_3590_msg[sense->mc] != NULL) if (tape_3590_msg[sense->mc] != NULL)
PRINT_WARN("(%s): %s\n", device->cdev->dev.bus_id, PRINT_WARN("(%s): %s\n", dev_name(&device->cdev->dev),
tape_3590_msg[sense->mc]); tape_3590_msg[sense->mc]);
else { else {
PRINT_WARN("(%s): Message Code 0x%x\n", PRINT_WARN("(%s): Message Code 0x%x\n",
device->cdev->dev.bus_id, sense->mc); dev_name(&device->cdev->dev), sense->mc);
} }
return; return;
} }
if (sense->mc == 0xf0) { if (sense->mc == 0xf0) {
/* Standard Media Information Message */ /* Standard Media Information Message */
PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, " PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, "
"RC=%02x-%04x-%02x\n", device->cdev->dev.bus_id, "RC=%02x-%04x-%02x\n", dev_name(&device->cdev->dev),
sense->fmt.f70.sev, sense->mc, sense->fmt.f70.sev, sense->mc,
sense->fmt.f70.emc, sense->fmt.f70.smc, sense->fmt.f70.emc, sense->fmt.f70.smc,
sense->fmt.f70.refcode, sense->fmt.f70.mid, sense->fmt.f70.refcode, sense->fmt.f70.mid,
@ -1302,7 +1305,7 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
/* Standard I/O Subsystem Service Information Message */ /* Standard I/O Subsystem Service Information Message */
PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, " PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, "
"MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n", "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
device->cdev->dev.bus_id, sense->fmt.f71.sev, dev_name(&device->cdev->dev), sense->fmt.f71.sev,
device->cdev->id.dev_model, device->cdev->id.dev_model,
sense->mc, sense->fmt.f71.emc, sense->mc, sense->fmt.f71.emc,
sense->fmt.f71.smc, sense->fmt.f71.refcode1, sense->fmt.f71.smc, sense->fmt.f71.refcode1,
@ -1314,7 +1317,7 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
/* Standard Device Service Information Message */ /* Standard Device Service Information Message */
PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, " PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, "
"MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n", "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
device->cdev->dev.bus_id, sense->fmt.f71.sev, dev_name(&device->cdev->dev), sense->fmt.f71.sev,
device->cdev->id.dev_model, device->cdev->id.dev_model,
sense->mc, sense->fmt.f71.emc, sense->mc, sense->fmt.f71.emc,
sense->fmt.f71.smc, sense->fmt.f71.refcode1, sense->fmt.f71.smc, sense->fmt.f71.refcode1,
@ -1327,7 +1330,7 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
return; return;
} }
PRINT_WARN("(%s): Device Message(%x)\n", PRINT_WARN("(%s): Device Message(%x)\n",
device->cdev->dev.bus_id, sense->mc); dev_name(&device->cdev->dev), sense->mc);
} }
static int tape_3590_crypt_error(struct tape_device *device, static int tape_3590_crypt_error(struct tape_device *device,
@ -1336,10 +1339,11 @@ static int tape_3590_crypt_error(struct tape_device *device,
u8 cu_rc, ekm_rc1; u8 cu_rc, ekm_rc1;
u16 ekm_rc2; u16 ekm_rc2;
u32 drv_rc; u32 drv_rc;
char *bus_id, *sense; const char *bus_id;
char *sense;
sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data; sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
bus_id = device->cdev->dev.bus_id; bus_id = dev_name(&device->cdev->dev);
cu_rc = sense[0]; cu_rc = sense[0];
drv_rc = *((u32*) &sense[5]) & 0xffffff; drv_rc = *((u32*) &sense[5]) & 0xffffff;
ekm_rc1 = sense[9]; ekm_rc1 = sense[9];
@ -1440,7 +1444,7 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
* "device intervention" is not very meaningfull * "device intervention" is not very meaningfull
*/ */
PRINT_WARN("(%s): Tape operation when medium not loaded\n", PRINT_WARN("(%s): Tape operation when medium not loaded\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
tape_med_state_set(device, MS_UNLOADED); tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF); tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM); return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
@ -1487,18 +1491,18 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
case 0x6020: case 0x6020:
PRINT_WARN("(%s): Cartridge of wrong type ?\n", PRINT_WARN("(%s): Cartridge of wrong type ?\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE); return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
case 0x8011: case 0x8011:
PRINT_WARN("(%s): Another host has reserved the tape device\n", PRINT_WARN("(%s): Another host has reserved the tape device\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EPERM); return tape_3590_erp_basic(device, request, irb, -EPERM);
case 0x8013: case 0x8013:
PRINT_WARN("(%s): Another host has privileged access to the " PRINT_WARN("(%s): Another host has privileged access to the "
"tape device\n", device->cdev->dev.bus_id); "tape device\n", dev_name(&device->cdev->dev));
PRINT_WARN("(%s): To solve the problem unload the current " PRINT_WARN("(%s): To solve the problem unload the current "
"cartridge!\n", device->cdev->dev.bus_id); "cartridge!\n", dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EPERM); return tape_3590_erp_basic(device, request, irb, -EPERM);
default: default:
return tape_3590_erp_basic(device, request, irb, -EIO); return tape_3590_erp_basic(device, request, irb, -EIO);

View file

@ -278,7 +278,7 @@ tapeblock_cleanup_device(struct tape_device *device)
if (!device->blk_data.disk) { if (!device->blk_data.disk) {
PRINT_ERR("(%s): No gendisk to clean up!\n", PRINT_ERR("(%s): No gendisk to clean up!\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
goto cleanup_queue; goto cleanup_queue;
} }

View file

@ -215,12 +215,12 @@ tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
case MS_UNLOADED: case MS_UNLOADED:
device->tape_generic_status |= GMT_DR_OPEN(~0); device->tape_generic_status |= GMT_DR_OPEN(~0);
PRINT_INFO("(%s): Tape is unloaded\n", PRINT_INFO("(%s): Tape is unloaded\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
case MS_LOADED: case MS_LOADED:
device->tape_generic_status &= ~GMT_DR_OPEN(~0); device->tape_generic_status &= ~GMT_DR_OPEN(~0);
PRINT_INFO("(%s): Tape has been mounted\n", PRINT_INFO("(%s): Tape has been mounted\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
break; break;
default: default:
// print nothing // print nothing
@ -415,7 +415,7 @@ tape_generic_offline(struct tape_device *device)
device->cdev_id); device->cdev_id);
PRINT_WARN("(%s): Set offline failed " PRINT_WARN("(%s): Set offline failed "
"- drive in use.\n", "- drive in use.\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
spin_unlock_irq(get_ccwdev_lock(device->cdev)); spin_unlock_irq(get_ccwdev_lock(device->cdev));
return -EBUSY; return -EBUSY;
} }
@ -538,7 +538,8 @@ tape_generic_probe(struct ccw_device *cdev)
ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
if (ret) { if (ret) {
tape_put_device(device); tape_put_device(device);
PRINT_ERR("probe failed for tape device %s\n", cdev->dev.bus_id); PRINT_ERR("probe failed for tape device %s\n",
dev_name(&cdev->dev));
return ret; return ret;
} }
cdev->dev.driver_data = device; cdev->dev.driver_data = device;
@ -546,7 +547,7 @@ tape_generic_probe(struct ccw_device *cdev)
device->cdev = cdev; device->cdev = cdev;
ccw_device_get_id(cdev, &dev_id); ccw_device_get_id(cdev, &dev_id);
device->cdev_id = devid_to_int(&dev_id); device->cdev_id = devid_to_int(&dev_id);
PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); PRINT_INFO("tape device %s found\n", dev_name(&cdev->dev));
return ret; return ret;
} }
@ -616,7 +617,7 @@ tape_generic_remove(struct ccw_device *cdev)
device->cdev_id); device->cdev_id);
PRINT_WARN("(%s): Drive in use vanished - " PRINT_WARN("(%s): Drive in use vanished - "
"expect trouble!\n", "expect trouble!\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
PRINT_WARN("State was %i\n", device->tape_state); PRINT_WARN("State was %i\n", device->tape_state);
tape_state_set(device, TS_NOT_OPER); tape_state_set(device, TS_NOT_OPER);
__tape_discard_requests(device); __tape_discard_requests(device);
@ -840,7 +841,7 @@ tape_dump_sense(struct tape_device* device, struct tape_request *request,
PRINT_INFO("-------------------------------------------------\n"); PRINT_INFO("-------------------------------------------------\n");
PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n", PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n",
irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa); irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id); PRINT_INFO("DEVICE: %s\n", dev_name(&device->cdev->dev));
if (request != NULL) if (request != NULL)
PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]); PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]);
@ -1051,7 +1052,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
device = (struct tape_device *) cdev->dev.driver_data; device = (struct tape_device *) cdev->dev.driver_data;
if (device == NULL) { if (device == NULL) {
PRINT_ERR("could not get device structure for %s " PRINT_ERR("could not get device structure for %s "
"in interrupt\n", cdev->dev.bus_id); "in interrupt\n", dev_name(&cdev->dev));
return; return;
} }
request = (struct tape_request *) intparm; request = (struct tape_request *) intparm;
@ -1064,13 +1065,13 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
switch (PTR_ERR(irb)) { switch (PTR_ERR(irb)) {
case -ETIMEDOUT: case -ETIMEDOUT:
PRINT_WARN("(%s): Request timed out\n", PRINT_WARN("(%s): Request timed out\n",
cdev->dev.bus_id); dev_name(&cdev->dev));
case -EIO: case -EIO:
__tape_end_request(device, request, -EIO); __tape_end_request(device, request, -EIO);
break; break;
default: default:
PRINT_ERR("(%s): Unexpected i/o error %li\n", PRINT_ERR("(%s): Unexpected i/o error %li\n",
cdev->dev.bus_id, dev_name(&cdev->dev),
PTR_ERR(irb)); PTR_ERR(irb));
} }
return; return;

View file

@ -52,7 +52,7 @@ static int tape_proc_show(struct seq_file *m, void *v)
return 0; return 0;
spin_lock_irq(get_ccwdev_lock(device->cdev)); spin_lock_irq(get_ccwdev_lock(device->cdev));
seq_printf(m, "%d\t", (int) n); seq_printf(m, "%d\t", (int) n);
seq_printf(m, "%-10.10s ", device->cdev->dev.bus_id); seq_printf(m, "%-10.10s ", dev_name(&device->cdev->dev));
seq_printf(m, "%04X/", device->cdev->id.cu_type); seq_printf(m, "%04X/", device->cdev->id.cu_type);
seq_printf(m, "%02X\t", device->cdev->id.cu_model); seq_printf(m, "%02X\t", device->cdev->id.cu_model);
seq_printf(m, "%04X/", device->cdev->id.dev_type); seq_printf(m, "%04X/", device->cdev->id.dev_type);

View file

@ -47,7 +47,7 @@ tape_std_assign_timeout(unsigned long data)
rc = tape_cancel_io(device, request); rc = tape_cancel_io(device, request);
if(rc) if(rc)
PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n", PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
device->cdev->dev.bus_id, rc); dev_name(&device->cdev->dev), rc);
} }
@ -83,7 +83,7 @@ tape_std_assign(struct tape_device *device)
if (rc != 0) { if (rc != 0) {
PRINT_WARN("%s: assign failed - device might be busy\n", PRINT_WARN("%s: assign failed - device might be busy\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
DBF_EVENT(3, "%08x: assign failed - device might be busy\n", DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
device->cdev_id); device->cdev_id);
} else { } else {
@ -106,7 +106,7 @@ tape_std_unassign (struct tape_device *device)
DBF_EVENT(3, "(%08x): Can't unassign device\n", DBF_EVENT(3, "(%08x): Can't unassign device\n",
device->cdev_id); device->cdev_id);
PRINT_WARN("(%s): Can't unassign device - device gone\n", PRINT_WARN("(%s): Can't unassign device - device gone\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
return -EIO; return -EIO;
} }
@ -120,7 +120,8 @@ tape_std_unassign (struct tape_device *device)
if ((rc = tape_do_io(device, request)) != 0) { if ((rc = tape_do_io(device, request)) != 0) {
DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id); DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
PRINT_WARN("%s: Unassign failed\n", device->cdev->dev.bus_id); PRINT_WARN("%s: Unassign failed\n",
dev_name(&device->cdev->dev));
} else { } else {
DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id); DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
} }
@ -634,10 +635,10 @@ tape_std_mtcompression(struct tape_device *device, int mt_count)
DBF_EXCEPTION(6, "xcom parm\n"); DBF_EXCEPTION(6, "xcom parm\n");
if (*device->modeset_byte & 0x08) if (*device->modeset_byte & 0x08)
PRINT_INFO("(%s) Compression is currently on\n", PRINT_INFO("(%s) Compression is currently on\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
else else
PRINT_INFO("(%s) Compression is currently off\n", PRINT_INFO("(%s) Compression is currently off\n",
device->cdev->dev.bus_id); dev_name(&device->cdev->dev));
PRINT_INFO("Use 1 to switch compression on, 0 to " PRINT_INFO("Use 1 to switch compression on, 0 to "
"switch it off\n"); "switch it off\n");
return -EINVAL; return -EINVAL;

View file

@ -724,8 +724,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
dev = kzalloc(sizeof(struct device), GFP_KERNEL); dev = kzalloc(sizeof(struct device), GFP_KERNEL);
if (dev) { if (dev) {
snprintf(dev->bus_id, BUS_ID_SIZE, "%s", dev_set_name(dev, priv->internal_name);
priv->internal_name);
dev->bus = &iucv_bus; dev->bus = &iucv_bus;
dev->parent = iucv_root; dev->parent = iucv_root;
dev->driver = &vmlogrdr_driver; dev->driver = &vmlogrdr_driver;
@ -751,7 +750,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
priv->class_device = device_create_drvdata(vmlogrdr_class, dev, priv->class_device = device_create_drvdata(vmlogrdr_class, dev,
MKDEV(vmlogrdr_major, MKDEV(vmlogrdr_major,
priv->minor_num), priv->minor_num),
priv, "%s", dev->bus_id); priv, "%s", dev_name(dev));
if (IS_ERR(priv->class_device)) { if (IS_ERR(priv->class_device)) {
ret = PTR_ERR(priv->class_device); ret = PTR_ERR(priv->class_device);
priv->class_device=NULL; priv->class_device=NULL;

View file

@ -886,11 +886,11 @@ static int ur_set_online(struct ccw_device *cdev)
goto fail_free_cdev; goto fail_free_cdev;
if (urd->cdev->id.cu_type == READER_PUNCH_DEVTYPE) { if (urd->cdev->id.cu_type == READER_PUNCH_DEVTYPE) {
if (urd->class == DEV_CLASS_UR_I) if (urd->class == DEV_CLASS_UR_I)
sprintf(node_id, "vmrdr-%s", cdev->dev.bus_id); sprintf(node_id, "vmrdr-%s", dev_name(&cdev->dev));
if (urd->class == DEV_CLASS_UR_O) if (urd->class == DEV_CLASS_UR_O)
sprintf(node_id, "vmpun-%s", cdev->dev.bus_id); sprintf(node_id, "vmpun-%s", dev_name(&cdev->dev));
} else if (urd->cdev->id.cu_type == PRINTER_DEVTYPE) { } else if (urd->cdev->id.cu_type == PRINTER_DEVTYPE) {
sprintf(node_id, "vmprt-%s", cdev->dev.bus_id); sprintf(node_id, "vmprt-%s", dev_name(&cdev->dev));
} else { } else {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto fail_free_cdev; goto fail_free_cdev;

View file

@ -24,6 +24,7 @@
#include "cio.h" #include "cio.h"
#include "cio_debug.h" #include "cio_debug.h"
#include "css.h" #include "css.h"
#include "device.h"
/* /*
* "Blacklisting" of certain devices: * "Blacklisting" of certain devices:
@ -191,9 +192,9 @@ static int blacklist_parse_parameters(char *str, range_action action,
rc = blacklist_range(ra, from_ssid, to_ssid, from, to, rc = blacklist_range(ra, from_ssid, to_ssid, from, to,
msgtrigger); msgtrigger);
if (rc) if (rc)
totalrc = 1; totalrc = -EINVAL;
} else } else
totalrc = 1; totalrc = -EINVAL;
} }
return totalrc; return totalrc;
@ -240,8 +241,10 @@ static int blacklist_parse_proc_parameters(char *buf)
rc = blacklist_parse_parameters(buf, free, 0); rc = blacklist_parse_parameters(buf, free, 0);
else if (strcmp("add", parm) == 0) else if (strcmp("add", parm) == 0)
rc = blacklist_parse_parameters(buf, add, 0); rc = blacklist_parse_parameters(buf, add, 0);
else if (strcmp("purge", parm) == 0)
return ccw_purge_blacklisted();
else else
return 1; return -EINVAL;
css_schedule_reprobe(); css_schedule_reprobe();
@ -353,7 +356,7 @@ cio_ignore_write(struct file *file, const char __user *user_buf,
} }
ret = blacklist_parse_proc_parameters(buf); ret = blacklist_parse_proc_parameters(buf);
if (ret) if (ret)
rc = -EINVAL; rc = ret;
else else
rc = user_len; rc = user_len;

View file

@ -269,8 +269,7 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
goto error; goto error;
} }
snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s", dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
gdev->cdev[0]->dev.bus_id);
rc = device_add(&gdev->dev); rc = device_add(&gdev->dev);
if (rc) if (rc)

View file

@ -393,8 +393,7 @@ int chp_new(struct chp_id chpid)
chp->state = 1; chp->state = 1;
chp->dev.parent = &channel_subsystems[chpid.cssid]->device; chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
chp->dev.release = chp_release; chp->dev.release = chp_release;
snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp%x.%02x", chpid.cssid, dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);
chpid.id);
/* Obtain channel path description and fill it in. */ /* Obtain channel path description and fill it in. */
ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);

View file

@ -261,7 +261,7 @@ static int chsc_examine_irb(struct chsc_request *request)
{ {
int backed_up; int backed_up;
if (!scsw_stctl(&request->irb.scsw) & SCSW_STCTL_STATUS_PEND) if (!(scsw_stctl(&request->irb.scsw) & SCSW_STCTL_STATUS_PEND))
return -EIO; return -EIO;
backed_up = scsw_cstat(&request->irb.scsw) & SCHN_STAT_CHAIN_CHECK; backed_up = scsw_cstat(&request->irb.scsw) & SCHN_STAT_CHAIN_CHECK;
request->irb.scsw.cmd.cstat &= ~SCHN_STAT_CHAIN_CHECK; request->irb.scsw.cmd.cstat &= ~SCHN_STAT_CHAIN_CHECK;

View file

@ -114,6 +114,7 @@ cio_tpi(void)
struct tpi_info *tpi_info; struct tpi_info *tpi_info;
struct subchannel *sch; struct subchannel *sch;
struct irb *irb; struct irb *irb;
int irq_context;
tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID; tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
if (tpi (NULL) != 1) if (tpi (NULL) != 1)
@ -126,7 +127,9 @@ cio_tpi(void)
sch = (struct subchannel *)(unsigned long)tpi_info->intparm; sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
if (!sch) if (!sch)
return 1; return 1;
local_bh_disable(); irq_context = in_interrupt();
if (!irq_context)
local_bh_disable();
irq_enter (); irq_enter ();
spin_lock(sch->lock); spin_lock(sch->lock);
memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
@ -134,7 +137,8 @@ cio_tpi(void)
sch->driver->irq(sch); sch->driver->irq(sch);
spin_unlock(sch->lock); spin_unlock(sch->lock);
irq_exit (); irq_exit ();
_local_bh_enable(); if (!irq_context)
_local_bh_enable();
return 1; return 1;
} }
@ -153,7 +157,7 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
CIO_MSG_EVENT(2, "cio_start: 'not oper' status for " CIO_MSG_EVENT(2, "cio_start: 'not oper' status for "
"subchannel 0.%x.%04x!\n", sch->schid.ssid, "subchannel 0.%x.%04x!\n", sch->schid.ssid,
sch->schid.sch_no); sch->schid.sch_no);
sprintf(dbf_text, "no%s", sch->dev.bus_id); sprintf(dbf_text, "no%s", dev_name(&sch->dev));
CIO_TRACE_EVENT(0, dbf_text); CIO_TRACE_EVENT(0, dbf_text);
CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib)); CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
@ -171,7 +175,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
union orb *orb; union orb *orb;
CIO_TRACE_EVENT(4, "stIO"); CIO_TRACE_EVENT(4, "stIO");
CIO_TRACE_EVENT(4, sch->dev.bus_id); CIO_TRACE_EVENT(4, dev_name(&sch->dev));
orb = &to_io_private(sch)->orb; orb = &to_io_private(sch)->orb;
memset(orb, 0, sizeof(union orb)); memset(orb, 0, sizeof(union orb));
@ -232,7 +236,7 @@ cio_resume (struct subchannel *sch)
int ccode; int ccode;
CIO_TRACE_EVENT (4, "resIO"); CIO_TRACE_EVENT (4, "resIO");
CIO_TRACE_EVENT (4, sch->dev.bus_id); CIO_TRACE_EVENT(4, dev_name(&sch->dev));
ccode = rsch (sch->schid); ccode = rsch (sch->schid);
@ -269,7 +273,7 @@ cio_halt(struct subchannel *sch)
return -ENODEV; return -ENODEV;
CIO_TRACE_EVENT (2, "haltIO"); CIO_TRACE_EVENT (2, "haltIO");
CIO_TRACE_EVENT (2, sch->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&sch->dev));
/* /*
* Issue "Halt subchannel" and process condition code * Issue "Halt subchannel" and process condition code
@ -304,7 +308,7 @@ cio_clear(struct subchannel *sch)
return -ENODEV; return -ENODEV;
CIO_TRACE_EVENT (2, "clearIO"); CIO_TRACE_EVENT (2, "clearIO");
CIO_TRACE_EVENT (2, sch->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&sch->dev));
/* /*
* Issue "Clear subchannel" and process condition code * Issue "Clear subchannel" and process condition code
@ -340,7 +344,7 @@ cio_cancel (struct subchannel *sch)
return -ENODEV; return -ENODEV;
CIO_TRACE_EVENT (2, "cancelIO"); CIO_TRACE_EVENT (2, "cancelIO");
CIO_TRACE_EVENT (2, sch->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&sch->dev));
ccode = xsch (sch->schid); ccode = xsch (sch->schid);
@ -404,7 +408,7 @@ int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
int ret; int ret;
CIO_TRACE_EVENT (2, "ensch"); CIO_TRACE_EVENT (2, "ensch");
CIO_TRACE_EVENT (2, sch->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&sch->dev));
if (sch_is_pseudo_sch(sch)) if (sch_is_pseudo_sch(sch))
return -EINVAL; return -EINVAL;
@ -454,7 +458,7 @@ int cio_disable_subchannel(struct subchannel *sch)
int ret; int ret;
CIO_TRACE_EVENT (2, "dissch"); CIO_TRACE_EVENT (2, "dissch");
CIO_TRACE_EVENT (2, sch->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&sch->dev));
if (sch_is_pseudo_sch(sch)) if (sch_is_pseudo_sch(sch))
return 0; return 0;
@ -571,8 +575,10 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
} }
mutex_init(&sch->reg_mutex); mutex_init(&sch->reg_mutex);
/* Set a name for the subchannel */ /* Set a name for the subchannel */
snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", schid.ssid, if (cio_is_console(schid))
schid.sch_no); sch->dev.init_name = cio_get_console_sch_name(schid);
else
dev_set_name(&sch->dev, "0.%x.%04x", schid.ssid, schid.sch_no);
/* /*
* The first subchannel that is not-operational (ccode==3) * The first subchannel that is not-operational (ccode==3)
@ -677,6 +683,7 @@ do_IRQ (struct pt_regs *regs)
#ifdef CONFIG_CCW_CONSOLE #ifdef CONFIG_CCW_CONSOLE
static struct subchannel console_subchannel; static struct subchannel console_subchannel;
static char console_sch_name[10] = "0.x.xxxx";
static struct io_subchannel_private console_priv; static struct io_subchannel_private console_priv;
static int console_subchannel_in_use; static int console_subchannel_in_use;
@ -827,6 +834,12 @@ cio_get_console_subchannel(void)
return &console_subchannel; return &console_subchannel;
} }
const char *cio_get_console_sch_name(struct subchannel_id schid)
{
snprintf(console_sch_name, 10, "0.%x.%04x", schid.ssid, schid.sch_no);
return (const char *)console_sch_name;
}
#endif #endif
static int static int
__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
@ -846,19 +859,6 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
return -EBUSY; /* uhm... */ return -EBUSY; /* uhm... */
} }
/* we can't use the normal udelay here, since it enables external interrupts */
static void udelay_reset(unsigned long usecs)
{
uint64_t start_cc, end_cc;
asm volatile ("STCK %0" : "=m" (start_cc));
do {
cpu_relax();
asm volatile ("STCK %0" : "=m" (end_cc));
} while (((end_cc - start_cc)/4096) < usecs);
}
static int static int
__clear_io_subchannel_easy(struct subchannel_id schid) __clear_io_subchannel_easy(struct subchannel_id schid)
{ {
@ -874,7 +874,7 @@ __clear_io_subchannel_easy(struct subchannel_id schid)
if (schid_equal(&ti.schid, &schid)) if (schid_equal(&ti.schid, &schid))
return 0; return 0;
} }
udelay_reset(100); udelay_simple(100);
} }
return -EBUSY; return -EBUSY;
} }
@ -882,7 +882,7 @@ __clear_io_subchannel_easy(struct subchannel_id schid)
static void __clear_chsc_subchannel_easy(void) static void __clear_chsc_subchannel_easy(void)
{ {
/* It seems we can only wait for a bit here :/ */ /* It seems we can only wait for a bit here :/ */
udelay_reset(100); udelay_simple(100);
} }
static int pgm_check_occured; static int pgm_check_occured;
@ -892,7 +892,7 @@ static void cio_reset_pgm_check_handler(void)
pgm_check_occured = 1; pgm_check_occured = 1;
} }
static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr) static int stsch_reset(struct subchannel_id schid, struct schib *addr)
{ {
int rc; int rc;

View file

@ -117,11 +117,15 @@ extern int cio_is_console(struct subchannel_id);
extern struct subchannel *cio_get_console_subchannel(void); extern struct subchannel *cio_get_console_subchannel(void);
extern spinlock_t * cio_get_console_lock(void); extern spinlock_t * cio_get_console_lock(void);
extern void *cio_get_console_priv(void); extern void *cio_get_console_priv(void);
extern const char *cio_get_console_sch_name(struct subchannel_id schid);
extern const char *cio_get_console_cdev_name(struct subchannel *sch);
#else #else
#define cio_is_console(schid) 0 #define cio_is_console(schid) 0
#define cio_get_console_subchannel() NULL #define cio_get_console_subchannel() NULL
#define cio_get_console_lock() NULL #define cio_get_console_lock() NULL
#define cio_get_console_priv() NULL #define cio_get_console_priv() NULL
#define cio_get_console_sch_name(schid) NULL
#define cio_get_console_cdev_name(sch) NULL
#endif #endif
#endif #endif

View file

@ -698,7 +698,7 @@ static int __init setup_css(int nr)
return -ENOMEM; return -ENOMEM;
css->pseudo_subchannel->dev.parent = &css->device; css->pseudo_subchannel->dev.parent = &css->device;
css->pseudo_subchannel->dev.release = css_subchannel_release; css->pseudo_subchannel->dev.release = css_subchannel_release;
sprintf(css->pseudo_subchannel->dev.bus_id, "defunct"); dev_set_name(&css->pseudo_subchannel->dev, "defunct");
ret = cio_create_sch_lock(css->pseudo_subchannel); ret = cio_create_sch_lock(css->pseudo_subchannel);
if (ret) { if (ret) {
kfree(css->pseudo_subchannel); kfree(css->pseudo_subchannel);
@ -707,7 +707,7 @@ static int __init setup_css(int nr)
mutex_init(&css->mutex); mutex_init(&css->mutex);
css->valid = 1; css->valid = 1;
css->cssid = nr; css->cssid = nr;
sprintf(css->device.bus_id, "css%x", nr); dev_set_name(&css->device, "css%x", nr);
css->device.release = channel_subsystem_release; css->device.release = channel_subsystem_release;
tod_high = (u32) (get_clock() >> 32); tod_high = (u32) (get_clock() >> 32);
css_generate_pgid(css, tod_high); css_generate_pgid(css, tod_high);

View file

@ -31,6 +31,7 @@
#include "device.h" #include "device.h"
#include "ioasm.h" #include "ioasm.h"
#include "io_sch.h" #include "io_sch.h"
#include "blacklist.h"
static struct timer_list recovery_timer; static struct timer_list recovery_timer;
static DEFINE_SPINLOCK(recovery_lock); static DEFINE_SPINLOCK(recovery_lock);
@ -296,36 +297,33 @@ static void ccw_device_unregister(struct ccw_device *cdev)
device_del(&cdev->dev); device_del(&cdev->dev);
} }
static void ccw_device_remove_orphan_cb(struct device *dev) static void ccw_device_remove_orphan_cb(struct work_struct *work)
{ {
struct ccw_device *cdev = to_ccwdev(dev); struct ccw_device_private *priv;
struct ccw_device *cdev;
priv = container_of(work, struct ccw_device_private, kick_work);
cdev = priv->cdev;
ccw_device_unregister(cdev); ccw_device_unregister(cdev);
put_device(&cdev->dev); put_device(&cdev->dev);
/* Release cdev reference for workqueue processing. */
put_device(&cdev->dev);
} }
static void ccw_device_remove_sch_cb(struct device *dev) static void ccw_device_call_sch_unregister(struct work_struct *work);
{
struct subchannel *sch;
sch = to_subchannel(dev);
css_sch_device_unregister(sch);
/* Reset intparm to zeroes. */
sch->schib.pmcw.intparm = 0;
cio_modify(sch);
put_device(&sch->dev);
}
static void static void
ccw_device_remove_disconnected(struct ccw_device *cdev) ccw_device_remove_disconnected(struct ccw_device *cdev)
{ {
unsigned long flags; unsigned long flags;
int rc;
/* /*
* Forced offline in disconnected state means * Forced offline in disconnected state means
* 'throw away device'. * 'throw away device'.
*/ */
/* Get cdev reference for workqueue processing. */
if (!get_device(&cdev->dev))
return;
if (ccw_device_is_orphan(cdev)) { if (ccw_device_is_orphan(cdev)) {
/* /*
* Deregister ccw device. * Deregister ccw device.
@ -335,23 +333,13 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
spin_lock_irqsave(cdev->ccwlock, flags); spin_lock_irqsave(cdev->ccwlock, flags);
cdev->private->state = DEV_STATE_NOT_OPER; cdev->private->state = DEV_STATE_NOT_OPER;
spin_unlock_irqrestore(cdev->ccwlock, flags); spin_unlock_irqrestore(cdev->ccwlock, flags);
rc = device_schedule_callback(&cdev->dev, PREPARE_WORK(&cdev->private->kick_work,
ccw_device_remove_orphan_cb); ccw_device_remove_orphan_cb);
if (rc) } else
CIO_MSG_EVENT(0, "Couldn't unregister orphan " /* Deregister subchannel, which will kill the ccw device. */
"0.%x.%04x\n", PREPARE_WORK(&cdev->private->kick_work,
cdev->private->dev_id.ssid, ccw_device_call_sch_unregister);
cdev->private->dev_id.devno); queue_work(slow_path_wq, &cdev->private->kick_work);
return;
}
/* Deregister subchannel, which will kill the ccw device. */
rc = device_schedule_callback(cdev->dev.parent,
ccw_device_remove_sch_cb);
if (rc)
CIO_MSG_EVENT(0, "Couldn't unregister disconnected device "
"0.%x.%04x\n",
cdev->private->dev_id.ssid,
cdev->private->dev_id.devno);
} }
/** /**
@ -970,12 +958,17 @@ static void ccw_device_call_sch_unregister(struct work_struct *work)
priv = container_of(work, struct ccw_device_private, kick_work); priv = container_of(work, struct ccw_device_private, kick_work);
cdev = priv->cdev; cdev = priv->cdev;
/* Get subchannel reference for local processing. */
if (!get_device(cdev->dev.parent))
return;
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
css_sch_device_unregister(sch); css_sch_device_unregister(sch);
/* Reset intparm to zeroes. */ /* Reset intparm to zeroes. */
sch->schib.pmcw.intparm = 0; sch->schib.pmcw.intparm = 0;
cio_modify(sch); cio_modify(sch);
/* Release cdev reference for workqueue processing.*/
put_device(&cdev->dev); put_device(&cdev->dev);
/* Release subchannel reference for local processing. */
put_device(&sch->dev); put_device(&sch->dev);
} }
@ -1001,6 +994,8 @@ io_subchannel_recog_done(struct ccw_device *cdev)
PREPARE_WORK(&cdev->private->kick_work, PREPARE_WORK(&cdev->private->kick_work,
ccw_device_call_sch_unregister); ccw_device_call_sch_unregister);
queue_work(slow_path_wq, &cdev->private->kick_work); queue_work(slow_path_wq, &cdev->private->kick_work);
/* Release subchannel reference for asynchronous recognition. */
put_device(&sch->dev);
if (atomic_dec_and_test(&ccw_device_init_count)) if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq); wake_up(&ccw_device_init_wq);
break; break;
@ -1040,8 +1035,11 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
init_timer(&priv->timer); init_timer(&priv->timer);
/* Set an initial name for the device. */ /* Set an initial name for the device. */
snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", if (cio_is_console(sch->schid))
sch->schid.ssid, sch->schib.pmcw.dev); cdev->dev.init_name = cio_get_console_cdev_name(sch);
else
dev_set_name(&cdev->dev, "0.%x.%04x",
sch->schid.ssid, sch->schib.pmcw.dev);
/* Increase counter of devices currently in recognition. */ /* Increase counter of devices currently in recognition. */
atomic_inc(&ccw_device_init_count); atomic_inc(&ccw_device_init_count);
@ -1106,7 +1104,7 @@ static void io_subchannel_irq(struct subchannel *sch)
cdev = sch_get_cdev(sch); cdev = sch_get_cdev(sch);
CIO_TRACE_EVENT(3, "IRQ"); CIO_TRACE_EVENT(3, "IRQ");
CIO_TRACE_EVENT(3, sch->dev.bus_id); CIO_TRACE_EVENT(3, dev_name(&sch->dev));
if (cdev) if (cdev)
dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
} }
@ -1476,6 +1474,45 @@ static void ccw_device_schedule_recovery(void)
spin_unlock_irqrestore(&recovery_lock, flags); spin_unlock_irqrestore(&recovery_lock, flags);
} }
static int purge_fn(struct device *dev, void *data)
{
struct ccw_device *cdev = to_ccwdev(dev);
struct ccw_device_private *priv = cdev->private;
int unreg;
spin_lock_irq(cdev->ccwlock);
unreg = is_blacklisted(priv->dev_id.ssid, priv->dev_id.devno) &&
(priv->state == DEV_STATE_OFFLINE);
spin_unlock_irq(cdev->ccwlock);
if (!unreg)
goto out;
if (!get_device(&cdev->dev))
goto out;
CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
priv->dev_id.devno);
PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister);
queue_work(slow_path_wq, &cdev->private->kick_work);
out:
/* Abort loop in case of pending signal. */
if (signal_pending(current))
return -EINTR;
return 0;
}
/**
* ccw_purge_blacklisted - purge unused, blacklisted devices
*
* Unregister all ccw devices that are offline and on the blacklist.
*/
int ccw_purge_blacklisted(void)
{
CIO_MSG_EVENT(2, "ccw: purging blacklisted devices\n");
bus_for_each_dev(&ccw_bus_type, NULL, NULL, purge_fn);
return 0;
}
static void device_set_disconnected(struct ccw_device *cdev) static void device_set_disconnected(struct ccw_device *cdev)
{ {
if (!cdev) if (!cdev)
@ -1492,7 +1529,7 @@ void ccw_device_set_notoper(struct ccw_device *cdev)
struct subchannel *sch = to_subchannel(cdev->dev.parent); struct subchannel *sch = to_subchannel(cdev->dev.parent);
CIO_TRACE_EVENT(2, "notoper"); CIO_TRACE_EVENT(2, "notoper");
CIO_TRACE_EVENT(2, sch->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&sch->dev));
ccw_device_set_timeout(cdev, 0); ccw_device_set_timeout(cdev, 0);
cio_disable_subchannel(sch); cio_disable_subchannel(sch);
cdev->private->state = DEV_STATE_NOT_OPER; cdev->private->state = DEV_STATE_NOT_OPER;
@ -1591,6 +1628,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow)
#ifdef CONFIG_CCW_CONSOLE #ifdef CONFIG_CCW_CONSOLE
static struct ccw_device console_cdev; static struct ccw_device console_cdev;
static char console_cdev_name[10] = "0.x.xxxx";
static struct ccw_device_private console_private; static struct ccw_device_private console_private;
static int console_cdev_in_use; static int console_cdev_in_use;
@ -1661,6 +1699,14 @@ ccw_device_probe_console(void)
console_cdev.online = 1; console_cdev.online = 1;
return &console_cdev; return &console_cdev;
} }
const char *cio_get_console_cdev_name(struct subchannel *sch)
{
snprintf(console_cdev_name, 10, "0.%x.%04x",
sch->schid.ssid, sch->schib.pmcw.dev);
return (const char *)console_cdev_name;
}
#endif #endif
/* /*
@ -1673,7 +1719,7 @@ __ccwdev_check_busid(struct device *dev, void *id)
bus_id = id; bus_id = id;
return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); return (strncmp(bus_id, dev_name(dev), BUS_ID_SIZE) == 0);
} }

View file

@ -86,6 +86,7 @@ int ccw_device_is_orphan(struct ccw_device *);
int ccw_device_recognition(struct ccw_device *); int ccw_device_recognition(struct ccw_device *);
int ccw_device_online(struct ccw_device *); int ccw_device_online(struct ccw_device *);
int ccw_device_offline(struct ccw_device *); int ccw_device_offline(struct ccw_device *);
int ccw_purge_blacklisted(void);
/* Function prototypes for device status and basic sense stuff. */ /* Function prototypes for device status and basic sense stuff. */
void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);

View file

@ -52,8 +52,10 @@ static void ccw_timeout_log(struct ccw_device *cdev)
printk(KERN_WARNING "cio: orb:\n"); printk(KERN_WARNING "cio: orb:\n");
print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1,
orb, sizeof(*orb), 0); orb, sizeof(*orb), 0);
printk(KERN_WARNING "cio: ccw device bus id: %s\n", cdev->dev.bus_id); printk(KERN_WARNING "cio: ccw device bus id: %s\n",
printk(KERN_WARNING "cio: subchannel bus id: %s\n", sch->dev.bus_id); dev_name(&cdev->dev));
printk(KERN_WARNING "cio: subchannel bus id: %s\n",
dev_name(&sch->dev));
printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, " printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, "
"vpm: %02x\n", sch->lpm, sch->opm, sch->vpm); "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm);

View file

@ -498,7 +498,7 @@ ccw_device_stlck(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
CIO_TRACE_EVENT(2, "stl lock"); CIO_TRACE_EVENT(2, "stl lock");
CIO_TRACE_EVENT(2, cdev->dev.bus_id); CIO_TRACE_EVENT(2, dev_name(&cdev->dev));
buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL); buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
if (!buf) if (!buf)

View file

@ -123,7 +123,7 @@ struct ccw_device_private {
void *cmb_wait; /* deferred cmb enable/disable */ void *cmb_wait; /* deferred cmb enable/disable */
}; };
static inline int ssch(struct subchannel_id schid, volatile union orb *addr) static inline int ssch(struct subchannel_id schid, union orb *addr)
{ {
register struct subchannel_id reg1 asm("1") = schid; register struct subchannel_id reg1 asm("1") = schid;
int ccode = -EIO; int ccode = -EIO;
@ -134,7 +134,9 @@ static inline int ssch(struct subchannel_id schid, volatile union orb *addr)
" srl %0,28\n" " srl %0,28\n"
"1:\n" "1:\n"
EX_TABLE(0b, 1b) EX_TABLE(0b, 1b)
: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); : "+d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc", "memory");
return ccode; return ccode;
} }
@ -147,7 +149,9 @@ static inline int rsch(struct subchannel_id schid)
" rsch\n" " rsch\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1) : "cc"); : "=d" (ccode)
: "d" (reg1)
: "cc", "memory");
return ccode; return ccode;
} }
@ -160,7 +164,9 @@ static inline int csch(struct subchannel_id schid)
" csch\n" " csch\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1) : "cc"); : "=d" (ccode)
: "d" (reg1)
: "cc");
return ccode; return ccode;
} }
@ -173,7 +179,9 @@ static inline int hsch(struct subchannel_id schid)
" hsch\n" " hsch\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1) : "cc"); : "=d" (ccode)
: "d" (reg1)
: "cc");
return ccode; return ccode;
} }
@ -186,7 +194,9 @@ static inline int xsch(struct subchannel_id schid)
" .insn rre,0xb2760000,%1,0\n" " .insn rre,0xb2760000,%1,0\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1) : "cc"); : "=d" (ccode)
: "d" (reg1)
: "cc");
return ccode; return ccode;
} }

View file

@ -23,38 +23,39 @@ struct tpi_info {
* Some S390 specific IO instructions as inline * Some S390 specific IO instructions as inline
*/ */
static inline int stsch(struct subchannel_id schid, static inline int stsch(struct subchannel_id schid, struct schib *addr)
volatile struct schib *addr)
{ {
register struct subchannel_id reg1 asm ("1") = schid; register struct subchannel_id reg1 asm ("1") = schid;
int ccode; int ccode;
asm volatile( asm volatile(
" stsch 0(%2)\n" " stsch 0(%3)\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); : "=d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
return ccode; return ccode;
} }
static inline int stsch_err(struct subchannel_id schid, static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
volatile struct schib *addr)
{ {
register struct subchannel_id reg1 asm ("1") = schid; register struct subchannel_id reg1 asm ("1") = schid;
int ccode = -EIO; int ccode = -EIO;
asm volatile( asm volatile(
" stsch 0(%2)\n" " stsch 0(%3)\n"
"0: ipm %0\n" "0: ipm %0\n"
" srl %0,28\n" " srl %0,28\n"
"1:\n" "1:\n"
EX_TABLE(0b,1b) EX_TABLE(0b,1b)
: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); : "+d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
return ccode; return ccode;
} }
static inline int msch(struct subchannel_id schid, static inline int msch(struct subchannel_id schid, struct schib *addr)
volatile struct schib *addr)
{ {
register struct subchannel_id reg1 asm ("1") = schid; register struct subchannel_id reg1 asm ("1") = schid;
int ccode; int ccode;
@ -63,12 +64,13 @@ static inline int msch(struct subchannel_id schid,
" msch 0(%2)\n" " msch 0(%2)\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); : "=d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc");
return ccode; return ccode;
} }
static inline int msch_err(struct subchannel_id schid, static inline int msch_err(struct subchannel_id schid, struct schib *addr)
volatile struct schib *addr)
{ {
register struct subchannel_id reg1 asm ("1") = schid; register struct subchannel_id reg1 asm ("1") = schid;
int ccode = -EIO; int ccode = -EIO;
@ -79,33 +81,38 @@ static inline int msch_err(struct subchannel_id schid,
" srl %0,28\n" " srl %0,28\n"
"1:\n" "1:\n"
EX_TABLE(0b,1b) EX_TABLE(0b,1b)
: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); : "+d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc");
return ccode; return ccode;
} }
static inline int tsch(struct subchannel_id schid, static inline int tsch(struct subchannel_id schid, struct irb *addr)
volatile struct irb *addr)
{ {
register struct subchannel_id reg1 asm ("1") = schid; register struct subchannel_id reg1 asm ("1") = schid;
int ccode; int ccode;
asm volatile( asm volatile(
" tsch 0(%2)\n" " tsch 0(%3)\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); : "=d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
return ccode; return ccode;
} }
static inline int tpi( volatile struct tpi_info *addr) static inline int tpi(struct tpi_info *addr)
{ {
int ccode; int ccode;
asm volatile( asm volatile(
" tpi 0(%1)\n" " tpi 0(%2)\n"
" ipm %0\n" " ipm %0\n"
" srl %0,28" " srl %0,28"
: "=d" (ccode) : "a" (addr), "m" (*addr) : "cc"); : "=d" (ccode), "=m" (*addr)
: "a" (addr)
: "cc");
return ccode; return ccode;
} }

View file

@ -16,6 +16,14 @@
#define QDIO_BUSY_BIT_GIVE_UP 2000000 /* 2 seconds = eternity */ #define QDIO_BUSY_BIT_GIVE_UP 2000000 /* 2 seconds = eternity */
#define QDIO_INPUT_THRESHOLD 500 /* 500 microseconds */ #define QDIO_INPUT_THRESHOLD 500 /* 500 microseconds */
/*
* if an asynchronous HiperSockets queue runs full, the 10 seconds timer wait
* till next initiative to give transmitted skbs back to the stack is too long.
* Therefore polling is started in case of multicast queue is filled more
* than 50 percent.
*/
#define QDIO_IQDIO_POLL_LVL 65 /* HS multicast queue */
enum qdio_irq_states { enum qdio_irq_states {
QDIO_IRQ_STATE_INACTIVE, QDIO_IRQ_STATE_INACTIVE,
QDIO_IRQ_STATE_ESTABLISHED, QDIO_IRQ_STATE_ESTABLISHED,
@ -195,6 +203,9 @@ struct qdio_output_q {
/* PCIs are enabled for the queue */ /* PCIs are enabled for the queue */
int pci_out_enabled; int pci_out_enabled;
/* IQDIO: output multiple buffers (enhanced SIGA) */
int use_enh_siga;
/* timer to check for more outbound work */ /* timer to check for more outbound work */
struct timer_list timer; struct timer_list timer;
}; };

View file

@ -155,7 +155,7 @@ static int qstat_seq_open(struct inode *inode, struct file *filp)
static void get_queue_name(struct qdio_q *q, struct ccw_device *cdev, char *name) static void get_queue_name(struct qdio_q *q, struct ccw_device *cdev, char *name)
{ {
memset(name, 0, sizeof(name)); memset(name, 0, sizeof(name));
sprintf(name, "%s", cdev->dev.bus_id); sprintf(name, "%s", dev_name(&cdev->dev));
if (q->is_input_q) if (q->is_input_q)
sprintf(name + strlen(name), "_input"); sprintf(name + strlen(name), "_input");
else else

View file

@ -316,6 +316,9 @@ static inline int qdio_do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
unsigned int fc = 0; unsigned int fc = 0;
unsigned long schid; unsigned long schid;
if (q->u.out.use_enh_siga) {
fc = 3;
}
if (!is_qebsm(q)) if (!is_qebsm(q))
schid = *((u32 *)&q->irq_ptr->schid); schid = *((u32 *)&q->irq_ptr->schid);
else { else {
@ -851,6 +854,12 @@ static void __qdio_outbound_processing(struct qdio_q *q)
if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
return; return;
if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
(atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
tasklet_schedule(&q->tasklet);
return;
}
if (q->u.out.pci_out_enabled) if (q->u.out.pci_out_enabled)
return; return;
@ -956,7 +965,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
char dbf_text[15]; char dbf_text[15];
QDIO_DBF_TEXT2(1, trace, "ick2"); QDIO_DBF_TEXT2(1, trace, "ick2");
sprintf(dbf_text, "%s", cdev->dev.bus_id); sprintf(dbf_text, "%s", dev_name(&cdev->dev));
QDIO_DBF_TEXT2(1, trace, dbf_text); QDIO_DBF_TEXT2(1, trace, dbf_text);
QDIO_DBF_HEX2(0, trace, &intparm, sizeof(int)); QDIO_DBF_HEX2(0, trace, &intparm, sizeof(int));
QDIO_DBF_HEX2(0, trace, &dstat, sizeof(int)); QDIO_DBF_HEX2(0, trace, &dstat, sizeof(int));
@ -1443,6 +1452,8 @@ int qdio_establish(struct qdio_initialize *init_data)
} }
qdio_setup_ssqd_info(irq_ptr); qdio_setup_ssqd_info(irq_ptr);
sprintf(dbf_text, "qDmmwc%2x", irq_ptr->ssqd_desc.mmwc);
QDIO_DBF_TEXT2(0, setup, dbf_text);
sprintf(dbf_text, "qib ac%2x", irq_ptr->qib.ac); sprintf(dbf_text, "qib ac%2x", irq_ptr->qib.ac);
QDIO_DBF_TEXT2(0, setup, dbf_text); QDIO_DBF_TEXT2(0, setup, dbf_text);
@ -1615,12 +1626,21 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
if (multicast_outbound(q)) if (multicast_outbound(q))
qdio_kick_outbound_q(q); qdio_kick_outbound_q(q);
else else
/* if ((q->irq_ptr->ssqd_desc.mmwc > 1) &&
* One siga-w per buffer required for unicast (count > 1) &&
* HiperSockets. (count <= q->irq_ptr->ssqd_desc.mmwc)) {
*/ /* exploit enhanced SIGA */
while (count--) q->u.out.use_enh_siga = 1;
qdio_kick_outbound_q(q); qdio_kick_outbound_q(q);
} else {
/*
* One siga-w per buffer required for unicast
* HiperSockets.
*/
q->u.out.use_enh_siga = 0;
while (count--)
qdio_kick_outbound_q(q);
}
goto out; goto out;
} }

View file

@ -892,8 +892,8 @@ static void ap_scan_bus(struct work_struct *unused)
ap_dev->device.bus = &ap_bus_type; ap_dev->device.bus = &ap_bus_type;
ap_dev->device.parent = ap_root_device; ap_dev->device.parent = ap_root_device;
snprintf(ap_dev->device.bus_id, BUS_ID_SIZE, "card%02x", dev_set_name(&ap_dev->device, "card%02x",
AP_QID_DEVICE(ap_dev->qid)); AP_QID_DEVICE(ap_dev->qid));
ap_dev->device.release = ap_device_release; ap_dev->device.release = ap_device_release;
rc = device_register(&ap_dev->device); rc = device_register(&ap_dev->device);
if (rc) { if (rc) {

View file

@ -24,6 +24,7 @@
#include <asm/kvm_virtio.h> #include <asm/kvm_virtio.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/s390_ext.h> #include <asm/s390_ext.h>
#include <asm/s390_rdev.h>
#define VIRTIO_SUBCODE_64 0x0D00 #define VIRTIO_SUBCODE_64 0x0D00
@ -241,10 +242,7 @@ static struct virtio_config_ops kvm_vq_configspace_ops = {
* The root device for the kvm virtio devices. * The root device for the kvm virtio devices.
* This makes them appear as /sys/devices/kvm_s390/0,1,2 not /sys/devices/0,1,2. * This makes them appear as /sys/devices/kvm_s390/0,1,2 not /sys/devices/0,1,2.
*/ */
static struct device kvm_root = { static struct device *kvm_root;
.parent = NULL,
.bus_id = "kvm_s390",
};
/* /*
* adds a new device and register it with virtio * adds a new device and register it with virtio
@ -261,7 +259,7 @@ static void add_kvm_device(struct kvm_device_desc *d, unsigned int offset)
return; return;
} }
kdev->vdev.dev.parent = &kvm_root; kdev->vdev.dev.parent = kvm_root;
kdev->vdev.id.device = d->type; kdev->vdev.id.device = d->type;
kdev->vdev.config = &kvm_vq_configspace_ops; kdev->vdev.config = &kvm_vq_configspace_ops;
kdev->desc = d; kdev->desc = d;
@ -317,15 +315,16 @@ static int __init kvm_devices_init(void)
if (!MACHINE_IS_KVM) if (!MACHINE_IS_KVM)
return -ENODEV; return -ENODEV;
rc = device_register(&kvm_root); kvm_root = s390_root_dev_register("kvm_s390");
if (rc) { if (IS_ERR(kvm_root)) {
rc = PTR_ERR(kvm_root);
printk(KERN_ERR "Could not register kvm_s390 root device"); printk(KERN_ERR "Could not register kvm_s390 root device");
return rc; return rc;
} }
rc = vmem_add_mapping(PFN_PHYS(max_pfn), PAGE_SIZE); rc = vmem_add_mapping(PFN_PHYS(max_pfn), PAGE_SIZE);
if (rc) { if (rc) {
device_unregister(&kvm_root); s390_root_dev_unregister(kvm_root);
return rc; return rc;
} }

View file

@ -299,7 +299,7 @@ claw_probe(struct ccwgroup_device *cgdev)
probe_error(cgdev); probe_error(cgdev);
put_device(&cgdev->dev); put_device(&cgdev->dev);
printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n", printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n",
cgdev->cdev[0]->dev.bus_id,__func__,__LINE__); dev_name(&cgdev->cdev[0]->dev), __func__, __LINE__);
CLAW_DBF_TEXT_(2, setup, "probex%d", rc); CLAW_DBF_TEXT_(2, setup, "probex%d", rc);
return rc; return rc;
} }
@ -584,7 +584,7 @@ claw_irq_handler(struct ccw_device *cdev,
if (!cdev->dev.driver_data) { if (!cdev->dev.driver_data) {
printk(KERN_WARNING "claw: unsolicited interrupt for device:" printk(KERN_WARNING "claw: unsolicited interrupt for device:"
"%s received c-%02x d-%02x\n", "%s received c-%02x d-%02x\n",
cdev->dev.bus_id, irb->scsw.cmd.cstat, dev_name(&cdev->dev), irb->scsw.cmd.cstat,
irb->scsw.cmd.dstat); irb->scsw.cmd.dstat);
CLAW_DBF_TEXT(2, trace, "badirq"); CLAW_DBF_TEXT(2, trace, "badirq");
return; return;
@ -598,7 +598,7 @@ claw_irq_handler(struct ccw_device *cdev,
p_ch = &privptr->channel[WRITE]; p_ch = &privptr->channel[WRITE];
else { else {
printk(KERN_WARNING "claw: Can't determine channel for " printk(KERN_WARNING "claw: Can't determine channel for "
"interrupt, device %s\n", cdev->dev.bus_id); "interrupt, device %s\n", dev_name(&cdev->dev));
CLAW_DBF_TEXT(2, trace, "badchan"); CLAW_DBF_TEXT(2, trace, "badchan");
return; return;
} }
@ -662,7 +662,7 @@ claw_irq_handler(struct ccw_device *cdev,
printk(KERN_WARNING "claw: unsolicited " printk(KERN_WARNING "claw: unsolicited "
"interrupt for device:" "interrupt for device:"
"%s received c-%02x d-%02x\n", "%s received c-%02x d-%02x\n",
cdev->dev.bus_id, dev_name(&cdev->dev),
irb->scsw.cmd.cstat, irb->scsw.cmd.cstat,
irb->scsw.cmd.dstat); irb->scsw.cmd.dstat);
return; return;
@ -1136,19 +1136,20 @@ ccw_check_return_code(struct ccw_device *cdev, int return_code)
break; break;
case -ENODEV: case -ENODEV:
printk(KERN_EMERG "%s: Missing device called " printk(KERN_EMERG "%s: Missing device called "
"for IO ENODEV\n", cdev->dev.bus_id); "for IO ENODEV\n", dev_name(&cdev->dev));
break; break;
case -EIO: case -EIO:
printk(KERN_EMERG "%s: Status pending... EIO \n", printk(KERN_EMERG "%s: Status pending... EIO \n",
cdev->dev.bus_id); dev_name(&cdev->dev));
break; break;
case -EINVAL: case -EINVAL:
printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n", printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n",
cdev->dev.bus_id); dev_name(&cdev->dev));
break; break;
default: default:
printk(KERN_EMERG "%s: Unknown error in " printk(KERN_EMERG "%s: Unknown error in "
"Do_IO %d\n",cdev->dev.bus_id, return_code); "Do_IO %d\n", dev_name(&cdev->dev),
return_code);
} }
} }
CLAW_DBF_TEXT(4, trace, "ccwret"); CLAW_DBF_TEXT(4, trace, "ccwret");
@ -2848,11 +2849,11 @@ add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr)
struct chbk *p_ch; struct chbk *p_ch;
struct ccw_dev_id dev_id; struct ccw_dev_id dev_id;
CLAW_DBF_TEXT_(2, setup, "%s", cdev->dev.bus_id); CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cdev->dev));
privptr->channel[i].flag = i+1; /* Read is 1 Write is 2 */ privptr->channel[i].flag = i+1; /* Read is 1 Write is 2 */
p_ch = &privptr->channel[i]; p_ch = &privptr->channel[i];
p_ch->cdev = cdev; p_ch->cdev = cdev;
snprintf(p_ch->id, CLAW_ID_SIZE, "cl-%s", cdev->dev.bus_id); snprintf(p_ch->id, CLAW_ID_SIZE, "cl-%s", dev_name(&cdev->dev));
ccw_device_get_id(cdev, &dev_id); ccw_device_get_id(cdev, &dev_id);
p_ch->devno = dev_id.devno; p_ch->devno = dev_id.devno;
if ((p_ch->irb = kzalloc(sizeof (struct irb),GFP_KERNEL)) == NULL) { if ((p_ch->irb = kzalloc(sizeof (struct irb),GFP_KERNEL)) == NULL) {
@ -2879,7 +2880,8 @@ claw_new_device(struct ccwgroup_device *cgdev)
int ret; int ret;
struct ccw_dev_id dev_id; struct ccw_dev_id dev_id;
printk(KERN_INFO "claw: add for %s\n",cgdev->cdev[READ]->dev.bus_id); printk(KERN_INFO "claw: add for %s\n",
dev_name(&cgdev->cdev[READ]->dev));
CLAW_DBF_TEXT(2, setup, "new_dev"); CLAW_DBF_TEXT(2, setup, "new_dev");
privptr = cgdev->dev.driver_data; privptr = cgdev->dev.driver_data;
cgdev->cdev[READ]->dev.driver_data = privptr; cgdev->cdev[READ]->dev.driver_data = privptr;
@ -2903,14 +2905,16 @@ claw_new_device(struct ccwgroup_device *cgdev)
if (ret != 0) { if (ret != 0) {
printk(KERN_WARNING printk(KERN_WARNING
"claw: ccw_device_set_online %s READ failed " "claw: ccw_device_set_online %s READ failed "
"with ret = %d\n",cgdev->cdev[READ]->dev.bus_id,ret); "with ret = %d\n", dev_name(&cgdev->cdev[READ]->dev),
ret);
goto out; goto out;
} }
ret = ccw_device_set_online(cgdev->cdev[WRITE]); ret = ccw_device_set_online(cgdev->cdev[WRITE]);
if (ret != 0) { if (ret != 0) {
printk(KERN_WARNING printk(KERN_WARNING
"claw: ccw_device_set_online %s WRITE failed " "claw: ccw_device_set_online %s WRITE failed "
"with ret = %d\n",cgdev->cdev[WRITE]->dev.bus_id, ret); "with ret = %d\n", dev_name(&cgdev->cdev[WRITE]->dev)
ret);
goto out; goto out;
} }
dev = alloc_netdev(0,"claw%d",claw_init_netdevice); dev = alloc_netdev(0,"claw%d",claw_init_netdevice);
@ -2986,7 +2990,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
struct net_device *ndev; struct net_device *ndev;
int ret; int ret;
CLAW_DBF_TEXT_(2, setup, "%s", cgdev->dev.bus_id); CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = cgdev->dev.driver_data; priv = cgdev->dev.driver_data;
if (!priv) if (!priv)
return -ENODEV; return -ENODEV;
@ -3016,11 +3020,11 @@ claw_remove_device(struct ccwgroup_device *cgdev)
struct claw_privbk *priv; struct claw_privbk *priv;
BUG_ON(!cgdev); BUG_ON(!cgdev);
CLAW_DBF_TEXT_(2, setup, "%s", cgdev->dev.bus_id); CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = cgdev->dev.driver_data; priv = cgdev->dev.driver_data;
BUG_ON(!priv); BUG_ON(!priv);
printk(KERN_INFO "claw: %s() called %s will be removed.\n", printk(KERN_INFO "claw: %s() called %s will be removed.\n",
__func__,cgdev->cdev[0]->dev.bus_id); __func__, dev_name(&cgdev->cdev[0]->dev));
if (cgdev->state == CCWGROUP_ONLINE) if (cgdev->state == CCWGROUP_ONLINE)
claw_shutdown_device(cgdev); claw_shutdown_device(cgdev);
claw_remove_files(&cgdev->dev); claw_remove_files(&cgdev->dev);

View file

@ -85,7 +85,7 @@
#define CLAW_MAX_DEV 256 /* max claw devices */ #define CLAW_MAX_DEV 256 /* max claw devices */
#define MAX_NAME_LEN 8 /* host name, adapter name length */ #define MAX_NAME_LEN 8 /* host name, adapter name length */
#define CLAW_FRAME_SIZE 4096 #define CLAW_FRAME_SIZE 4096
#define CLAW_ID_SIZE BUS_ID_SIZE+3 #define CLAW_ID_SIZE 20+3
/* state machine codes used in claw_irq_handler */ /* state machine codes used in claw_irq_handler */

View file

@ -277,18 +277,18 @@ static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN, CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN,
"irb error %ld on device %s\n", "irb error %ld on device %s\n",
PTR_ERR(irb), cdev->dev.bus_id); PTR_ERR(irb), dev_name(&cdev->dev));
switch (PTR_ERR(irb)) { switch (PTR_ERR(irb)) {
case -EIO: case -EIO:
ctcm_pr_warn("i/o-error on device %s\n", cdev->dev.bus_id); ctcm_pr_warn("i/o-error on device %s\n", dev_name(&cdev->dev));
break; break;
case -ETIMEDOUT: case -ETIMEDOUT:
ctcm_pr_warn("timeout on device %s\n", cdev->dev.bus_id); ctcm_pr_warn("timeout on device %s\n", dev_name(&cdev->dev));
break; break;
default: default:
ctcm_pr_warn("unknown error %ld on device %s\n", ctcm_pr_warn("unknown error %ld on device %s\n",
PTR_ERR(irb), cdev->dev.bus_id); PTR_ERR(irb), dev_name(&cdev->dev));
} }
return PTR_ERR(irb); return PTR_ERR(irb);
} }
@ -1182,7 +1182,7 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
int dstat; int dstat;
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
"Enter %s(%s)", CTCM_FUNTAIL, &cdev->dev.bus_id); "Enter %s(%s)", CTCM_FUNTAIL, dev_name(&cdev->dev));
if (ctcm_check_irb_error(cdev, irb)) if (ctcm_check_irb_error(cdev, irb))
return; return;
@ -1208,14 +1208,14 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
ch = priv->channel[WRITE]; ch = priv->channel[WRITE];
else { else {
ctcm_pr_err("ctcm: Can't determine channel for interrupt, " ctcm_pr_err("ctcm: Can't determine channel for interrupt, "
"device %s\n", cdev->dev.bus_id); "device %s\n", dev_name(&cdev->dev));
return; return;
} }
dev = ch->netdev; dev = ch->netdev;
if (dev == NULL) { if (dev == NULL) {
ctcm_pr_crit("ctcm: %s dev=NULL bus_id=%s, ch=0x%p\n", ctcm_pr_crit("ctcm: %s dev=NULL bus_id=%s, ch=0x%p\n",
__func__, cdev->dev.bus_id, ch); __func__, dev_name(&cdev->dev), ch);
return; return;
} }
@ -1329,7 +1329,7 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
"%s(%s), type %d, proto %d", "%s(%s), type %d, proto %d",
__func__, cdev->dev.bus_id, type, priv->protocol); __func__, dev_name(&cdev->dev), type, priv->protocol);
ch = kzalloc(sizeof(struct channel), GFP_KERNEL); ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
if (ch == NULL) if (ch == NULL)
@ -1358,7 +1358,7 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
goto nomem_return; goto nomem_return;
ch->cdev = cdev; ch->cdev = cdev;
snprintf(ch->id, CTCM_ID_SIZE, "ch-%s", cdev->dev.bus_id); snprintf(ch->id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev->dev));
ch->type = type; ch->type = type;
/** /**
@ -1518,8 +1518,8 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
type = get_channel_type(&cdev0->id); type = get_channel_type(&cdev0->id);
snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cdev0->dev.bus_id); snprintf(read_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev0->dev));
snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cdev1->dev.bus_id); snprintf(write_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev1->dev));
ret = add_channel(cdev0, type, priv); ret = add_channel(cdev0, type, priv);
if (ret) if (ret)

View file

@ -104,7 +104,7 @@
#define READ 0 #define READ 0
#define WRITE 1 #define WRITE 1
#define CTCM_ID_SIZE BUS_ID_SIZE+3 #define CTCM_ID_SIZE 20+3
struct ctcm_profile { struct ctcm_profile {
unsigned long maxmulti; unsigned long maxmulti;

View file

@ -492,7 +492,7 @@ lcs_start_channel(struct lcs_channel *channel)
unsigned long flags; unsigned long flags;
int rc; int rc;
LCS_DBF_TEXT_(4,trace,"ssch%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4, trace,"ssch%s", dev_name(&channel->ccwdev->dev));
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
rc = ccw_device_start(channel->ccwdev, rc = ccw_device_start(channel->ccwdev,
channel->ccws + channel->io_idx, 0, 0, channel->ccws + channel->io_idx, 0, 0,
@ -501,7 +501,8 @@ lcs_start_channel(struct lcs_channel *channel)
channel->state = LCS_CH_STATE_RUNNING; channel->state = LCS_CH_STATE_RUNNING;
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) { if (rc) {
LCS_DBF_TEXT_(4,trace,"essh%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4,trace,"essh%s",
dev_name(&channel->ccwdev->dev));
PRINT_ERR("Error in starting channel, rc=%d!\n", rc); PRINT_ERR("Error in starting channel, rc=%d!\n", rc);
} }
return rc; return rc;
@ -514,12 +515,13 @@ lcs_clear_channel(struct lcs_channel *channel)
int rc; int rc;
LCS_DBF_TEXT(4,trace,"clearch"); LCS_DBF_TEXT(4,trace,"clearch");
LCS_DBF_TEXT_(4,trace,"%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev));
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
rc = ccw_device_clear(channel->ccwdev, (addr_t) channel); rc = ccw_device_clear(channel->ccwdev, (addr_t) channel);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) { if (rc) {
LCS_DBF_TEXT_(4,trace,"ecsc%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4, trace, "ecsc%s",
dev_name(&channel->ccwdev->dev));
return rc; return rc;
} }
wait_event(channel->wait_q, (channel->state == LCS_CH_STATE_CLEARED)); wait_event(channel->wait_q, (channel->state == LCS_CH_STATE_CLEARED));
@ -540,13 +542,14 @@ lcs_stop_channel(struct lcs_channel *channel)
if (channel->state == LCS_CH_STATE_STOPPED) if (channel->state == LCS_CH_STATE_STOPPED)
return 0; return 0;
LCS_DBF_TEXT(4,trace,"haltsch"); LCS_DBF_TEXT(4,trace,"haltsch");
LCS_DBF_TEXT_(4,trace,"%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev));
channel->state = LCS_CH_STATE_INIT; channel->state = LCS_CH_STATE_INIT;
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
rc = ccw_device_halt(channel->ccwdev, (addr_t) channel); rc = ccw_device_halt(channel->ccwdev, (addr_t) channel);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) { if (rc) {
LCS_DBF_TEXT_(4,trace,"ehsc%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4, trace, "ehsc%s",
dev_name(&channel->ccwdev->dev));
return rc; return rc;
} }
/* Asynchronous halt initialted. Wait for its completion. */ /* Asynchronous halt initialted. Wait for its completion. */
@ -632,10 +635,11 @@ __lcs_resume_channel(struct lcs_channel *channel)
return 0; return 0;
if (channel->ccws[channel->io_idx].flags & CCW_FLAG_SUSPEND) if (channel->ccws[channel->io_idx].flags & CCW_FLAG_SUSPEND)
return 0; return 0;
LCS_DBF_TEXT_(5, trace, "rsch%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(5, trace, "rsch%s", dev_name(&channel->ccwdev->dev));
rc = ccw_device_resume(channel->ccwdev); rc = ccw_device_resume(channel->ccwdev);
if (rc) { if (rc) {
LCS_DBF_TEXT_(4, trace, "ersc%s", channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(4, trace, "ersc%s",
dev_name(&channel->ccwdev->dev));
PRINT_ERR("Error in lcs_resume_channel: rc=%d\n",rc); PRINT_ERR("Error in lcs_resume_channel: rc=%d\n",rc);
} else } else
channel->state = LCS_CH_STATE_RUNNING; channel->state = LCS_CH_STATE_RUNNING;
@ -1302,18 +1306,18 @@ lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
switch (PTR_ERR(irb)) { switch (PTR_ERR(irb)) {
case -EIO: case -EIO:
PRINT_WARN("i/o-error on device %s\n", cdev->dev.bus_id); PRINT_WARN("i/o-error on device %s\n", dev_name(&cdev->dev));
LCS_DBF_TEXT(2, trace, "ckirberr"); LCS_DBF_TEXT(2, trace, "ckirberr");
LCS_DBF_TEXT_(2, trace, " rc%d", -EIO); LCS_DBF_TEXT_(2, trace, " rc%d", -EIO);
break; break;
case -ETIMEDOUT: case -ETIMEDOUT:
PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id); PRINT_WARN("timeout on device %s\n", dev_name(&cdev->dev));
LCS_DBF_TEXT(2, trace, "ckirberr"); LCS_DBF_TEXT(2, trace, "ckirberr");
LCS_DBF_TEXT_(2, trace, " rc%d", -ETIMEDOUT); LCS_DBF_TEXT_(2, trace, " rc%d", -ETIMEDOUT);
break; break;
default: default:
PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb), PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
cdev->dev.bus_id); dev_name(&cdev->dev));
LCS_DBF_TEXT(2, trace, "ckirberr"); LCS_DBF_TEXT(2, trace, "ckirberr");
LCS_DBF_TEXT(2, trace, " rc???"); LCS_DBF_TEXT(2, trace, " rc???");
} }
@ -1390,7 +1394,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
cstat = irb->scsw.cmd.cstat; cstat = irb->scsw.cmd.cstat;
dstat = irb->scsw.cmd.dstat; dstat = irb->scsw.cmd.dstat;
LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id); LCS_DBF_TEXT_(5, trace, "Rint%s", dev_name(&cdev->dev));
LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.cstat, LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.cstat,
irb->scsw.cmd.dstat); irb->scsw.cmd.dstat);
LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.fctl, LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.fctl,
@ -1400,7 +1404,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
rc = lcs_get_problem(cdev, irb); rc = lcs_get_problem(cdev, irb);
if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) { if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) {
PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n", PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
cdev->dev.bus_id, dstat, cstat); dev_name(&cdev->dev), dstat, cstat);
if (rc) { if (rc) {
channel->state = LCS_CH_STATE_ERROR; channel->state = LCS_CH_STATE_ERROR;
} }
@ -1463,7 +1467,7 @@ lcs_tasklet(unsigned long data)
int rc; int rc;
channel = (struct lcs_channel *) data; channel = (struct lcs_channel *) data;
LCS_DBF_TEXT_(5, trace, "tlet%s",channel->ccwdev->dev.bus_id); LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev));
/* Check for processed buffers. */ /* Check for processed buffers. */
iob = channel->iob; iob = channel->iob;
@ -2244,7 +2248,7 @@ lcs_recovery(void *ptr)
return 0; return 0;
LCS_DBF_TEXT(4, trace, "recover2"); LCS_DBF_TEXT(4, trace, "recover2");
gdev = card->gdev; gdev = card->gdev;
PRINT_WARN("Recovery of device %s started...\n", gdev->dev.bus_id); PRINT_WARN("Recovery of device %s started...\n", dev_name(&gdev->dev));
rc = __lcs_shutdown_device(gdev, 1); rc = __lcs_shutdown_device(gdev, 1);
rc = lcs_new_device(gdev); rc = lcs_new_device(gdev);
if (!rc) if (!rc)

View file

@ -1724,7 +1724,7 @@ static int netiucv_register_device(struct net_device *ndev)
IUCV_DBF_TEXT(trace, 3, __func__); IUCV_DBF_TEXT(trace, 3, __func__);
if (dev) { if (dev) {
snprintf(dev->bus_id, BUS_ID_SIZE, "net%s", ndev->name); dev_set_name(dev, "net%s", ndev->name);
dev->bus = &iucv_bus; dev->bus = &iucv_bus;
dev->parent = iucv_root; dev->parent = iucv_root;
/* /*

View file

@ -90,11 +90,11 @@ struct qeth_dbf_info {
#define CARD_RDEV(card) card->read.ccwdev #define CARD_RDEV(card) card->read.ccwdev
#define CARD_WDEV(card) card->write.ccwdev #define CARD_WDEV(card) card->write.ccwdev
#define CARD_DDEV(card) card->data.ccwdev #define CARD_DDEV(card) card->data.ccwdev
#define CARD_BUS_ID(card) card->gdev->dev.bus_id #define CARD_BUS_ID(card) dev_name(&card->gdev->dev)
#define CARD_RDEV_ID(card) card->read.ccwdev->dev.bus_id #define CARD_RDEV_ID(card) dev_name(&card->read.ccwdev->dev)
#define CARD_WDEV_ID(card) card->write.ccwdev->dev.bus_id #define CARD_WDEV_ID(card) dev_name(&card->write.ccwdev->dev)
#define CARD_DDEV_ID(card) card->data.ccwdev->dev.bus_id #define CARD_DDEV_ID(card) dev_name(&card->data.ccwdev->dev)
#define CHANNEL_ID(channel) channel->ccwdev->dev.bus_id #define CHANNEL_ID(channel) dev_name(&channel->ccwdev->dev)
/** /**
* card stuff * card stuff

View file

@ -745,7 +745,7 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) { SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
QETH_DBF_TEXT(TRACE, 2, "CGENCHK"); QETH_DBF_TEXT(TRACE, 2, "CGENCHK");
PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x ", PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x ",
cdev->dev.bus_id, dstat, cstat); dev_name(&cdev->dev), dstat, cstat);
print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET, print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET,
16, 1, irb, 64, 1); 16, 1, irb, 64, 1);
return 1; return 1;
@ -784,12 +784,12 @@ static long __qeth_check_irb_error(struct ccw_device *cdev,
switch (PTR_ERR(irb)) { switch (PTR_ERR(irb)) {
case -EIO: case -EIO:
PRINT_WARN("i/o-error on device %s\n", cdev->dev.bus_id); PRINT_WARN("i/o-error on device %s\n", dev_name(&cdev->dev));
QETH_DBF_TEXT(TRACE, 2, "ckirberr"); QETH_DBF_TEXT(TRACE, 2, "ckirberr");
QETH_DBF_TEXT_(TRACE, 2, " rc%d", -EIO); QETH_DBF_TEXT_(TRACE, 2, " rc%d", -EIO);
break; break;
case -ETIMEDOUT: case -ETIMEDOUT:
PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id); PRINT_WARN("timeout on device %s\n", dev_name(&cdev->dev));
QETH_DBF_TEXT(TRACE, 2, "ckirberr"); QETH_DBF_TEXT(TRACE, 2, "ckirberr");
QETH_DBF_TEXT_(TRACE, 2, " rc%d", -ETIMEDOUT); QETH_DBF_TEXT_(TRACE, 2, " rc%d", -ETIMEDOUT);
if (intparm == QETH_RCD_PARM) { if (intparm == QETH_RCD_PARM) {
@ -803,7 +803,7 @@ static long __qeth_check_irb_error(struct ccw_device *cdev,
break; break;
default: default:
PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb), PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
cdev->dev.bus_id); dev_name(&cdev->dev));
QETH_DBF_TEXT(TRACE, 2, "ckirberr"); QETH_DBF_TEXT(TRACE, 2, "ckirberr");
QETH_DBF_TEXT(TRACE, 2, " rc???"); QETH_DBF_TEXT(TRACE, 2, " rc???");
} }
@ -4081,7 +4081,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
if (!get_device(dev)) if (!get_device(dev))
return -ENODEV; return -ENODEV;
QETH_DBF_TEXT_(SETUP, 2, "%s", gdev->dev.bus_id); QETH_DBF_TEXT_(SETUP, 2, "%s", dev_name(&gdev->dev));
card = qeth_alloc_card(); card = qeth_alloc_card();
if (!card) { if (!card) {

View file

@ -30,7 +30,7 @@ s390_root_dev_register(const char *name)
dev = kzalloc(sizeof(struct device), GFP_KERNEL); dev = kzalloc(sizeof(struct device), GFP_KERNEL);
if (!dev) if (!dev)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
strncpy(dev->bus_id, name, min(strlen(name), (size_t)BUS_ID_SIZE)); dev_set_name(dev, name);
dev->release = s390_root_dev_release; dev->release = s390_root_dev_release;
ret = device_register(dev); ret = device_register(dev);
if (ret) { if (ret) {

View file

@ -283,8 +283,8 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
unit->port = port; unit->port = port;
unit->fcp_lun = fcp_lun; unit->fcp_lun = fcp_lun;
snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", dev_set_name(&unit->sysfs_device, "0x%016llx",
(unsigned long long) fcp_lun); (unsigned long long) fcp_lun);
unit->sysfs_device.parent = &port->sysfs_device; unit->sysfs_device.parent = &port->sysfs_device;
unit->sysfs_device.release = zfcp_sysfs_unit_release; unit->sysfs_device.release = zfcp_sysfs_unit_release;
dev_set_drvdata(&unit->sysfs_device, unit); dev_set_drvdata(&unit->sysfs_device, unit);
@ -610,8 +610,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
atomic_set(&port->refcount, 0); atomic_set(&port->refcount, 0);
snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", dev_set_name(&port->sysfs_device, "0x%016llx", wwpn);
(unsigned long long) wwpn);
port->sysfs_device.parent = &adapter->ccw_device->dev; port->sysfs_device.parent = &adapter->ccw_device->dev;
port->sysfs_device.release = zfcp_sysfs_port_release; port->sysfs_device.release = zfcp_sysfs_port_release;

View file

@ -596,7 +596,7 @@ struct zfcp_data {
struct semaphore config_sema; /* serialises configuration struct semaphore config_sema; /* serialises configuration
changes */ changes */
atomic_t loglevel; /* current loglevel */ atomic_t loglevel; /* current loglevel */
char init_busid[BUS_ID_SIZE]; char init_busid[20];
u64 init_wwpn; u64 init_wwpn;
u64 init_fcp_lun; u64 init_fcp_lun;
struct kmem_cache *fsf_req_qtcb_cache; struct kmem_cache *fsf_req_qtcb_cache;
@ -619,7 +619,7 @@ struct zfcp_fsf_req_qtcb {
#define ZFCP_SET 0x00000100 #define ZFCP_SET 0x00000100
#define ZFCP_CLEAR 0x00000200 #define ZFCP_CLEAR 0x00000200
#define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id) #define zfcp_get_busid_by_adapter(adapter) (dev_name(&adapter->ccw_device->dev))
/* /*
* Helper functions for request ID management. * Helper functions for request ID management.

View file

@ -1376,7 +1376,7 @@ static int zfcp_erp_thread(void *data)
struct zfcp_erp_action *act; struct zfcp_erp_action *act;
unsigned long flags; unsigned long flags;
daemonize("zfcperp%s", adapter->ccw_device->dev.bus_id); daemonize("zfcperp%s", dev_name(&adapter->ccw_device->dev));
/* Block all signals */ /* Block all signals */
siginitsetinv(&current->blocked, 0); siginitsetinv(&current->blocked, 0);
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);

View file

@ -381,7 +381,7 @@ static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
unit->port->adapter->ccw_device->dev.bus_id); dev_name(&unit->port->adapter->ccw_device->dev));
ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
(unsigned long long) unit->port->wwpn); (unsigned long long) unit->port->wwpn);
ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n",

View file

@ -81,7 +81,10 @@ my (@stack, $re, $dre, $x, $xs);
$re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o; $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
} elsif ($arch =~ /^s390x?$/) { } elsif ($arch =~ /^s390x?$/) {
# 11160: a7 fb ff 60 aghi %r15,-160 # 11160: a7 fb ff 60 aghi %r15,-160
$re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o; # or
# 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15)
$re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})
(?:\(\%r15\))?$/ox;
} elsif ($arch =~ /^sh64$/) { } elsif ($arch =~ /^sh64$/) {
#XXX: we only check for the immediate case presently, #XXX: we only check for the immediate case presently,
# though we will want to check for the movi/sub # though we will want to check for the movi/sub