diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd_eer.c | 16 | ||||
-rw-r--r-- | drivers/s390/block/dasd_proc.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 10 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 12 | ||||
-rw-r--r-- | drivers/s390/char/sclp_chp.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp_info.c | 117 | ||||
-rw-r--r-- | drivers/s390/char/vmcp.c | 13 | ||||
-rw-r--r-- | drivers/s390/char/vmlogrdr.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/zcore.c | 5 | ||||
-rw-r--r-- | drivers/s390/cio/chp.c | 12 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 49 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 6 | ||||
-rw-r--r-- | drivers/s390/cio/device_id.c | 22 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 98 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.h | 11 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex2a.c | 27 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcica.c | 27 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcicc.c | 27 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 40 | ||||
-rw-r--r-- | drivers/s390/net/claw.c | 13 | ||||
-rw-r--r-- | drivers/s390/net/netiucv.c | 23 | ||||
-rw-r--r-- | drivers/s390/net/qeth_eddp.c | 3 | ||||
-rw-r--r-- | drivers/s390/net/qeth_main.c | 52 | ||||
-rw-r--r-- | drivers/s390/net/qeth_sys.c | 2 |
24 files changed, 370 insertions, 227 deletions
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index a1dc8c466ec9..0c081a664ee8 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c | |||
@@ -14,9 +14,9 @@ | |||
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
17 | #include <linux/mutex.h> | ||
17 | 18 | ||
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | #include <asm/semaphore.h> | ||
20 | #include <asm/atomic.h> | 20 | #include <asm/atomic.h> |
21 | #include <asm/ebcdic.h> | 21 | #include <asm/ebcdic.h> |
22 | 22 | ||
@@ -514,7 +514,7 @@ void dasd_eer_disable(struct dasd_device *device) | |||
514 | * to transfer in a readbuffer, which is protected by the readbuffer_mutex. | 514 | * to transfer in a readbuffer, which is protected by the readbuffer_mutex. |
515 | */ | 515 | */ |
516 | static char readbuffer[PAGE_SIZE]; | 516 | static char readbuffer[PAGE_SIZE]; |
517 | static DECLARE_MUTEX(readbuffer_mutex); | 517 | static DEFINE_MUTEX(readbuffer_mutex); |
518 | 518 | ||
519 | static int dasd_eer_open(struct inode *inp, struct file *filp) | 519 | static int dasd_eer_open(struct inode *inp, struct file *filp) |
520 | { | 520 | { |
@@ -579,7 +579,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
579 | struct eerbuffer *eerb; | 579 | struct eerbuffer *eerb; |
580 | 580 | ||
581 | eerb = (struct eerbuffer *) filp->private_data; | 581 | eerb = (struct eerbuffer *) filp->private_data; |
582 | if (down_interruptible(&readbuffer_mutex)) | 582 | if (mutex_lock_interruptible(&readbuffer_mutex)) |
583 | return -ERESTARTSYS; | 583 | return -ERESTARTSYS; |
584 | 584 | ||
585 | spin_lock_irqsave(&bufferlock, flags); | 585 | spin_lock_irqsave(&bufferlock, flags); |
@@ -588,7 +588,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
588 | /* has been deleted */ | 588 | /* has been deleted */ |
589 | eerb->residual = 0; | 589 | eerb->residual = 0; |
590 | spin_unlock_irqrestore(&bufferlock, flags); | 590 | spin_unlock_irqrestore(&bufferlock, flags); |
591 | up(&readbuffer_mutex); | 591 | mutex_unlock(&readbuffer_mutex); |
592 | return -EIO; | 592 | return -EIO; |
593 | } else if (eerb->residual > 0) { | 593 | } else if (eerb->residual > 0) { |
594 | /* OK we still have a second half of a record to deliver */ | 594 | /* OK we still have a second half of a record to deliver */ |
@@ -602,7 +602,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
602 | if (!tc) { | 602 | if (!tc) { |
603 | /* no data available */ | 603 | /* no data available */ |
604 | spin_unlock_irqrestore(&bufferlock, flags); | 604 | spin_unlock_irqrestore(&bufferlock, flags); |
605 | up(&readbuffer_mutex); | 605 | mutex_unlock(&readbuffer_mutex); |
606 | if (filp->f_flags & O_NONBLOCK) | 606 | if (filp->f_flags & O_NONBLOCK) |
607 | return -EAGAIN; | 607 | return -EAGAIN; |
608 | rc = wait_event_interruptible( | 608 | rc = wait_event_interruptible( |
@@ -610,7 +610,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
610 | eerb->head != eerb->tail); | 610 | eerb->head != eerb->tail); |
611 | if (rc) | 611 | if (rc) |
612 | return rc; | 612 | return rc; |
613 | if (down_interruptible(&readbuffer_mutex)) | 613 | if (mutex_lock_interruptible(&readbuffer_mutex)) |
614 | return -ERESTARTSYS; | 614 | return -ERESTARTSYS; |
615 | spin_lock_irqsave(&bufferlock, flags); | 615 | spin_lock_irqsave(&bufferlock, flags); |
616 | } | 616 | } |
@@ -626,11 +626,11 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
626 | spin_unlock_irqrestore(&bufferlock, flags); | 626 | spin_unlock_irqrestore(&bufferlock, flags); |
627 | 627 | ||
628 | if (copy_to_user(buf, readbuffer, effective_count)) { | 628 | if (copy_to_user(buf, readbuffer, effective_count)) { |
629 | up(&readbuffer_mutex); | 629 | mutex_unlock(&readbuffer_mutex); |
630 | return -EFAULT; | 630 | return -EFAULT; |
631 | } | 631 | } |
632 | 632 | ||
633 | up(&readbuffer_mutex); | 633 | mutex_unlock(&readbuffer_mutex); |
634 | return effective_count; | 634 | return effective_count; |
635 | } | 635 | } |
636 | 636 | ||
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 8b3b0f4a157c..ac7e8ef504cb 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL; | |||
28 | static struct proc_dir_entry *dasd_devices_entry = NULL; | 28 | static struct proc_dir_entry *dasd_devices_entry = NULL; |
29 | static struct proc_dir_entry *dasd_statistics_entry = NULL; | 29 | static struct proc_dir_entry *dasd_statistics_entry = NULL; |
30 | 30 | ||
31 | #ifdef CONFIG_DASD_PROFILE | ||
31 | static char * | 32 | static char * |
32 | dasd_get_user_string(const char __user *user_buf, size_t user_len) | 33 | dasd_get_user_string(const char __user *user_buf, size_t user_len) |
33 | { | 34 | { |
@@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len) | |||
47 | buffer[user_len] = 0; | 48 | buffer[user_len] = 0; |
48 | return buffer; | 49 | return buffer; |
49 | } | 50 | } |
51 | #endif /* CONFIG_DASD_PROFILE */ | ||
50 | 52 | ||
51 | static int | 53 | static int |
52 | dasd_devices_show(struct seq_file *m, void *v) | 54 | dasd_devices_show(struct seq_file *m, void *v) |
@@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off, | |||
167 | return len; | 169 | return len; |
168 | } | 170 | } |
169 | 171 | ||
172 | #ifdef CONFIG_DASD_PROFILE | ||
170 | static char * | 173 | static char * |
171 | dasd_statistics_array(char *str, unsigned int *array, int shift) | 174 | dasd_statistics_array(char *str, unsigned int *array, int shift) |
172 | { | 175 | { |
@@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift) | |||
180 | str += sprintf(str,"\n"); | 183 | str += sprintf(str,"\n"); |
181 | return str; | 184 | return str; |
182 | } | 185 | } |
186 | #endif /* CONFIG_DASD_PROFILE */ | ||
183 | 187 | ||
184 | static int | 188 | static int |
185 | dasd_statistics_read(char *page, char **start, off_t off, | 189 | dasd_statistics_read(char *page, char **start, off_t off, |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index f6ef90ee3e7d..743944ad61ec 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -487,7 +487,7 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */ | |||
487 | } __attribute__ ((packed)); | 487 | } __attribute__ ((packed)); |
488 | 488 | ||
489 | static struct diag210 raw3270_init_diag210; | 489 | static struct diag210 raw3270_init_diag210; |
490 | static DECLARE_MUTEX(raw3270_init_sem); | 490 | static DEFINE_MUTEX(raw3270_init_mutex); |
491 | 491 | ||
492 | static int | 492 | static int |
493 | raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, | 493 | raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, |
@@ -713,7 +713,7 @@ raw3270_size_device(struct raw3270 *rp) | |||
713 | { | 713 | { |
714 | int rc; | 714 | int rc; |
715 | 715 | ||
716 | down(&raw3270_init_sem); | 716 | mutex_lock(&raw3270_init_mutex); |
717 | rp->view = &raw3270_init_view; | 717 | rp->view = &raw3270_init_view; |
718 | raw3270_init_view.dev = rp; | 718 | raw3270_init_view.dev = rp; |
719 | if (MACHINE_IS_VM) | 719 | if (MACHINE_IS_VM) |
@@ -722,7 +722,7 @@ raw3270_size_device(struct raw3270 *rp) | |||
722 | rc = __raw3270_size_device(rp); | 722 | rc = __raw3270_size_device(rp); |
723 | raw3270_init_view.dev = NULL; | 723 | raw3270_init_view.dev = NULL; |
724 | rp->view = NULL; | 724 | rp->view = NULL; |
725 | up(&raw3270_init_sem); | 725 | mutex_unlock(&raw3270_init_mutex); |
726 | if (rc == 0) { /* Found something. */ | 726 | if (rc == 0) { /* Found something. */ |
727 | /* Try to find a model. */ | 727 | /* Try to find a model. */ |
728 | rp->model = 0; | 728 | rp->model = 0; |
@@ -749,7 +749,7 @@ raw3270_reset_device(struct raw3270 *rp) | |||
749 | { | 749 | { |
750 | int rc; | 750 | int rc; |
751 | 751 | ||
752 | down(&raw3270_init_sem); | 752 | mutex_lock(&raw3270_init_mutex); |
753 | memset(&rp->init_request, 0, sizeof(rp->init_request)); | 753 | memset(&rp->init_request, 0, sizeof(rp->init_request)); |
754 | memset(&rp->init_data, 0, sizeof(rp->init_data)); | 754 | memset(&rp->init_data, 0, sizeof(rp->init_data)); |
755 | /* Store reset data stream to init_data/init_request */ | 755 | /* Store reset data stream to init_data/init_request */ |
@@ -764,7 +764,7 @@ raw3270_reset_device(struct raw3270 *rp) | |||
764 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); | 764 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
765 | raw3270_init_view.dev = NULL; | 765 | raw3270_init_view.dev = NULL; |
766 | rp->view = NULL; | 766 | rp->view = NULL; |
767 | up(&raw3270_init_sem); | 767 | mutex_unlock(&raw3270_init_mutex); |
768 | return rc; | 768 | return rc; |
769 | } | 769 | } |
770 | 770 | ||
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index dbb99d1b6f57..c7318a125852 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
@@ -72,6 +72,18 @@ typedef unsigned int sclp_cmdw_t; | |||
72 | 72 | ||
73 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ | 73 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ |
74 | 74 | ||
75 | struct sccb_header { | ||
76 | u16 length; | ||
77 | u8 function_code; | ||
78 | u8 control_mask[3]; | ||
79 | u16 response_code; | ||
80 | } __attribute__((packed)); | ||
81 | |||
82 | extern u64 sclp_facilities; | ||
83 | |||
84 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) | ||
85 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) | ||
86 | |||
75 | struct gds_subvector { | 87 | struct gds_subvector { |
76 | u8 length; | 88 | u8 length; |
77 | u8 key; | 89 | u8 key; |
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c index a66b914519b5..c68f5e7e63a0 100644 --- a/drivers/s390/char/sclp_chp.c +++ b/drivers/s390/char/sclp_chp.c | |||
@@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd) | |||
55 | struct chp_cfg_data *data; | 55 | struct chp_cfg_data *data; |
56 | int rc; | 56 | int rc; |
57 | 57 | ||
58 | if (!SCLP_HAS_CHP_RECONFIG) | ||
59 | return -EOPNOTSUPP; | ||
58 | /* Prepare sccb. */ | 60 | /* Prepare sccb. */ |
59 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 61 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
60 | if (!data) | 62 | if (!data) |
@@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info) | |||
152 | struct chp_info_data *data; | 154 | struct chp_info_data *data; |
153 | int rc; | 155 | int rc; |
154 | 156 | ||
157 | if (!SCLP_HAS_CHP_INFO) | ||
158 | return -EOPNOTSUPP; | ||
155 | /* Prepare sccb. */ | 159 | /* Prepare sccb. */ |
156 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 160 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
157 | if (!data) | 161 | if (!data) |
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c index 7bcbe643b087..a1136e052750 100644 --- a/drivers/s390/char/sclp_info.c +++ b/drivers/s390/char/sclp_info.c | |||
@@ -11,47 +11,106 @@ | |||
11 | #include <asm/sclp.h> | 11 | #include <asm/sclp.h> |
12 | #include "sclp.h" | 12 | #include "sclp.h" |
13 | 13 | ||
14 | struct sclp_readinfo_sccb s390_readinfo_sccb; | 14 | struct sclp_readinfo_sccb { |
15 | struct sccb_header header; /* 0-7 */ | ||
16 | u16 rnmax; /* 8-9 */ | ||
17 | u8 rnsize; /* 10 */ | ||
18 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
19 | u8 loadparm[8]; /* 24-31 */ | ||
20 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
21 | u64 facilities; /* 48-55 */ | ||
22 | u8 _reserved2[91 - 56]; /* 56-90 */ | ||
23 | u8 flags; /* 91 */ | ||
24 | u8 _reserved3[100 - 92]; /* 92-99 */ | ||
25 | u32 rnsize2; /* 100-103 */ | ||
26 | u64 rnmax2; /* 104-111 */ | ||
27 | u8 _reserved4[4096 - 112]; /* 112-4095 */ | ||
28 | } __attribute__((packed, aligned(4096))); | ||
29 | |||
30 | static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; | ||
31 | static int __initdata early_readinfo_sccb_valid; | ||
32 | |||
33 | u64 sclp_facilities; | ||
15 | 34 | ||
16 | void __init sclp_readinfo_early(void) | 35 | void __init sclp_readinfo_early(void) |
17 | { | 36 | { |
18 | sclp_cmdw_t command; | ||
19 | struct sccb_header *sccb; | ||
20 | int ret; | 37 | int ret; |
38 | int i; | ||
39 | struct sclp_readinfo_sccb *sccb; | ||
40 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
41 | SCLP_CMDW_READ_SCP_INFO}; | ||
21 | 42 | ||
22 | __ctl_set_bit(0, 9); /* enable service signal subclass mask */ | 43 | /* Enable service signal subclass mask. */ |
23 | 44 | __ctl_set_bit(0, 9); | |
24 | sccb = &s390_readinfo_sccb.header; | 45 | sccb = &early_readinfo_sccb; |
25 | command = SCLP_CMDW_READ_SCP_INFO_FORCED; | 46 | for (i = 0; i < ARRAY_SIZE(commands); i++) { |
26 | while (1) { | 47 | do { |
27 | u16 response; | 48 | memset(sccb, 0, sizeof(*sccb)); |
28 | 49 | sccb->header.length = sizeof(*sccb); | |
29 | memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); | 50 | sccb->header.control_mask[2] = 0x80; |
30 | sccb->length = sizeof(s390_readinfo_sccb); | 51 | ret = sclp_service_call(commands[i], sccb); |
31 | sccb->control_mask[2] = 0x80; | 52 | } while (ret == -EBUSY); |
32 | |||
33 | ret = sclp_service_call(command, &s390_readinfo_sccb); | ||
34 | |||
35 | if (ret == -EIO) | ||
36 | goto out; | ||
37 | if (ret == -EBUSY) | ||
38 | continue; | ||
39 | 53 | ||
54 | if (ret) | ||
55 | break; | ||
40 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | 56 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | |
41 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | 57 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); |
42 | local_irq_disable(); | 58 | local_irq_disable(); |
59 | /* | ||
60 | * Contents of the sccb might have changed | ||
61 | * therefore a barrier is needed. | ||
62 | */ | ||
43 | barrier(); | 63 | barrier(); |
64 | if (sccb->header.response_code == 0x10) { | ||
65 | early_readinfo_sccb_valid = 1; | ||
66 | break; | ||
67 | } | ||
68 | if (sccb->header.response_code != 0x1f0) | ||
69 | break; | ||
70 | } | ||
71 | /* Disable service signal subclass mask again. */ | ||
72 | __ctl_clear_bit(0, 9); | ||
73 | } | ||
44 | 74 | ||
45 | response = sccb->response_code; | 75 | void __init sclp_facilities_detect(void) |
76 | { | ||
77 | if (!early_readinfo_sccb_valid) | ||
78 | return; | ||
79 | sclp_facilities = early_readinfo_sccb.facilities; | ||
80 | } | ||
46 | 81 | ||
47 | if (response == 0x10) | 82 | unsigned long long __init sclp_memory_detect(void) |
48 | break; | 83 | { |
84 | unsigned long long memsize; | ||
85 | struct sclp_readinfo_sccb *sccb; | ||
49 | 86 | ||
50 | if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) | 87 | if (!early_readinfo_sccb_valid) |
51 | break; | 88 | return 0; |
89 | sccb = &early_readinfo_sccb; | ||
90 | if (sccb->rnsize) | ||
91 | memsize = sccb->rnsize << 20; | ||
92 | else | ||
93 | memsize = sccb->rnsize2 << 20; | ||
94 | if (sccb->rnmax) | ||
95 | memsize *= sccb->rnmax; | ||
96 | else | ||
97 | memsize *= sccb->rnmax2; | ||
98 | return memsize; | ||
99 | } | ||
52 | 100 | ||
53 | command = SCLP_CMDW_READ_SCP_INFO; | 101 | /* |
54 | } | 102 | * This function will be called after sclp_memory_detect(), which gets called |
55 | out: | 103 | * early from early.c code. Therefore the sccb should have valid contents. |
56 | __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ | 104 | */ |
105 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
106 | { | ||
107 | struct sclp_readinfo_sccb *sccb; | ||
108 | |||
109 | if (!early_readinfo_sccb_valid) | ||
110 | return; | ||
111 | sccb = &early_readinfo_sccb; | ||
112 | info->is_valid = 1; | ||
113 | if (sccb->flags & 0x2) | ||
114 | info->has_dump = 1; | ||
115 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
57 | } | 116 | } |
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index fce3dac5cb3e..82e6a6b253eb 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
175 | 175 | ||
176 | static const struct file_operations vmcp_fops = { | 176 | static const struct file_operations vmcp_fops = { |
177 | .owner = THIS_MODULE, | 177 | .owner = THIS_MODULE, |
178 | .open = &vmcp_open, | 178 | .open = vmcp_open, |
179 | .release = &vmcp_release, | 179 | .release = vmcp_release, |
180 | .read = &vmcp_read, | 180 | .read = vmcp_read, |
181 | .llseek = &no_llseek, | 181 | .write = vmcp_write, |
182 | .write = &vmcp_write, | 182 | .unlocked_ioctl = vmcp_ioctl, |
183 | .unlocked_ioctl = &vmcp_ioctl, | 183 | .compat_ioctl = vmcp_ioctl |
184 | .compat_ioctl = &vmcp_ioctl | ||
185 | }; | 184 | }; |
186 | 185 | ||
187 | static struct miscdevice vmcp_dev = { | 186 | static struct miscdevice vmcp_dev = { |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a5a00e9ae4d0..12f7a4ce82c1 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void) | |||
835 | } | 835 | } |
836 | 836 | ||
837 | 837 | ||
838 | static int vmlogrdr_init(void) | 838 | static int __init vmlogrdr_init(void) |
839 | { | 839 | { |
840 | int rc; | 840 | int rc; |
841 | int i; | 841 | int i; |
@@ -885,7 +885,7 @@ cleanup: | |||
885 | } | 885 | } |
886 | 886 | ||
887 | 887 | ||
888 | static void vmlogrdr_exit(void) | 888 | static void __exit vmlogrdr_exit(void) |
889 | { | 889 | { |
890 | vmlogrdr_cleanup(); | 890 | vmlogrdr_cleanup(); |
891 | printk (KERN_INFO "vmlogrdr: driver unloaded\n"); | 891 | printk (KERN_INFO "vmlogrdr: driver unloaded\n"); |
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 66eb0688d523..3712ede16723 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count) | |||
156 | return rc; | 156 | return rc; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int memcpy_real_user(__user void *dest, unsigned long src, size_t count) | 159 | static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) |
160 | { | 160 | { |
161 | static char buf[4096]; | 161 | static char buf[4096]; |
162 | int offs = 0, size; | 162 | int offs = 0, size; |
@@ -267,7 +267,9 @@ struct zcore_header { | |||
267 | u64 tod; | 267 | u64 tod; |
268 | cpuid_t cpu_id; | 268 | cpuid_t cpu_id; |
269 | u32 arch_id; | 269 | u32 arch_id; |
270 | u32 volnr; | ||
270 | u32 build_arch; | 271 | u32 build_arch; |
272 | u64 rmem_size; | ||
271 | char pad2[4016]; | 273 | char pad2[4016]; |
272 | } __attribute__((packed,__aligned__(16))); | 274 | } __attribute__((packed,__aligned__(16))); |
273 | 275 | ||
@@ -559,6 +561,7 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr) | |||
559 | else | 561 | else |
560 | hdr->arch_id = DUMP_ARCH_S390; | 562 | hdr->arch_id = DUMP_ARCH_S390; |
561 | hdr->mem_size = sys_info.mem_size; | 563 | hdr->mem_size = sys_info.mem_size; |
564 | hdr->rmem_size = sys_info.mem_size; | ||
562 | hdr->mem_end = sys_info.mem_size; | 565 | hdr->mem_end = sys_info.mem_size; |
563 | hdr->num_pages = sys_info.mem_size / PAGE_SIZE; | 566 | hdr->num_pages = sys_info.mem_size / PAGE_SIZE; |
564 | hdr->tod = get_clock(); | 567 | hdr->tod = get_clock(); |
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index ac289e6eadfe..b57d93d986c0 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -141,8 +141,9 @@ static int s390_vary_chpid(struct chp_id chpid, int on) | |||
141 | /* | 141 | /* |
142 | * Channel measurement related functions | 142 | * Channel measurement related functions |
143 | */ | 143 | */ |
144 | static ssize_t chp_measurement_chars_read(struct kobject *kobj, char *buf, | 144 | static ssize_t chp_measurement_chars_read(struct kobject *kobj, |
145 | loff_t off, size_t count) | 145 | struct bin_attribute *bin_attr, |
146 | char *buf, loff_t off, size_t count) | ||
146 | { | 147 | { |
147 | struct channel_path *chp; | 148 | struct channel_path *chp; |
148 | unsigned int size; | 149 | unsigned int size; |
@@ -165,7 +166,6 @@ static struct bin_attribute chp_measurement_chars_attr = { | |||
165 | .attr = { | 166 | .attr = { |
166 | .name = "measurement_chars", | 167 | .name = "measurement_chars", |
167 | .mode = S_IRUSR, | 168 | .mode = S_IRUSR, |
168 | .owner = THIS_MODULE, | ||
169 | }, | 169 | }, |
170 | .size = sizeof(struct cmg_chars), | 170 | .size = sizeof(struct cmg_chars), |
171 | .read = chp_measurement_chars_read, | 171 | .read = chp_measurement_chars_read, |
@@ -193,8 +193,9 @@ static void chp_measurement_copy_block(struct cmg_entry *buf, | |||
193 | } while (reference_buf.values[0] != buf->values[0]); | 193 | } while (reference_buf.values[0] != buf->values[0]); |
194 | } | 194 | } |
195 | 195 | ||
196 | static ssize_t chp_measurement_read(struct kobject *kobj, char *buf, | 196 | static ssize_t chp_measurement_read(struct kobject *kobj, |
197 | loff_t off, size_t count) | 197 | struct bin_attribute *bin_attr, |
198 | char *buf, loff_t off, size_t count) | ||
198 | { | 199 | { |
199 | struct channel_path *chp; | 200 | struct channel_path *chp; |
200 | struct channel_subsystem *css; | 201 | struct channel_subsystem *css; |
@@ -217,7 +218,6 @@ static struct bin_attribute chp_measurement_attr = { | |||
217 | .attr = { | 218 | .attr = { |
218 | .name = "measurement", | 219 | .name = "measurement", |
219 | .mode = S_IRUSR, | 220 | .mode = S_IRUSR, |
220 | .owner = THIS_MODULE, | ||
221 | }, | 221 | }, |
222 | .size = sizeof(struct cmg_entry), | 222 | .size = sizeof(struct cmg_entry), |
223 | .read = chp_measurement_read, | 223 | .read = chp_measurement_read, |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index a8b373f69cf0..6b264bdb5bfb 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -296,30 +296,57 @@ static void ccw_device_unregister(struct ccw_device *cdev) | |||
296 | device_del(&cdev->dev); | 296 | device_del(&cdev->dev); |
297 | } | 297 | } |
298 | 298 | ||
299 | static void ccw_device_remove_orphan_cb(struct device *dev) | ||
300 | { | ||
301 | struct ccw_device *cdev = to_ccwdev(dev); | ||
302 | |||
303 | ccw_device_unregister(cdev); | ||
304 | put_device(&cdev->dev); | ||
305 | } | ||
306 | |||
307 | static void ccw_device_remove_sch_cb(struct device *dev) | ||
308 | { | ||
309 | struct subchannel *sch; | ||
310 | |||
311 | sch = to_subchannel(dev); | ||
312 | css_sch_device_unregister(sch); | ||
313 | /* Reset intparm to zeroes. */ | ||
314 | sch->schib.pmcw.intparm = 0; | ||
315 | cio_modify(sch); | ||
316 | put_device(&sch->dev); | ||
317 | } | ||
318 | |||
299 | static void | 319 | static void |
300 | ccw_device_remove_disconnected(struct ccw_device *cdev) | 320 | ccw_device_remove_disconnected(struct ccw_device *cdev) |
301 | { | 321 | { |
302 | struct subchannel *sch; | ||
303 | unsigned long flags; | 322 | unsigned long flags; |
323 | int rc; | ||
324 | |||
304 | /* | 325 | /* |
305 | * Forced offline in disconnected state means | 326 | * Forced offline in disconnected state means |
306 | * 'throw away device'. | 327 | * 'throw away device'. |
307 | */ | 328 | */ |
308 | if (ccw_device_is_orphan(cdev)) { | 329 | if (ccw_device_is_orphan(cdev)) { |
309 | /* Deregister ccw device. */ | 330 | /* |
331 | * Deregister ccw device. | ||
332 | * Unfortunately, we cannot do this directly from the | ||
333 | * attribute method. | ||
334 | */ | ||
310 | spin_lock_irqsave(cdev->ccwlock, flags); | 335 | spin_lock_irqsave(cdev->ccwlock, flags); |
311 | cdev->private->state = DEV_STATE_NOT_OPER; | 336 | cdev->private->state = DEV_STATE_NOT_OPER; |
312 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 337 | spin_unlock_irqrestore(cdev->ccwlock, flags); |
313 | ccw_device_unregister(cdev); | 338 | rc = device_schedule_callback(&cdev->dev, |
314 | put_device(&cdev->dev); | 339 | ccw_device_remove_orphan_cb); |
315 | return ; | 340 | if (rc) |
341 | dev_info(&cdev->dev, "Couldn't unregister orphan\n"); | ||
342 | return; | ||
316 | } | 343 | } |
317 | sch = to_subchannel(cdev->dev.parent); | 344 | /* Deregister subchannel, which will kill the ccw device. */ |
318 | css_sch_device_unregister(sch); | 345 | rc = device_schedule_callback(cdev->dev.parent, |
319 | /* Reset intparm to zeroes. */ | 346 | ccw_device_remove_sch_cb); |
320 | sch->schib.pmcw.intparm = 0; | 347 | if (rc) |
321 | cio_modify(sch); | 348 | dev_info(&cdev->dev, |
322 | put_device(&sch->dev); | 349 | "Couldn't unregister disconnected device\n"); |
323 | } | 350 | } |
324 | 351 | ||
325 | int | 352 | int |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 898ec3b2bebb..6bba80929577 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -688,6 +688,12 @@ ccw_device_disband_done(struct ccw_device *cdev, int err) | |||
688 | ccw_device_done(cdev, DEV_STATE_BOXED); | 688 | ccw_device_done(cdev, DEV_STATE_BOXED); |
689 | break; | 689 | break; |
690 | default: | 690 | default: |
691 | cdev->private->flags.donotify = 0; | ||
692 | if (get_device(&cdev->dev)) { | ||
693 | PREPARE_WORK(&cdev->private->kick_work, | ||
694 | ccw_device_call_sch_unregister); | ||
695 | queue_work(ccw_device_work, &cdev->private->kick_work); | ||
696 | } | ||
691 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 697 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
692 | break; | 698 | break; |
693 | } | 699 | } |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 997f46874537..60b9347f7c92 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
@@ -27,7 +27,6 @@ | |||
27 | /* | 27 | /* |
28 | * diag210 is used under VM to get information about a virtual device | 28 | * diag210 is used under VM to get information about a virtual device |
29 | */ | 29 | */ |
30 | #ifdef CONFIG_64BIT | ||
31 | int | 30 | int |
32 | diag210(struct diag210 * addr) | 31 | diag210(struct diag210 * addr) |
33 | { | 32 | { |
@@ -43,6 +42,7 @@ diag210(struct diag210 * addr) | |||
43 | spin_lock_irqsave(&diag210_lock, flags); | 42 | spin_lock_irqsave(&diag210_lock, flags); |
44 | diag210_tmp = *addr; | 43 | diag210_tmp = *addr; |
45 | 44 | ||
45 | #ifdef CONFIG_64BIT | ||
46 | asm volatile( | 46 | asm volatile( |
47 | " lhi %0,-1\n" | 47 | " lhi %0,-1\n" |
48 | " sam31\n" | 48 | " sam31\n" |
@@ -51,19 +51,8 @@ diag210(struct diag210 * addr) | |||
51 | " srl %0,28\n" | 51 | " srl %0,28\n" |
52 | "1: sam64\n" | 52 | "1: sam64\n" |
53 | EX_TABLE(0b,1b) | 53 | EX_TABLE(0b,1b) |
54 | : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); | 54 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
55 | |||
56 | *addr = diag210_tmp; | ||
57 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
58 | |||
59 | return ccode; | ||
60 | } | ||
61 | #else | 55 | #else |
62 | int | ||
63 | diag210(struct diag210 * addr) | ||
64 | { | ||
65 | int ccode; | ||
66 | |||
67 | asm volatile( | 56 | asm volatile( |
68 | " lhi %0,-1\n" | 57 | " lhi %0,-1\n" |
69 | " diag %1,0,0x210\n" | 58 | " diag %1,0,0x210\n" |
@@ -71,11 +60,14 @@ diag210(struct diag210 * addr) | |||
71 | " srl %0,28\n" | 60 | " srl %0,28\n" |
72 | "1:\n" | 61 | "1:\n" |
73 | EX_TABLE(0b,1b) | 62 | EX_TABLE(0b,1b) |
74 | : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); | 63 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
64 | #endif | ||
65 | |||
66 | *addr = diag210_tmp; | ||
67 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
75 | 68 | ||
76 | return ccode; | 69 | return ccode; |
77 | } | 70 | } |
78 | #endif | ||
79 | 71 | ||
80 | /* | 72 | /* |
81 | * Input : | 73 | * Input : |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 5aac0ec36368..90bd22014513 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long); | |||
43 | static void ap_poll_timeout(unsigned long); | 43 | static void ap_poll_timeout(unsigned long); |
44 | static int ap_poll_thread_start(void); | 44 | static int ap_poll_thread_start(void); |
45 | static void ap_poll_thread_stop(void); | 45 | static void ap_poll_thread_stop(void); |
46 | static void ap_request_timeout(unsigned long); | ||
46 | 47 | ||
47 | /** | 48 | /** |
48 | * Module description. | 49 | * Module description. |
@@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length) | |||
189 | case AP_RESPONSE_NORMAL: | 190 | case AP_RESPONSE_NORMAL: |
190 | return 0; | 191 | return 0; |
191 | case AP_RESPONSE_Q_FULL: | 192 | case AP_RESPONSE_Q_FULL: |
193 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
192 | return -EBUSY; | 194 | return -EBUSY; |
193 | default: /* Device is gone. */ | 195 | default: /* Device is gone. */ |
194 | return -ENODEV; | 196 | return -ENODEV; |
@@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) | |||
252 | if (status.queue_empty) | 254 | if (status.queue_empty) |
253 | return -ENOENT; | 255 | return -ENOENT; |
254 | return -EBUSY; | 256 | return -EBUSY; |
257 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
258 | return -EBUSY; | ||
255 | default: | 259 | default: |
256 | return -ENODEV; | 260 | return -ENODEV; |
257 | } | 261 | } |
@@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid) | |||
326 | i = AP_MAX_RESET; /* return with -ENODEV */ | 330 | i = AP_MAX_RESET; /* return with -ENODEV */ |
327 | break; | 331 | break; |
328 | case AP_RESPONSE_RESET_IN_PROGRESS: | 332 | case AP_RESPONSE_RESET_IN_PROGRESS: |
333 | rc = -EBUSY; | ||
329 | case AP_RESPONSE_BUSY: | 334 | case AP_RESPONSE_BUSY: |
330 | default: | 335 | default: |
331 | break; | 336 | break; |
332 | } | 337 | } |
333 | if (rc != -ENODEV) | 338 | if (rc != -ENODEV && rc != -EBUSY) |
334 | break; | 339 | break; |
335 | if (i < AP_MAX_RESET - 1) { | 340 | if (i < AP_MAX_RESET - 1) { |
336 | udelay(5); | 341 | udelay(5); |
@@ -341,6 +346,40 @@ static int ap_init_queue(ap_qid_t qid) | |||
341 | } | 346 | } |
342 | 347 | ||
343 | /** | 348 | /** |
349 | * Arm request timeout if a AP device was idle and a new request is submitted. | ||
350 | */ | ||
351 | static void ap_increase_queue_count(struct ap_device *ap_dev) | ||
352 | { | ||
353 | int timeout = ap_dev->drv->request_timeout; | ||
354 | |||
355 | ap_dev->queue_count++; | ||
356 | if (ap_dev->queue_count == 1) { | ||
357 | mod_timer(&ap_dev->timeout, jiffies + timeout); | ||
358 | ap_dev->reset = AP_RESET_ARMED; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * AP device is still alive, re-schedule request timeout if there are still | ||
364 | * pending requests. | ||
365 | */ | ||
366 | static void ap_decrease_queue_count(struct ap_device *ap_dev) | ||
367 | { | ||
368 | int timeout = ap_dev->drv->request_timeout; | ||
369 | |||
370 | ap_dev->queue_count--; | ||
371 | if (ap_dev->queue_count > 0) | ||
372 | mod_timer(&ap_dev->timeout, jiffies + timeout); | ||
373 | else | ||
374 | /** | ||
375 | * The timeout timer should to be disabled now - since | ||
376 | * del_timer_sync() is very expensive, we just tell via the | ||
377 | * reset flag to ignore the pending timeout timer. | ||
378 | */ | ||
379 | ap_dev->reset = AP_RESET_IGNORE; | ||
380 | } | ||
381 | |||
382 | /** | ||
344 | * AP device related attributes. | 383 | * AP device related attributes. |
345 | */ | 384 | */ |
346 | static ssize_t ap_hwtype_show(struct device *dev, | 385 | static ssize_t ap_hwtype_show(struct device *dev, |
@@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev) | |||
498 | struct ap_driver *ap_drv = ap_dev->drv; | 537 | struct ap_driver *ap_drv = ap_dev->drv; |
499 | 538 | ||
500 | ap_flush_queue(ap_dev); | 539 | ap_flush_queue(ap_dev); |
540 | del_timer_sync(&ap_dev->timeout); | ||
501 | if (ap_drv->remove) | 541 | if (ap_drv->remove) |
502 | ap_drv->remove(ap_dev); | 542 | ap_drv->remove(ap_dev); |
503 | spin_lock_bh(&ap_device_lock); | 543 | spin_lock_bh(&ap_device_lock); |
@@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused) | |||
759 | __ap_scan_bus); | 799 | __ap_scan_bus); |
760 | rc = ap_query_queue(qid, &queue_depth, &device_type); | 800 | rc = ap_query_queue(qid, &queue_depth, &device_type); |
761 | if (dev) { | 801 | if (dev) { |
802 | if (rc == -EBUSY) { | ||
803 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
804 | schedule_timeout(AP_RESET_TIMEOUT); | ||
805 | rc = ap_query_queue(qid, &queue_depth, | ||
806 | &device_type); | ||
807 | } | ||
762 | ap_dev = to_ap_dev(dev); | 808 | ap_dev = to_ap_dev(dev); |
763 | spin_lock_bh(&ap_dev->lock); | 809 | spin_lock_bh(&ap_dev->lock); |
764 | if (rc || ap_dev->unregistered) { | 810 | if (rc || ap_dev->unregistered) { |
765 | spin_unlock_bh(&ap_dev->lock); | 811 | spin_unlock_bh(&ap_dev->lock); |
766 | put_device(dev); | ||
767 | device_unregister(dev); | 812 | device_unregister(dev); |
813 | put_device(dev); | ||
768 | continue; | 814 | continue; |
769 | } else | 815 | } |
770 | spin_unlock_bh(&ap_dev->lock); | 816 | spin_unlock_bh(&ap_dev->lock); |
771 | } | ||
772 | if (dev) { | ||
773 | put_device(dev); | 817 | put_device(dev); |
774 | continue; | 818 | continue; |
775 | } | 819 | } |
@@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused) | |||
788 | INIT_LIST_HEAD(&ap_dev->pendingq); | 832 | INIT_LIST_HEAD(&ap_dev->pendingq); |
789 | INIT_LIST_HEAD(&ap_dev->requestq); | 833 | INIT_LIST_HEAD(&ap_dev->requestq); |
790 | INIT_LIST_HEAD(&ap_dev->list); | 834 | INIT_LIST_HEAD(&ap_dev->list); |
835 | setup_timer(&ap_dev->timeout, ap_request_timeout, | ||
836 | (unsigned long) ap_dev); | ||
791 | if (device_type == 0) | 837 | if (device_type == 0) |
792 | ap_probe_device_type(ap_dev); | 838 | ap_probe_device_type(ap_dev); |
793 | else | 839 | else |
@@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) | |||
853 | switch (status.response_code) { | 899 | switch (status.response_code) { |
854 | case AP_RESPONSE_NORMAL: | 900 | case AP_RESPONSE_NORMAL: |
855 | atomic_dec(&ap_poll_requests); | 901 | atomic_dec(&ap_poll_requests); |
856 | ap_dev->queue_count--; | 902 | ap_decrease_queue_count(ap_dev); |
857 | list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { | 903 | list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { |
858 | if (ap_msg->psmid != ap_dev->reply->psmid) | 904 | if (ap_msg->psmid != ap_dev->reply->psmid) |
859 | continue; | 905 | continue; |
@@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) | |||
904 | switch (status.response_code) { | 950 | switch (status.response_code) { |
905 | case AP_RESPONSE_NORMAL: | 951 | case AP_RESPONSE_NORMAL: |
906 | atomic_inc(&ap_poll_requests); | 952 | atomic_inc(&ap_poll_requests); |
907 | ap_dev->queue_count++; | 953 | ap_increase_queue_count(ap_dev); |
908 | list_move_tail(&ap_msg->list, &ap_dev->pendingq); | 954 | list_move_tail(&ap_msg->list, &ap_dev->pendingq); |
909 | ap_dev->requestq_count--; | 955 | ap_dev->requestq_count--; |
910 | ap_dev->pendingq_count++; | 956 | ap_dev->pendingq_count++; |
@@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) | |||
914 | *flags |= 2; | 960 | *flags |= 2; |
915 | break; | 961 | break; |
916 | case AP_RESPONSE_Q_FULL: | 962 | case AP_RESPONSE_Q_FULL: |
963 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
917 | *flags |= 2; | 964 | *flags |= 2; |
918 | break; | 965 | break; |
919 | case AP_RESPONSE_MESSAGE_TOO_BIG: | 966 | case AP_RESPONSE_MESSAGE_TOO_BIG: |
@@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms | |||
960 | list_add_tail(&ap_msg->list, &ap_dev->pendingq); | 1007 | list_add_tail(&ap_msg->list, &ap_dev->pendingq); |
961 | atomic_inc(&ap_poll_requests); | 1008 | atomic_inc(&ap_poll_requests); |
962 | ap_dev->pendingq_count++; | 1009 | ap_dev->pendingq_count++; |
963 | ap_dev->queue_count++; | 1010 | ap_increase_queue_count(ap_dev); |
964 | ap_dev->total_request_count++; | 1011 | ap_dev->total_request_count++; |
965 | break; | 1012 | break; |
966 | case AP_RESPONSE_Q_FULL: | 1013 | case AP_RESPONSE_Q_FULL: |
1014 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
967 | list_add_tail(&ap_msg->list, &ap_dev->requestq); | 1015 | list_add_tail(&ap_msg->list, &ap_dev->requestq); |
968 | ap_dev->requestq_count++; | 1016 | ap_dev->requestq_count++; |
969 | ap_dev->total_request_count++; | 1017 | ap_dev->total_request_count++; |
@@ -1046,6 +1094,25 @@ static void ap_poll_timeout(unsigned long unused) | |||
1046 | } | 1094 | } |
1047 | 1095 | ||
1048 | /** | 1096 | /** |
1097 | * Reset a not responding AP device and move all requests from the | ||
1098 | * pending queue to the request queue. | ||
1099 | */ | ||
1100 | static void ap_reset(struct ap_device *ap_dev) | ||
1101 | { | ||
1102 | int rc; | ||
1103 | |||
1104 | ap_dev->reset = AP_RESET_IGNORE; | ||
1105 | atomic_sub(ap_dev->queue_count, &ap_poll_requests); | ||
1106 | ap_dev->queue_count = 0; | ||
1107 | list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); | ||
1108 | ap_dev->requestq_count += ap_dev->pendingq_count; | ||
1109 | ap_dev->pendingq_count = 0; | ||
1110 | rc = ap_init_queue(ap_dev->qid); | ||
1111 | if (rc == -ENODEV) | ||
1112 | ap_dev->unregistered = 1; | ||
1113 | } | ||
1114 | |||
1115 | /** | ||
1049 | * Poll all AP devices on the bus in a round robin fashion. Continue | 1116 | * Poll all AP devices on the bus in a round robin fashion. Continue |
1050 | * polling until bit 2^0 of the control flags is not set. If bit 2^1 | 1117 | * polling until bit 2^0 of the control flags is not set. If bit 2^1 |
1051 | * of the control flags has been set arm the poll timer. | 1118 | * of the control flags has been set arm the poll timer. |
@@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) | |||
1056 | if (!ap_dev->unregistered) { | 1123 | if (!ap_dev->unregistered) { |
1057 | if (ap_poll_queue(ap_dev, flags)) | 1124 | if (ap_poll_queue(ap_dev, flags)) |
1058 | ap_dev->unregistered = 1; | 1125 | ap_dev->unregistered = 1; |
1126 | if (ap_dev->reset == AP_RESET_DO) | ||
1127 | ap_reset(ap_dev); | ||
1059 | } | 1128 | } |
1060 | spin_unlock(&ap_dev->lock); | 1129 | spin_unlock(&ap_dev->lock); |
1061 | return 0; | 1130 | return 0; |
@@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void) | |||
1147 | mutex_unlock(&ap_poll_thread_mutex); | 1216 | mutex_unlock(&ap_poll_thread_mutex); |
1148 | } | 1217 | } |
1149 | 1218 | ||
1219 | /** | ||
1220 | * Handling of request timeouts | ||
1221 | */ | ||
1222 | static void ap_request_timeout(unsigned long data) | ||
1223 | { | ||
1224 | struct ap_device *ap_dev = (struct ap_device *) data; | ||
1225 | |||
1226 | if (ap_dev->reset == AP_RESET_ARMED) | ||
1227 | ap_dev->reset = AP_RESET_DO; | ||
1228 | } | ||
1229 | |||
1150 | static void ap_reset_domain(void) | 1230 | static void ap_reset_domain(void) |
1151 | { | 1231 | { |
1152 | int i; | 1232 | int i; |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 008559ea742b..87c2d6442875 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define AP_DEVICES 64 /* Number of AP devices. */ | 33 | #define AP_DEVICES 64 /* Number of AP devices. */ |
34 | #define AP_DOMAINS 16 /* Number of AP domains. */ | 34 | #define AP_DOMAINS 16 /* Number of AP domains. */ |
35 | #define AP_MAX_RESET 90 /* Maximum number of resets. */ | 35 | #define AP_MAX_RESET 90 /* Maximum number of resets. */ |
36 | #define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */ | ||
36 | #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ | 37 | #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ |
37 | #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ | 38 | #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ |
38 | 39 | ||
@@ -83,6 +84,13 @@ struct ap_queue_status { | |||
83 | #define AP_DEVICE_TYPE_CEX2A 6 | 84 | #define AP_DEVICE_TYPE_CEX2A 6 |
84 | #define AP_DEVICE_TYPE_CEX2C 7 | 85 | #define AP_DEVICE_TYPE_CEX2C 7 |
85 | 86 | ||
87 | /** | ||
88 | * AP reset flag states | ||
89 | */ | ||
90 | #define AP_RESET_IGNORE 0 /* request timeout will be ignored */ | ||
91 | #define AP_RESET_ARMED 1 /* request timeout timer is active */ | ||
92 | #define AP_RESET_DO 2 /* AP reset required */ | ||
93 | |||
86 | struct ap_device; | 94 | struct ap_device; |
87 | struct ap_message; | 95 | struct ap_message; |
88 | 96 | ||
@@ -95,6 +103,7 @@ struct ap_driver { | |||
95 | /* receive is called from tasklet context */ | 103 | /* receive is called from tasklet context */ |
96 | void (*receive)(struct ap_device *, struct ap_message *, | 104 | void (*receive)(struct ap_device *, struct ap_message *, |
97 | struct ap_message *); | 105 | struct ap_message *); |
106 | int request_timeout; /* request timeout in jiffies */ | ||
98 | }; | 107 | }; |
99 | 108 | ||
100 | #define to_ap_drv(x) container_of((x), struct ap_driver, driver) | 109 | #define to_ap_drv(x) container_of((x), struct ap_driver, driver) |
@@ -112,6 +121,8 @@ struct ap_device { | |||
112 | int queue_depth; /* AP queue depth.*/ | 121 | int queue_depth; /* AP queue depth.*/ |
113 | int device_type; /* AP device type. */ | 122 | int device_type; /* AP device type. */ |
114 | int unregistered; /* marks AP device as unregistered */ | 123 | int unregistered; /* marks AP device as unregistered */ |
124 | struct timer_list timeout; /* Timer for request timeouts. */ | ||
125 | int reset; /* Reset required after req. timeout. */ | ||
115 | 126 | ||
116 | int queue_count; /* # messages currently on AP queue. */ | 127 | int queue_count; /* # messages currently on AP queue. */ |
117 | 128 | ||
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 5bb13a9d0898..08657f604b8c 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c | |||
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = { | |||
70 | .remove = zcrypt_cex2a_remove, | 70 | .remove = zcrypt_cex2a_remove, |
71 | .receive = zcrypt_cex2a_receive, | 71 | .receive = zcrypt_cex2a_receive, |
72 | .ids = zcrypt_cex2a_ids, | 72 | .ids = zcrypt_cex2a_ids, |
73 | .request_timeout = CEX2A_CLEANUP_TIME, | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | /** | 76 | /** |
@@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, | |||
306 | goto out_free; | 307 | goto out_free; |
307 | init_completion(&work); | 308 | init_completion(&work); |
308 | ap_queue_message(zdev->ap_dev, &ap_msg); | 309 | ap_queue_message(zdev->ap_dev, &ap_msg); |
309 | rc = wait_for_completion_interruptible_timeout( | 310 | rc = wait_for_completion_interruptible(&work); |
310 | &work, CEX2A_CLEANUP_TIME); | 311 | if (rc == 0) |
311 | if (rc > 0) | ||
312 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 312 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
313 | mex->outputdatalength); | 313 | mex->outputdatalength); |
314 | else { | 314 | else |
315 | /* Signal pending or message timed out. */ | 315 | /* Signal pending. */ |
316 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 316 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
317 | if (rc == 0) | ||
318 | /* Message timed out. */ | ||
319 | rc = -ETIME; | ||
320 | } | ||
321 | out_free: | 317 | out_free: |
322 | kfree(ap_msg.message); | 318 | kfree(ap_msg.message); |
323 | return rc; | 319 | return rc; |
@@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, | |||
348 | goto out_free; | 344 | goto out_free; |
349 | init_completion(&work); | 345 | init_completion(&work); |
350 | ap_queue_message(zdev->ap_dev, &ap_msg); | 346 | ap_queue_message(zdev->ap_dev, &ap_msg); |
351 | rc = wait_for_completion_interruptible_timeout( | 347 | rc = wait_for_completion_interruptible(&work); |
352 | &work, CEX2A_CLEANUP_TIME); | 348 | if (rc == 0) |
353 | if (rc > 0) | ||
354 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 349 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
355 | crt->outputdatalength); | 350 | crt->outputdatalength); |
356 | else { | 351 | else |
357 | /* Signal pending or message timed out. */ | 352 | /* Signal pending. */ |
358 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 353 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
359 | if (rc == 0) | ||
360 | /* Message timed out. */ | ||
361 | rc = -ETIME; | ||
362 | } | ||
363 | out_free: | 354 | out_free: |
364 | kfree(ap_msg.message); | 355 | kfree(ap_msg.message); |
365 | return rc; | 356 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 818ffe05ac00..6e93b4751782 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c | |||
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = { | |||
70 | .remove = zcrypt_pcica_remove, | 70 | .remove = zcrypt_pcica_remove, |
71 | .receive = zcrypt_pcica_receive, | 71 | .receive = zcrypt_pcica_receive, |
72 | .ids = zcrypt_pcica_ids, | 72 | .ids = zcrypt_pcica_ids, |
73 | .request_timeout = PCICA_CLEANUP_TIME, | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | /** | 76 | /** |
@@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, | |||
290 | goto out_free; | 291 | goto out_free; |
291 | init_completion(&work); | 292 | init_completion(&work); |
292 | ap_queue_message(zdev->ap_dev, &ap_msg); | 293 | ap_queue_message(zdev->ap_dev, &ap_msg); |
293 | rc = wait_for_completion_interruptible_timeout( | 294 | rc = wait_for_completion_interruptible(&work); |
294 | &work, PCICA_CLEANUP_TIME); | 295 | if (rc == 0) |
295 | if (rc > 0) | ||
296 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 296 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
297 | mex->outputdatalength); | 297 | mex->outputdatalength); |
298 | else { | 298 | else |
299 | /* Signal pending or message timed out. */ | 299 | /* Signal pending. */ |
300 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 300 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
301 | if (rc == 0) | ||
302 | /* Message timed out. */ | ||
303 | rc = -ETIME; | ||
304 | } | ||
305 | out_free: | 301 | out_free: |
306 | kfree(ap_msg.message); | 302 | kfree(ap_msg.message); |
307 | return rc; | 303 | return rc; |
@@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, | |||
332 | goto out_free; | 328 | goto out_free; |
333 | init_completion(&work); | 329 | init_completion(&work); |
334 | ap_queue_message(zdev->ap_dev, &ap_msg); | 330 | ap_queue_message(zdev->ap_dev, &ap_msg); |
335 | rc = wait_for_completion_interruptible_timeout( | 331 | rc = wait_for_completion_interruptible(&work); |
336 | &work, PCICA_CLEANUP_TIME); | 332 | if (rc == 0) |
337 | if (rc > 0) | ||
338 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 333 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
339 | crt->outputdatalength); | 334 | crt->outputdatalength); |
340 | else { | 335 | else |
341 | /* Signal pending or message timed out. */ | 336 | /* Signal pending. */ |
342 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 337 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
343 | if (rc == 0) | ||
344 | /* Message timed out. */ | ||
345 | rc = -ETIME; | ||
346 | } | ||
347 | out_free: | 338 | out_free: |
348 | kfree(ap_msg.message); | 339 | kfree(ap_msg.message); |
349 | return rc; | 340 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index f295a403b29a..d6d59bf9ac38 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c | |||
@@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = { | |||
82 | .remove = zcrypt_pcicc_remove, | 82 | .remove = zcrypt_pcicc_remove, |
83 | .receive = zcrypt_pcicc_receive, | 83 | .receive = zcrypt_pcicc_receive, |
84 | .ids = zcrypt_pcicc_ids, | 84 | .ids = zcrypt_pcicc_ids, |
85 | .request_timeout = PCICC_CLEANUP_TIME, | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | /** | 88 | /** |
@@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev, | |||
501 | goto out_free; | 502 | goto out_free; |
502 | init_completion(&work); | 503 | init_completion(&work); |
503 | ap_queue_message(zdev->ap_dev, &ap_msg); | 504 | ap_queue_message(zdev->ap_dev, &ap_msg); |
504 | rc = wait_for_completion_interruptible_timeout( | 505 | rc = wait_for_completion_interruptible(&work); |
505 | &work, PCICC_CLEANUP_TIME); | 506 | if (rc == 0) |
506 | if (rc > 0) | ||
507 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 507 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
508 | mex->outputdatalength); | 508 | mex->outputdatalength); |
509 | else { | 509 | else |
510 | /* Signal pending or message timed out. */ | 510 | /* Signal pending. */ |
511 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 511 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
512 | if (rc == 0) | ||
513 | /* Message timed out. */ | ||
514 | rc = -ETIME; | ||
515 | } | ||
516 | out_free: | 512 | out_free: |
517 | free_page((unsigned long) ap_msg.message); | 513 | free_page((unsigned long) ap_msg.message); |
518 | return rc; | 514 | return rc; |
@@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev, | |||
544 | goto out_free; | 540 | goto out_free; |
545 | init_completion(&work); | 541 | init_completion(&work); |
546 | ap_queue_message(zdev->ap_dev, &ap_msg); | 542 | ap_queue_message(zdev->ap_dev, &ap_msg); |
547 | rc = wait_for_completion_interruptible_timeout( | 543 | rc = wait_for_completion_interruptible(&work); |
548 | &work, PCICC_CLEANUP_TIME); | 544 | if (rc == 0) |
549 | if (rc > 0) | ||
550 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 545 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
551 | crt->outputdatalength); | 546 | crt->outputdatalength); |
552 | else { | 547 | else |
553 | /* Signal pending or message timed out. */ | 548 | /* Signal pending. */ |
554 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 549 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
555 | if (rc == 0) | ||
556 | /* Message timed out. */ | ||
557 | rc = -ETIME; | ||
558 | } | ||
559 | out_free: | 550 | out_free: |
560 | free_page((unsigned long) ap_msg.message); | 551 | free_page((unsigned long) ap_msg.message); |
561 | return rc; | 552 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 252443b6bd1b..64948788d301 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = { | |||
93 | .remove = zcrypt_pcixcc_remove, | 93 | .remove = zcrypt_pcixcc_remove, |
94 | .receive = zcrypt_pcixcc_receive, | 94 | .receive = zcrypt_pcixcc_receive, |
95 | .ids = zcrypt_pcixcc_ids, | 95 | .ids = zcrypt_pcixcc_ids, |
96 | .request_timeout = PCIXCC_CLEANUP_TIME, | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | /** | 99 | /** |
@@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, | |||
641 | goto out_free; | 642 | goto out_free; |
642 | init_completion(&resp_type.work); | 643 | init_completion(&resp_type.work); |
643 | ap_queue_message(zdev->ap_dev, &ap_msg); | 644 | ap_queue_message(zdev->ap_dev, &ap_msg); |
644 | rc = wait_for_completion_interruptible_timeout( | 645 | rc = wait_for_completion_interruptible(&resp_type.work); |
645 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 646 | if (rc == 0) |
646 | if (rc > 0) | ||
647 | rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, | 647 | rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, |
648 | mex->outputdatalength); | 648 | mex->outputdatalength); |
649 | else { | 649 | else |
650 | /* Signal pending or message timed out. */ | 650 | /* Signal pending. */ |
651 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 651 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
652 | if (rc == 0) | ||
653 | /* Message timed out. */ | ||
654 | rc = -ETIME; | ||
655 | } | ||
656 | out_free: | 652 | out_free: |
657 | free_page((unsigned long) ap_msg.message); | 653 | free_page((unsigned long) ap_msg.message); |
658 | return rc; | 654 | return rc; |
@@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, | |||
685 | goto out_free; | 681 | goto out_free; |
686 | init_completion(&resp_type.work); | 682 | init_completion(&resp_type.work); |
687 | ap_queue_message(zdev->ap_dev, &ap_msg); | 683 | ap_queue_message(zdev->ap_dev, &ap_msg); |
688 | rc = wait_for_completion_interruptible_timeout( | 684 | rc = wait_for_completion_interruptible(&resp_type.work); |
689 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 685 | if (rc == 0) |
690 | if (rc > 0) | ||
691 | rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, | 686 | rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, |
692 | crt->outputdatalength); | 687 | crt->outputdatalength); |
693 | else { | 688 | else |
694 | /* Signal pending or message timed out. */ | 689 | /* Signal pending. */ |
695 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 690 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
696 | if (rc == 0) | ||
697 | /* Message timed out. */ | ||
698 | rc = -ETIME; | ||
699 | } | ||
700 | out_free: | 691 | out_free: |
701 | free_page((unsigned long) ap_msg.message); | 692 | free_page((unsigned long) ap_msg.message); |
702 | return rc; | 693 | return rc; |
@@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, | |||
729 | goto out_free; | 720 | goto out_free; |
730 | init_completion(&resp_type.work); | 721 | init_completion(&resp_type.work); |
731 | ap_queue_message(zdev->ap_dev, &ap_msg); | 722 | ap_queue_message(zdev->ap_dev, &ap_msg); |
732 | rc = wait_for_completion_interruptible_timeout( | 723 | rc = wait_for_completion_interruptible(&resp_type.work); |
733 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 724 | if (rc == 0) |
734 | if (rc > 0) | ||
735 | rc = convert_response_xcrb(zdev, &ap_msg, xcRB); | 725 | rc = convert_response_xcrb(zdev, &ap_msg, xcRB); |
736 | else { | 726 | else |
737 | /* Signal pending or message timed out. */ | 727 | /* Signal pending. */ |
738 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 728 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
739 | if (rc == 0) | ||
740 | /* Message timed out. */ | ||
741 | rc = -ETIME; | ||
742 | } | ||
743 | out_free: | 729 | out_free: |
744 | memset(ap_msg.message, 0x0, ap_msg.length); | 730 | memset(ap_msg.message, 0x0, ap_msg.length); |
745 | kfree(ap_msg.message); | 731 | kfree(ap_msg.message); |
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 6dd64d0c8d45..348bb7b82771 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c | |||
@@ -3912,6 +3912,7 @@ static int | |||
3912 | add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr) | 3912 | add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr) |
3913 | { | 3913 | { |
3914 | struct chbk *p_ch; | 3914 | struct chbk *p_ch; |
3915 | struct ccw_dev_id dev_id; | ||
3915 | 3916 | ||
3916 | #ifdef FUNCTRACE | 3917 | #ifdef FUNCTRACE |
3917 | printk(KERN_INFO "%s:%s Enter\n",cdev->dev.bus_id,__FUNCTION__); | 3918 | printk(KERN_INFO "%s:%s Enter\n",cdev->dev.bus_id,__FUNCTION__); |
@@ -3921,7 +3922,8 @@ add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr) | |||
3921 | p_ch = &privptr->channel[i]; | 3922 | p_ch = &privptr->channel[i]; |
3922 | p_ch->cdev = cdev; | 3923 | p_ch->cdev = cdev; |
3923 | snprintf(p_ch->id, CLAW_ID_SIZE, "cl-%s", cdev->dev.bus_id); | 3924 | snprintf(p_ch->id, CLAW_ID_SIZE, "cl-%s", cdev->dev.bus_id); |
3924 | sscanf(cdev->dev.bus_id+4,"%x",&p_ch->devno); | 3925 | ccw_device_get_id(cdev, &dev_id); |
3926 | p_ch->devno = dev_id.devno; | ||
3925 | if ((p_ch->irb = kmalloc(sizeof (struct irb),GFP_KERNEL)) == NULL) { | 3927 | if ((p_ch->irb = kmalloc(sizeof (struct irb),GFP_KERNEL)) == NULL) { |
3926 | printk(KERN_WARNING "%s Out of memory in %s for irb\n", | 3928 | printk(KERN_WARNING "%s Out of memory in %s for irb\n", |
3927 | p_ch->id,__FUNCTION__); | 3929 | p_ch->id,__FUNCTION__); |
@@ -3955,6 +3957,7 @@ claw_new_device(struct ccwgroup_device *cgdev) | |||
3955 | struct claw_env *p_env; | 3957 | struct claw_env *p_env; |
3956 | struct net_device *dev; | 3958 | struct net_device *dev; |
3957 | int ret; | 3959 | int ret; |
3960 | struct ccw_dev_id dev_id; | ||
3958 | 3961 | ||
3959 | pr_debug("%s() called\n", __FUNCTION__); | 3962 | pr_debug("%s() called\n", __FUNCTION__); |
3960 | printk(KERN_INFO "claw: add for %s\n",cgdev->cdev[READ]->dev.bus_id); | 3963 | printk(KERN_INFO "claw: add for %s\n",cgdev->cdev[READ]->dev.bus_id); |
@@ -3965,10 +3968,10 @@ claw_new_device(struct ccwgroup_device *cgdev) | |||
3965 | if (!privptr) | 3968 | if (!privptr) |
3966 | return -ENODEV; | 3969 | return -ENODEV; |
3967 | p_env = privptr->p_env; | 3970 | p_env = privptr->p_env; |
3968 | sscanf(cgdev->cdev[READ]->dev.bus_id+4,"%x", | 3971 | ccw_device_get_id(cgdev->cdev[READ], &dev_id); |
3969 | &p_env->devno[READ]); | 3972 | p_env->devno[READ] = dev_id.devno; |
3970 | sscanf(cgdev->cdev[WRITE]->dev.bus_id+4,"%x", | 3973 | ccw_device_get_id(cgdev->cdev[WRITE], &dev_id); |
3971 | &p_env->devno[WRITE]); | 3974 | p_env->devno[WRITE] = dev_id.devno; |
3972 | ret = add_channel(cgdev->cdev[0],0,privptr); | 3975 | ret = add_channel(cgdev->cdev[0],0,privptr); |
3973 | if (ret == 0) | 3976 | if (ret == 0) |
3974 | ret = add_channel(cgdev->cdev[1],1,privptr); | 3977 | ret = add_channel(cgdev->cdev[1],1,privptr); |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index c358764f3264..3d28e1a5bf79 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -134,18 +134,6 @@ PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ | |||
134 | *(((char*)ptr)+28),*(((char*)ptr)+29), \ | 134 | *(((char*)ptr)+28),*(((char*)ptr)+29), \ |
135 | *(((char*)ptr)+30),*(((char*)ptr)+31)); | 135 | *(((char*)ptr)+30),*(((char*)ptr)+31)); |
136 | 136 | ||
137 | static inline void iucv_hex_dump(unsigned char *buf, size_t len) | ||
138 | { | ||
139 | size_t i; | ||
140 | |||
141 | for (i = 0; i < len; i++) { | ||
142 | if (i && !(i % 16)) | ||
143 | printk("\n"); | ||
144 | printk("%02x ", *(buf + i)); | ||
145 | } | ||
146 | printk("\n"); | ||
147 | } | ||
148 | |||
149 | #define PRINTK_HEADER " iucv: " /* for debugging */ | 137 | #define PRINTK_HEADER " iucv: " /* for debugging */ |
150 | 138 | ||
151 | static struct device_driver netiucv_driver = { | 139 | static struct device_driver netiucv_driver = { |
@@ -212,7 +200,7 @@ struct iucv_connection { | |||
212 | */ | 200 | */ |
213 | static struct list_head iucv_connection_list = | 201 | static struct list_head iucv_connection_list = |
214 | LIST_HEAD_INIT(iucv_connection_list); | 202 | LIST_HEAD_INIT(iucv_connection_list); |
215 | static rwlock_t iucv_connection_rwlock = RW_LOCK_UNLOCKED; | 203 | static DEFINE_RWLOCK(iucv_connection_rwlock); |
216 | 204 | ||
217 | /** | 205 | /** |
218 | * Representation of event-data for the | 206 | * Representation of event-data for the |
@@ -280,7 +268,7 @@ static u8 iucvMagic[16] = { | |||
280 | * | 268 | * |
281 | * @returns The printable string (static data!!) | 269 | * @returns The printable string (static data!!) |
282 | */ | 270 | */ |
283 | static inline char *netiucv_printname(char *name) | 271 | static char *netiucv_printname(char *name) |
284 | { | 272 | { |
285 | static char tmp[9]; | 273 | static char tmp[9]; |
286 | char *p = tmp; | 274 | char *p = tmp; |
@@ -1315,7 +1303,8 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) | |||
1315 | * and throw away packet. | 1303 | * and throw away packet. |
1316 | */ | 1304 | */ |
1317 | if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { | 1305 | if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { |
1318 | fsm_event(privptr->fsm, DEV_EVENT_START, dev); | 1306 | if (!in_atomic()) |
1307 | fsm_event(privptr->fsm, DEV_EVENT_START, dev); | ||
1319 | dev_kfree_skb(skb); | 1308 | dev_kfree_skb(skb); |
1320 | privptr->stats.tx_dropped++; | 1309 | privptr->stats.tx_dropped++; |
1321 | privptr->stats.tx_errors++; | 1310 | privptr->stats.tx_errors++; |
@@ -1729,7 +1718,7 @@ static struct attribute_group netiucv_stat_attr_group = { | |||
1729 | .attrs = netiucv_stat_attrs, | 1718 | .attrs = netiucv_stat_attrs, |
1730 | }; | 1719 | }; |
1731 | 1720 | ||
1732 | static inline int netiucv_add_files(struct device *dev) | 1721 | static int netiucv_add_files(struct device *dev) |
1733 | { | 1722 | { |
1734 | int ret; | 1723 | int ret; |
1735 | 1724 | ||
@@ -1743,7 +1732,7 @@ static inline int netiucv_add_files(struct device *dev) | |||
1743 | return ret; | 1732 | return ret; |
1744 | } | 1733 | } |
1745 | 1734 | ||
1746 | static inline void netiucv_remove_files(struct device *dev) | 1735 | static void netiucv_remove_files(struct device *dev) |
1747 | { | 1736 | { |
1748 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 1737 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
1749 | sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group); | 1738 | sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group); |
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 4640f32daae5..70108fb16906 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c | |||
@@ -424,8 +424,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, | |||
424 | /* prepare qdio hdr */ | 424 | /* prepare qdio hdr */ |
425 | if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ | 425 | if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ |
426 | eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN + | 426 | eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN + |
427 | eddp->nhl + eddp->thl - | 427 | eddp->nhl + eddp->thl; |
428 | sizeof(struct qeth_hdr); | ||
429 | #ifdef CONFIG_QETH_VLAN | 428 | #ifdef CONFIG_QETH_VLAN |
430 | if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) | 429 | if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) |
431 | eddp->qh.hdr.l2.pkt_length += VLAN_HLEN; | 430 | eddp->qh.hdr.l2.pkt_length += VLAN_HLEN; |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 0b96d49dd636..86b0c44165c1 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -986,15 +986,15 @@ qeth_recover(void *ptr) | |||
986 | card->use_hard_stop = 1; | 986 | card->use_hard_stop = 1; |
987 | __qeth_set_offline(card->gdev,1); | 987 | __qeth_set_offline(card->gdev,1); |
988 | rc = __qeth_set_online(card->gdev,1); | 988 | rc = __qeth_set_online(card->gdev,1); |
989 | /* don't run another scheduled recovery */ | ||
990 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); | ||
991 | qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); | ||
989 | if (!rc) | 992 | if (!rc) |
990 | PRINT_INFO("Device %s successfully recovered!\n", | 993 | PRINT_INFO("Device %s successfully recovered!\n", |
991 | CARD_BUS_ID(card)); | 994 | CARD_BUS_ID(card)); |
992 | else | 995 | else |
993 | PRINT_INFO("Device %s could not be recovered!\n", | 996 | PRINT_INFO("Device %s could not be recovered!\n", |
994 | CARD_BUS_ID(card)); | 997 | CARD_BUS_ID(card)); |
995 | /* don't run another scheduled recovery */ | ||
996 | qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); | ||
997 | qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); | ||
998 | return 0; | 998 | return 0; |
999 | } | 999 | } |
1000 | 1000 | ||
@@ -2176,13 +2176,6 @@ qeth_ulp_enable(struct qeth_card *card) | |||
2176 | 2176 | ||
2177 | } | 2177 | } |
2178 | 2178 | ||
2179 | static inline __u16 | ||
2180 | __raw_devno_from_bus_id(char *id) | ||
2181 | { | ||
2182 | id += (strlen(id) - 4); | ||
2183 | return (__u16) simple_strtoul(id, &id, 16); | ||
2184 | } | ||
2185 | |||
2186 | static int | 2179 | static int |
2187 | qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, | 2180 | qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, |
2188 | unsigned long data) | 2181 | unsigned long data) |
@@ -2205,6 +2198,7 @@ qeth_ulp_setup(struct qeth_card *card) | |||
2205 | int rc; | 2198 | int rc; |
2206 | __u16 temp; | 2199 | __u16 temp; |
2207 | struct qeth_cmd_buffer *iob; | 2200 | struct qeth_cmd_buffer *iob; |
2201 | struct ccw_dev_id dev_id; | ||
2208 | 2202 | ||
2209 | QETH_DBF_TEXT(setup,2,"ulpsetup"); | 2203 | QETH_DBF_TEXT(setup,2,"ulpsetup"); |
2210 | 2204 | ||
@@ -2218,8 +2212,8 @@ qeth_ulp_setup(struct qeth_card *card) | |||
2218 | memcpy(QETH_ULP_SETUP_FILTER_TOKEN(iob->data), | 2212 | memcpy(QETH_ULP_SETUP_FILTER_TOKEN(iob->data), |
2219 | &card->token.ulp_filter_r, QETH_MPC_TOKEN_LENGTH); | 2213 | &card->token.ulp_filter_r, QETH_MPC_TOKEN_LENGTH); |
2220 | 2214 | ||
2221 | temp = __raw_devno_from_bus_id(CARD_DDEV_ID(card)); | 2215 | ccw_device_get_id(CARD_DDEV(card), &dev_id); |
2222 | memcpy(QETH_ULP_SETUP_CUA(iob->data), &temp, 2); | 2216 | memcpy(QETH_ULP_SETUP_CUA(iob->data), &dev_id.devno, 2); |
2223 | temp = (card->info.cula << 8) + card->info.unit_addr2; | 2217 | temp = (card->info.cula << 8) + card->info.unit_addr2; |
2224 | memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2); | 2218 | memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2); |
2225 | rc = qeth_send_control_data(card, ULP_SETUP_SIZE, iob, | 2219 | rc = qeth_send_control_data(card, ULP_SETUP_SIZE, iob, |
@@ -5850,9 +5844,9 @@ qeth_add_vlan_mc6(struct qeth_card *card) | |||
5850 | in_dev = in6_dev_get(netdev); | 5844 | in_dev = in6_dev_get(netdev); |
5851 | if (!in_dev) | 5845 | if (!in_dev) |
5852 | continue; | 5846 | continue; |
5853 | read_lock(&in_dev->lock); | 5847 | read_lock_bh(&in_dev->lock); |
5854 | qeth_add_mc6(card,in_dev); | 5848 | qeth_add_mc6(card,in_dev); |
5855 | read_unlock(&in_dev->lock); | 5849 | read_unlock_bh(&in_dev->lock); |
5856 | in6_dev_put(in_dev); | 5850 | in6_dev_put(in_dev); |
5857 | } | 5851 | } |
5858 | #endif /* CONFIG_QETH_VLAN */ | 5852 | #endif /* CONFIG_QETH_VLAN */ |
@@ -5869,10 +5863,10 @@ qeth_add_multicast_ipv6(struct qeth_card *card) | |||
5869 | in6_dev = in6_dev_get(card->dev); | 5863 | in6_dev = in6_dev_get(card->dev); |
5870 | if (in6_dev == NULL) | 5864 | if (in6_dev == NULL) |
5871 | return; | 5865 | return; |
5872 | read_lock(&in6_dev->lock); | 5866 | read_lock_bh(&in6_dev->lock); |
5873 | qeth_add_mc6(card, in6_dev); | 5867 | qeth_add_mc6(card, in6_dev); |
5874 | qeth_add_vlan_mc6(card); | 5868 | qeth_add_vlan_mc6(card); |
5875 | read_unlock(&in6_dev->lock); | 5869 | read_unlock_bh(&in6_dev->lock); |
5876 | in6_dev_put(in6_dev); | 5870 | in6_dev_put(in6_dev); |
5877 | } | 5871 | } |
5878 | #endif /* CONFIG_QETH_IPV6 */ | 5872 | #endif /* CONFIG_QETH_IPV6 */ |
@@ -7476,11 +7470,11 @@ qeth_softsetup_card(struct qeth_card *card) | |||
7476 | QETH_DBF_TEXT_(setup, 2, "1err%d", rc); | 7470 | QETH_DBF_TEXT_(setup, 2, "1err%d", rc); |
7477 | if (rc == 0xe080){ | 7471 | if (rc == 0xe080){ |
7478 | PRINT_WARN("LAN on card %s if offline! " | 7472 | PRINT_WARN("LAN on card %s if offline! " |
7479 | "Continuing softsetup.\n", | 7473 | "Waiting for STARTLAN from card.\n", |
7480 | CARD_BUS_ID(card)); | 7474 | CARD_BUS_ID(card)); |
7481 | card->lan_online = 0; | 7475 | card->lan_online = 0; |
7482 | } else | 7476 | } |
7483 | return rc; | 7477 | return rc; |
7484 | } else | 7478 | } else |
7485 | card->lan_online = 1; | 7479 | card->lan_online = 1; |
7486 | if (card->info.type==QETH_CARD_TYPE_OSN) | 7480 | if (card->info.type==QETH_CARD_TYPE_OSN) |
@@ -7797,15 +7791,17 @@ qeth_print_status_message(struct qeth_card *card) | |||
7797 | } | 7791 | } |
7798 | /* fallthrough */ | 7792 | /* fallthrough */ |
7799 | case QETH_CARD_TYPE_IQD: | 7793 | case QETH_CARD_TYPE_IQD: |
7800 | card->info.mcl_level[0] = (char) _ebcasc[(__u8) | 7794 | if (card->info.guestlan) { |
7801 | card->info.mcl_level[0]]; | 7795 | card->info.mcl_level[0] = (char) _ebcasc[(__u8) |
7802 | card->info.mcl_level[1] = (char) _ebcasc[(__u8) | 7796 | card->info.mcl_level[0]]; |
7803 | card->info.mcl_level[1]]; | 7797 | card->info.mcl_level[1] = (char) _ebcasc[(__u8) |
7804 | card->info.mcl_level[2] = (char) _ebcasc[(__u8) | 7798 | card->info.mcl_level[1]]; |
7805 | card->info.mcl_level[2]]; | 7799 | card->info.mcl_level[2] = (char) _ebcasc[(__u8) |
7806 | card->info.mcl_level[3] = (char) _ebcasc[(__u8) | 7800 | card->info.mcl_level[2]]; |
7807 | card->info.mcl_level[3]]; | 7801 | card->info.mcl_level[3] = (char) _ebcasc[(__u8) |
7808 | card->info.mcl_level[QETH_MCL_LENGTH] = 0; | 7802 | card->info.mcl_level[3]]; |
7803 | card->info.mcl_level[QETH_MCL_LENGTH] = 0; | ||
7804 | } | ||
7809 | break; | 7805 | break; |
7810 | default: | 7806 | default: |
7811 | memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1); | 7807 | memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1); |
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index 65ffc21afc37..bb0287ad1aac 100644 --- a/drivers/s390/net/qeth_sys.c +++ b/drivers/s390/net/qeth_sys.c | |||
@@ -991,7 +991,7 @@ static struct attribute_group qeth_osn_device_attr_group = { | |||
991 | 991 | ||
992 | #define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \ | 992 | #define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \ |
993 | struct device_attribute dev_attr_##_id = { \ | 993 | struct device_attribute dev_attr_##_id = { \ |
994 | .attr = {.name=__stringify(_name), .mode=_mode, .owner=THIS_MODULE },\ | 994 | .attr = {.name=__stringify(_name), .mode=_mode, },\ |
995 | .show = _show, \ | 995 | .show = _show, \ |
996 | .store = _store, \ | 996 | .store = _store, \ |
997 | }; | 997 | }; |