diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 18 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 13 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_async.c | 51 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 30 | ||||
-rw-r--r-- | drivers/s390/char/tape_block.c | 3 | ||||
-rw-r--r-- | drivers/s390/cio/blacklist.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/chp.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/device.h | 1 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 35 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 13 | ||||
-rw-r--r-- | drivers/s390/net/smsgiucv.c | 7 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 44 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 40 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_cfdc.c | 17 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 22 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 3 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 11 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 35 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 1 |
21 files changed, 225 insertions, 149 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index dad0449475b6..aaccc8ecfa8f 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2508,8 +2508,6 @@ int dasd_generic_restore_device(struct ccw_device *cdev) | |||
2508 | device->stopped &= ~DASD_UNRESUMED_PM; | 2508 | device->stopped &= ~DASD_UNRESUMED_PM; |
2509 | 2509 | ||
2510 | dasd_schedule_device_bh(device); | 2510 | dasd_schedule_device_bh(device); |
2511 | if (device->block) | ||
2512 | dasd_schedule_block_bh(device->block); | ||
2513 | 2511 | ||
2514 | if (device->discipline->restore) | 2512 | if (device->discipline->restore) |
2515 | rc = device->discipline->restore(device); | 2513 | rc = device->discipline->restore(device); |
@@ -2520,6 +2518,9 @@ int dasd_generic_restore_device(struct ccw_device *cdev) | |||
2520 | */ | 2518 | */ |
2521 | device->stopped |= DASD_UNRESUMED_PM; | 2519 | device->stopped |= DASD_UNRESUMED_PM; |
2522 | 2520 | ||
2521 | if (device->block) | ||
2522 | dasd_schedule_block_bh(device->block); | ||
2523 | |||
2523 | dasd_put_device(device); | 2524 | dasd_put_device(device); |
2524 | return 0; | 2525 | return 0; |
2525 | } | 2526 | } |
@@ -2532,6 +2533,7 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, | |||
2532 | { | 2533 | { |
2533 | struct dasd_ccw_req *cqr; | 2534 | struct dasd_ccw_req *cqr; |
2534 | struct ccw1 *ccw; | 2535 | struct ccw1 *ccw; |
2536 | unsigned long *idaw; | ||
2535 | 2537 | ||
2536 | cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device); | 2538 | cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device); |
2537 | 2539 | ||
@@ -2545,9 +2547,17 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, | |||
2545 | 2547 | ||
2546 | ccw = cqr->cpaddr; | 2548 | ccw = cqr->cpaddr; |
2547 | ccw->cmd_code = CCW_CMD_RDC; | 2549 | ccw->cmd_code = CCW_CMD_RDC; |
2548 | ccw->cda = (__u32)(addr_t)rdc_buffer; | 2550 | if (idal_is_needed(rdc_buffer, rdc_buffer_size)) { |
2549 | ccw->count = rdc_buffer_size; | 2551 | idaw = (unsigned long *) (cqr->data); |
2552 | ccw->cda = (__u32)(addr_t) idaw; | ||
2553 | ccw->flags = CCW_FLAG_IDA; | ||
2554 | idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size); | ||
2555 | } else { | ||
2556 | ccw->cda = (__u32)(addr_t) rdc_buffer; | ||
2557 | ccw->flags = 0; | ||
2558 | } | ||
2550 | 2559 | ||
2560 | ccw->count = rdc_buffer_size; | ||
2551 | cqr->startdev = device; | 2561 | cqr->startdev = device; |
2552 | cqr->memdev = device; | 2562 | cqr->memdev = device; |
2553 | cqr->expires = 10*HZ; | 2563 | cqr->expires = 10*HZ; |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index ab3521755588..417b97cd3f94 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -2338,6 +2338,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | |||
2338 | /* Calculate number of blocks/records per track. */ | 2338 | /* Calculate number of blocks/records per track. */ |
2339 | blksize = block->bp_block; | 2339 | blksize = block->bp_block; |
2340 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | 2340 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
2341 | if (blk_per_trk == 0) | ||
2342 | return ERR_PTR(-EINVAL); | ||
2341 | /* Calculate record id of first and last block. */ | 2343 | /* Calculate record id of first and last block. */ |
2342 | first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift; | 2344 | first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift; |
2343 | first_offs = sector_div(first_trk, blk_per_trk); | 2345 | first_offs = sector_div(first_trk, blk_per_trk); |
@@ -3211,8 +3213,10 @@ int dasd_eckd_pm_freeze(struct dasd_device *device) | |||
3211 | int dasd_eckd_restore_device(struct dasd_device *device) | 3213 | int dasd_eckd_restore_device(struct dasd_device *device) |
3212 | { | 3214 | { |
3213 | struct dasd_eckd_private *private; | 3215 | struct dasd_eckd_private *private; |
3216 | struct dasd_eckd_characteristics temp_rdc_data; | ||
3214 | int is_known, rc; | 3217 | int is_known, rc; |
3215 | struct dasd_uid temp_uid; | 3218 | struct dasd_uid temp_uid; |
3219 | unsigned long flags; | ||
3216 | 3220 | ||
3217 | private = (struct dasd_eckd_private *) device->private; | 3221 | private = (struct dasd_eckd_private *) device->private; |
3218 | 3222 | ||
@@ -3225,7 +3229,8 @@ int dasd_eckd_restore_device(struct dasd_device *device) | |||
3225 | rc = dasd_eckd_generate_uid(device, &private->uid); | 3229 | rc = dasd_eckd_generate_uid(device, &private->uid); |
3226 | dasd_get_uid(device->cdev, &temp_uid); | 3230 | dasd_get_uid(device->cdev, &temp_uid); |
3227 | if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) | 3231 | if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) |
3228 | dev_err(&device->cdev->dev, "The UID of the DASD has changed\n"); | 3232 | dev_err(&device->cdev->dev, "The UID of the DASD has " |
3233 | "changed\n"); | ||
3229 | if (rc) | 3234 | if (rc) |
3230 | goto out_err; | 3235 | goto out_err; |
3231 | dasd_set_uid(device->cdev, &private->uid); | 3236 | dasd_set_uid(device->cdev, &private->uid); |
@@ -3245,15 +3250,17 @@ int dasd_eckd_restore_device(struct dasd_device *device) | |||
3245 | dasd_eckd_read_features(device); | 3250 | dasd_eckd_read_features(device); |
3246 | 3251 | ||
3247 | /* Read Device Characteristics */ | 3252 | /* Read Device Characteristics */ |
3248 | memset(&private->rdc_data, 0, sizeof(private->rdc_data)); | ||
3249 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, | 3253 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, |
3250 | &private->rdc_data, 64); | 3254 | &temp_rdc_data, 64); |
3251 | if (rc) { | 3255 | if (rc) { |
3252 | DBF_EVENT(DBF_WARNING, | 3256 | DBF_EVENT(DBF_WARNING, |
3253 | "Read device characteristics failed, rc=%d for " | 3257 | "Read device characteristics failed, rc=%d for " |
3254 | "device: %s", rc, dev_name(&device->cdev->dev)); | 3258 | "device: %s", rc, dev_name(&device->cdev->dev)); |
3255 | goto out_err; | 3259 | goto out_err; |
3256 | } | 3260 | } |
3261 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
3262 | memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data)); | ||
3263 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
3257 | 3264 | ||
3258 | /* add device to alias management */ | 3265 | /* add device to alias management */ |
3259 | dasd_alias_add_device(device); | 3266 | dasd_alias_add_device(device); |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index d6a022f55e92..62ddf5202b79 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -1361,11 +1361,13 @@ static int raw3270_pm_start(struct ccw_device *cdev) | |||
1361 | 1361 | ||
1362 | void raw3270_pm_unfreeze(struct raw3270_view *view) | 1362 | void raw3270_pm_unfreeze(struct raw3270_view *view) |
1363 | { | 1363 | { |
1364 | #ifdef CONFIG_TN3270_CONSOLE | ||
1364 | struct raw3270 *rp; | 1365 | struct raw3270 *rp; |
1365 | 1366 | ||
1366 | rp = view->dev; | 1367 | rp = view->dev; |
1367 | if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) | 1368 | if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) |
1368 | ccw_device_force_console(); | 1369 | ccw_device_force_console(); |
1370 | #endif | ||
1369 | } | 1371 | } |
1370 | 1372 | ||
1371 | static struct ccw_device_id raw3270_id[] = { | 1373 | static struct ccw_device_id raw3270_id[] = { |
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index daaec185ed36..b44462a6c6d3 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c | |||
@@ -26,7 +26,6 @@ static struct sclp_async_sccb *sccb; | |||
26 | static int sclp_async_send_wait(char *message); | 26 | static int sclp_async_send_wait(char *message); |
27 | static struct ctl_table_header *callhome_sysctl_header; | 27 | static struct ctl_table_header *callhome_sysctl_header; |
28 | static DEFINE_SPINLOCK(sclp_async_lock); | 28 | static DEFINE_SPINLOCK(sclp_async_lock); |
29 | static char nodename[64]; | ||
30 | #define SCLP_NORMAL_WRITE 0x00 | 29 | #define SCLP_NORMAL_WRITE 0x00 |
31 | 30 | ||
32 | struct async_evbuf { | 31 | struct async_evbuf { |
@@ -52,9 +51,10 @@ static struct sclp_register sclp_async_register = { | |||
52 | static int call_home_on_panic(struct notifier_block *self, | 51 | static int call_home_on_panic(struct notifier_block *self, |
53 | unsigned long event, void *data) | 52 | unsigned long event, void *data) |
54 | { | 53 | { |
55 | strncat(data, nodename, strlen(nodename)); | 54 | strncat(data, init_utsname()->nodename, |
56 | sclp_async_send_wait(data); | 55 | sizeof(init_utsname()->nodename)); |
57 | return NOTIFY_DONE; | 56 | sclp_async_send_wait(data); |
57 | return NOTIFY_DONE; | ||
58 | } | 58 | } |
59 | 59 | ||
60 | static struct notifier_block call_home_panic_nb = { | 60 | static struct notifier_block call_home_panic_nb = { |
@@ -62,21 +62,20 @@ static struct notifier_block call_home_panic_nb = { | |||
62 | .priority = INT_MAX, | 62 | .priority = INT_MAX, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static int proc_handler_callhome(ctl_table *ctl, int write, struct file *filp, | 65 | static int proc_handler_callhome(struct ctl_table *ctl, int write, |
66 | void __user *buffer, size_t *count, | 66 | void __user *buffer, size_t *count, |
67 | loff_t *ppos) | 67 | loff_t *ppos) |
68 | { | 68 | { |
69 | unsigned long val; | 69 | unsigned long val; |
70 | int len, rc; | 70 | int len, rc; |
71 | char buf[2]; | 71 | char buf[3]; |
72 | 72 | ||
73 | if (!*count | (*ppos && !write)) { | 73 | if (!*count || (*ppos && !write)) { |
74 | *count = 0; | 74 | *count = 0; |
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | if (!write) { | 77 | if (!write) { |
78 | len = sprintf(buf, "%d\n", callhome_enabled); | 78 | len = snprintf(buf, sizeof(buf), "%d\n", callhome_enabled); |
79 | buf[len] = '\0'; | ||
80 | rc = copy_to_user(buffer, buf, sizeof(buf)); | 79 | rc = copy_to_user(buffer, buf, sizeof(buf)); |
81 | if (rc != 0) | 80 | if (rc != 0) |
82 | return -EFAULT; | 81 | return -EFAULT; |
@@ -100,7 +99,7 @@ static struct ctl_table callhome_table[] = { | |||
100 | { | 99 | { |
101 | .procname = "callhome", | 100 | .procname = "callhome", |
102 | .mode = 0644, | 101 | .mode = 0644, |
103 | .proc_handler = &proc_handler_callhome, | 102 | .proc_handler = proc_handler_callhome, |
104 | }, | 103 | }, |
105 | { .ctl_name = 0 } | 104 | { .ctl_name = 0 } |
106 | }; | 105 | }; |
@@ -171,39 +170,29 @@ static int __init sclp_async_init(void) | |||
171 | rc = sclp_register(&sclp_async_register); | 170 | rc = sclp_register(&sclp_async_register); |
172 | if (rc) | 171 | if (rc) |
173 | return rc; | 172 | return rc; |
174 | callhome_sysctl_header = register_sysctl_table(kern_dir_table); | 173 | rc = -EOPNOTSUPP; |
175 | if (!callhome_sysctl_header) { | 174 | if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) |
176 | rc = -ENOMEM; | ||
177 | goto out_sclp; | ||
178 | } | ||
179 | if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) { | ||
180 | rc = -EOPNOTSUPP; | ||
181 | goto out_sclp; | 175 | goto out_sclp; |
182 | } | ||
183 | rc = -ENOMEM; | 176 | rc = -ENOMEM; |
177 | callhome_sysctl_header = register_sysctl_table(kern_dir_table); | ||
178 | if (!callhome_sysctl_header) | ||
179 | goto out_sclp; | ||
184 | request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL); | 180 | request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL); |
185 | if (!request) | ||
186 | goto out_sys; | ||
187 | sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 181 | sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
188 | if (!sccb) | 182 | if (!request || !sccb) |
189 | goto out_mem; | 183 | goto out_mem; |
190 | rc = atomic_notifier_chain_register(&panic_notifier_list, | 184 | rc = atomic_notifier_chain_register(&panic_notifier_list, |
191 | &call_home_panic_nb); | 185 | &call_home_panic_nb); |
192 | if (rc) | 186 | if (!rc) |
193 | goto out_mem; | 187 | goto out; |
194 | |||
195 | strncpy(nodename, init_utsname()->nodename, 64); | ||
196 | return 0; | ||
197 | |||
198 | out_mem: | 188 | out_mem: |
199 | kfree(request); | 189 | kfree(request); |
200 | free_page((unsigned long) sccb); | 190 | free_page((unsigned long) sccb); |
201 | out_sys: | ||
202 | unregister_sysctl_table(callhome_sysctl_header); | 191 | unregister_sysctl_table(callhome_sysctl_header); |
203 | out_sclp: | 192 | out_sclp: |
204 | sclp_unregister(&sclp_async_register); | 193 | sclp_unregister(&sclp_async_register); |
194 | out: | ||
205 | return rc; | 195 | return rc; |
206 | |||
207 | } | 196 | } |
208 | module_init(sclp_async_init); | 197 | module_init(sclp_async_init); |
209 | 198 | ||
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 178724f2a4c3..b9d2a007e93b 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -705,21 +705,6 @@ out_driver: | |||
705 | } | 705 | } |
706 | __initcall(sclp_vt220_tty_init); | 706 | __initcall(sclp_vt220_tty_init); |
707 | 707 | ||
708 | #ifdef CONFIG_SCLP_VT220_CONSOLE | ||
709 | |||
710 | static void | ||
711 | sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count) | ||
712 | { | ||
713 | __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0); | ||
714 | } | ||
715 | |||
716 | static struct tty_driver * | ||
717 | sclp_vt220_con_device(struct console *c, int *index) | ||
718 | { | ||
719 | *index = 0; | ||
720 | return sclp_vt220_driver; | ||
721 | } | ||
722 | |||
723 | static void __sclp_vt220_flush_buffer(void) | 708 | static void __sclp_vt220_flush_buffer(void) |
724 | { | 709 | { |
725 | unsigned long flags; | 710 | unsigned long flags; |
@@ -776,6 +761,21 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg, | |||
776 | } | 761 | } |
777 | } | 762 | } |
778 | 763 | ||
764 | #ifdef CONFIG_SCLP_VT220_CONSOLE | ||
765 | |||
766 | static void | ||
767 | sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count) | ||
768 | { | ||
769 | __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0); | ||
770 | } | ||
771 | |||
772 | static struct tty_driver * | ||
773 | sclp_vt220_con_device(struct console *c, int *index) | ||
774 | { | ||
775 | *index = 0; | ||
776 | return sclp_vt220_driver; | ||
777 | } | ||
778 | |||
779 | static int | 779 | static int |
780 | sclp_vt220_notify(struct notifier_block *self, | 780 | sclp_vt220_notify(struct notifier_block *self, |
781 | unsigned long event, void *data) | 781 | unsigned long event, void *data) |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 64f57ef2763c..0c0705b91c28 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -162,9 +162,10 @@ tapeblock_requeue(struct work_struct *work) { | |||
162 | spin_lock_irq(&device->blk_data.request_queue_lock); | 162 | spin_lock_irq(&device->blk_data.request_queue_lock); |
163 | while ( | 163 | while ( |
164 | !blk_queue_plugged(queue) && | 164 | !blk_queue_plugged(queue) && |
165 | (req = blk_fetch_request(queue)) && | 165 | blk_peek_request(queue) && |
166 | nr_queued < TAPEBLOCK_MIN_REQUEUE | 166 | nr_queued < TAPEBLOCK_MIN_REQUEUE |
167 | ) { | 167 | ) { |
168 | req = blk_fetch_request(queue); | ||
168 | if (rq_data_dir(req) == WRITE) { | 169 | if (rq_data_dir(req) == WRITE) { |
169 | DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); | 170 | DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); |
170 | spin_unlock_irq(&device->blk_data.request_queue_lock); | 171 | spin_unlock_irq(&device->blk_data.request_queue_lock); |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 6565f027791e..7eab9ab9f406 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -265,13 +265,11 @@ struct ccwdev_iter { | |||
265 | static void * | 265 | static void * |
266 | cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) | 266 | cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) |
267 | { | 267 | { |
268 | struct ccwdev_iter *iter; | 268 | struct ccwdev_iter *iter = s->private; |
269 | 269 | ||
270 | if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) | 270 | if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) |
271 | return NULL; | 271 | return NULL; |
272 | iter = kzalloc(sizeof(struct ccwdev_iter), GFP_KERNEL); | 272 | memset(iter, 0, sizeof(*iter)); |
273 | if (!iter) | ||
274 | return ERR_PTR(-ENOMEM); | ||
275 | iter->ssid = *offset / (__MAX_SUBCHANNEL + 1); | 273 | iter->ssid = *offset / (__MAX_SUBCHANNEL + 1); |
276 | iter->devno = *offset % (__MAX_SUBCHANNEL + 1); | 274 | iter->devno = *offset % (__MAX_SUBCHANNEL + 1); |
277 | return iter; | 275 | return iter; |
@@ -280,8 +278,6 @@ cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) | |||
280 | static void | 278 | static void |
281 | cio_ignore_proc_seq_stop(struct seq_file *s, void *it) | 279 | cio_ignore_proc_seq_stop(struct seq_file *s, void *it) |
282 | { | 280 | { |
283 | if (!IS_ERR(it)) | ||
284 | kfree(it); | ||
285 | } | 281 | } |
286 | 282 | ||
287 | static void * | 283 | static void * |
@@ -378,14 +374,15 @@ static const struct seq_operations cio_ignore_proc_seq_ops = { | |||
378 | static int | 374 | static int |
379 | cio_ignore_proc_open(struct inode *inode, struct file *file) | 375 | cio_ignore_proc_open(struct inode *inode, struct file *file) |
380 | { | 376 | { |
381 | return seq_open(file, &cio_ignore_proc_seq_ops); | 377 | return seq_open_private(file, &cio_ignore_proc_seq_ops, |
378 | sizeof(struct ccwdev_iter)); | ||
382 | } | 379 | } |
383 | 380 | ||
384 | static const struct file_operations cio_ignore_proc_fops = { | 381 | static const struct file_operations cio_ignore_proc_fops = { |
385 | .open = cio_ignore_proc_open, | 382 | .open = cio_ignore_proc_open, |
386 | .read = seq_read, | 383 | .read = seq_read, |
387 | .llseek = seq_lseek, | 384 | .llseek = seq_lseek, |
388 | .release = seq_release, | 385 | .release = seq_release_private, |
389 | .write = cio_ignore_write, | 386 | .write = cio_ignore_write, |
390 | }; | 387 | }; |
391 | 388 | ||
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 40002830d48a..8ab51608da55 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -393,7 +393,6 @@ int chp_new(struct chp_id chpid) | |||
393 | chp->state = 1; | 393 | chp->state = 1; |
394 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; | 394 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; |
395 | chp->dev.release = chp_release; | 395 | chp->dev.release = chp_release; |
396 | dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); | ||
397 | 396 | ||
398 | /* Obtain channel path description and fill it in. */ | 397 | /* Obtain channel path description and fill it in. */ |
399 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); | 398 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); |
@@ -411,6 +410,7 @@ int chp_new(struct chp_id chpid) | |||
411 | } else { | 410 | } else { |
412 | chp->cmg = -1; | 411 | chp->cmg = -1; |
413 | } | 412 | } |
413 | dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); | ||
414 | 414 | ||
415 | /* make it known to the system */ | 415 | /* make it known to the system */ |
416 | ret = device_register(&chp->dev); | 416 | ret = device_register(&chp->dev); |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index f780bdd3a04e..2490b741e16a 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1250,8 +1250,7 @@ static int io_subchannel_probe(struct subchannel *sch) | |||
1250 | unsigned long flags; | 1250 | unsigned long flags; |
1251 | struct ccw_dev_id dev_id; | 1251 | struct ccw_dev_id dev_id; |
1252 | 1252 | ||
1253 | cdev = sch_get_cdev(sch); | 1253 | if (cio_is_console(sch->schid)) { |
1254 | if (cdev) { | ||
1255 | rc = sysfs_create_group(&sch->dev.kobj, | 1254 | rc = sysfs_create_group(&sch->dev.kobj, |
1256 | &io_subchannel_attr_group); | 1255 | &io_subchannel_attr_group); |
1257 | if (rc) | 1256 | if (rc) |
@@ -1260,13 +1259,13 @@ static int io_subchannel_probe(struct subchannel *sch) | |||
1260 | "0.%x.%04x (rc=%d)\n", | 1259 | "0.%x.%04x (rc=%d)\n", |
1261 | sch->schid.ssid, sch->schid.sch_no, rc); | 1260 | sch->schid.ssid, sch->schid.sch_no, rc); |
1262 | /* | 1261 | /* |
1263 | * This subchannel already has an associated ccw_device. | 1262 | * The console subchannel already has an associated ccw_device. |
1264 | * Throw the delayed uevent for the subchannel, register | 1263 | * Throw the delayed uevent for the subchannel, register |
1265 | * the ccw_device and exit. This happens for all early | 1264 | * the ccw_device and exit. |
1266 | * devices, e.g. the console. | ||
1267 | */ | 1265 | */ |
1268 | dev_set_uevent_suppress(&sch->dev, 0); | 1266 | dev_set_uevent_suppress(&sch->dev, 0); |
1269 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 1267 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
1268 | cdev = sch_get_cdev(sch); | ||
1270 | cdev->dev.groups = ccwdev_attr_groups; | 1269 | cdev->dev.groups = ccwdev_attr_groups; |
1271 | device_initialize(&cdev->dev); | 1270 | device_initialize(&cdev->dev); |
1272 | ccw_device_register(cdev); | 1271 | ccw_device_register(cdev); |
@@ -1609,7 +1608,7 @@ int ccw_purge_blacklisted(void) | |||
1609 | return 0; | 1608 | return 0; |
1610 | } | 1609 | } |
1611 | 1610 | ||
1612 | static void device_set_disconnected(struct ccw_device *cdev) | 1611 | void ccw_device_set_disconnected(struct ccw_device *cdev) |
1613 | { | 1612 | { |
1614 | if (!cdev) | 1613 | if (!cdev) |
1615 | return; | 1614 | return; |
@@ -1705,7 +1704,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow) | |||
1705 | ccw_device_trigger_reprobe(cdev); | 1704 | ccw_device_trigger_reprobe(cdev); |
1706 | break; | 1705 | break; |
1707 | case DISC: | 1706 | case DISC: |
1708 | device_set_disconnected(cdev); | 1707 | ccw_device_set_disconnected(cdev); |
1709 | break; | 1708 | break; |
1710 | default: | 1709 | default: |
1711 | break; | 1710 | break; |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index ed39a2caaf47..246c6482842c 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -125,6 +125,7 @@ int ccw_device_stlck(struct ccw_device *); | |||
125 | void ccw_device_trigger_reprobe(struct ccw_device *); | 125 | void ccw_device_trigger_reprobe(struct ccw_device *); |
126 | void ccw_device_kill_io(struct ccw_device *); | 126 | void ccw_device_kill_io(struct ccw_device *); |
127 | int ccw_device_notify(struct ccw_device *, int); | 127 | int ccw_device_notify(struct ccw_device *, int); |
128 | void ccw_device_set_disconnected(struct ccw_device *cdev); | ||
128 | void ccw_device_set_notoper(struct ccw_device *cdev); | 129 | void ccw_device_set_notoper(struct ccw_device *cdev); |
129 | 130 | ||
130 | /* qdio needs this. */ | 131 | /* qdio needs this. */ |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index e728ce447f6e..b9613d7df9ef 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -387,19 +387,35 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
387 | 387 | ||
388 | cdev->private->state = state; | 388 | cdev->private->state = state; |
389 | 389 | ||
390 | if (state == DEV_STATE_BOXED) { | 390 | switch (state) { |
391 | case DEV_STATE_BOXED: | ||
391 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", | 392 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", |
392 | cdev->private->dev_id.devno, sch->schid.sch_no); | 393 | cdev->private->dev_id.devno, sch->schid.sch_no); |
393 | if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) | 394 | if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) |
394 | ccw_device_schedule_sch_unregister(cdev); | 395 | ccw_device_schedule_sch_unregister(cdev); |
395 | cdev->private->flags.donotify = 0; | 396 | cdev->private->flags.donotify = 0; |
396 | } | 397 | break; |
397 | if (state == DEV_STATE_NOT_OPER) { | 398 | case DEV_STATE_NOT_OPER: |
398 | CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", | 399 | CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", |
399 | cdev->private->dev_id.devno, sch->schid.sch_no); | 400 | cdev->private->dev_id.devno, sch->schid.sch_no); |
400 | if (!ccw_device_notify(cdev, CIO_GONE)) | 401 | if (!ccw_device_notify(cdev, CIO_GONE)) |
401 | ccw_device_schedule_sch_unregister(cdev); | 402 | ccw_device_schedule_sch_unregister(cdev); |
403 | else | ||
404 | ccw_device_set_disconnected(cdev); | ||
402 | cdev->private->flags.donotify = 0; | 405 | cdev->private->flags.donotify = 0; |
406 | break; | ||
407 | case DEV_STATE_DISCONNECTED: | ||
408 | CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel " | ||
409 | "%04x\n", cdev->private->dev_id.devno, | ||
410 | sch->schid.sch_no); | ||
411 | if (!ccw_device_notify(cdev, CIO_NO_PATH)) | ||
412 | ccw_device_schedule_sch_unregister(cdev); | ||
413 | else | ||
414 | ccw_device_set_disconnected(cdev); | ||
415 | cdev->private->flags.donotify = 0; | ||
416 | break; | ||
417 | default: | ||
418 | break; | ||
403 | } | 419 | } |
404 | 420 | ||
405 | if (cdev->private->flags.donotify) { | 421 | if (cdev->private->flags.donotify) { |
@@ -671,6 +687,10 @@ ccw_device_offline(struct ccw_device *cdev) | |||
671 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 687 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
672 | return 0; | 688 | return 0; |
673 | } | 689 | } |
690 | if (cdev->private->state == DEV_STATE_BOXED) { | ||
691 | ccw_device_done(cdev, DEV_STATE_BOXED); | ||
692 | return 0; | ||
693 | } | ||
674 | if (ccw_device_is_orphan(cdev)) { | 694 | if (ccw_device_is_orphan(cdev)) { |
675 | ccw_device_done(cdev, DEV_STATE_OFFLINE); | 695 | ccw_device_done(cdev, DEV_STATE_OFFLINE); |
676 | return 0; | 696 | return 0; |
@@ -730,11 +750,10 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event) | |||
730 | static void ccw_device_generic_notoper(struct ccw_device *cdev, | 750 | static void ccw_device_generic_notoper(struct ccw_device *cdev, |
731 | enum dev_event dev_event) | 751 | enum dev_event dev_event) |
732 | { | 752 | { |
733 | struct subchannel *sch; | 753 | if (!ccw_device_notify(cdev, CIO_GONE)) |
734 | 754 | ccw_device_schedule_sch_unregister(cdev); | |
735 | ccw_device_set_notoper(cdev); | 755 | else |
736 | sch = to_subchannel(cdev->dev.parent); | 756 | ccw_device_set_disconnected(cdev); |
737 | css_schedule_eval(sch->schid); | ||
738 | } | 757 | } |
739 | 758 | ||
740 | /* | 759 | /* |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index c20d4790258e..5677b40e4ac0 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -361,7 +361,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev, | |||
361 | .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), | 361 | .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), |
362 | .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), | 362 | .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), |
363 | }; | 363 | }; |
364 | static struct CPRBX static_cprbx = { | 364 | static struct CPRBX local_cprbx = { |
365 | .cprb_len = 0x00dc, | 365 | .cprb_len = 0x00dc, |
366 | .cprb_ver_id = 0x02, | 366 | .cprb_ver_id = 0x02, |
367 | .func_id = {0x54, 0x32}, | 367 | .func_id = {0x54, 0x32}, |
@@ -372,7 +372,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev, | |||
372 | 372 | ||
373 | msg->hdr = static_type6_hdrX; | 373 | msg->hdr = static_type6_hdrX; |
374 | msg->hdr.FromCardLen2 = random_number_length, | 374 | msg->hdr.FromCardLen2 = random_number_length, |
375 | msg->cprbx = static_cprbx; | 375 | msg->cprbx = local_cprbx; |
376 | msg->cprbx.rpl_datal = random_number_length, | 376 | msg->cprbx.rpl_datal = random_number_length, |
377 | msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); | 377 | msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); |
378 | memcpy(msg->function_code, msg->hdr.function_code, 0x02); | 378 | memcpy(msg->function_code, msg->hdr.function_code, 0x02); |
@@ -561,7 +561,8 @@ static int convert_response_ica(struct zcrypt_device *zdev, | |||
561 | if (msg->cprbx.cprb_ver_id == 0x02) | 561 | if (msg->cprbx.cprb_ver_id == 0x02) |
562 | return convert_type86_ica(zdev, reply, | 562 | return convert_type86_ica(zdev, reply, |
563 | outputdata, outputdatalength); | 563 | outputdata, outputdatalength); |
564 | /* no break, incorrect cprb version is an unknown response */ | 564 | /* Fall through, no break, incorrect cprb version is an unknown |
565 | * response */ | ||
565 | default: /* Unknown response type, this should NEVER EVER happen */ | 566 | default: /* Unknown response type, this should NEVER EVER happen */ |
566 | zdev->online = 0; | 567 | zdev->online = 0; |
567 | return -EAGAIN; /* repeat the request on a different device. */ | 568 | return -EAGAIN; /* repeat the request on a different device. */ |
@@ -587,7 +588,8 @@ static int convert_response_xcrb(struct zcrypt_device *zdev, | |||
587 | } | 588 | } |
588 | if (msg->cprbx.cprb_ver_id == 0x02) | 589 | if (msg->cprbx.cprb_ver_id == 0x02) |
589 | return convert_type86_xcrb(zdev, reply, xcRB); | 590 | return convert_type86_xcrb(zdev, reply, xcRB); |
590 | /* no break, incorrect cprb version is an unknown response */ | 591 | /* Fall through, no break, incorrect cprb version is an unknown |
592 | * response */ | ||
591 | default: /* Unknown response type, this should NEVER EVER happen */ | 593 | default: /* Unknown response type, this should NEVER EVER happen */ |
592 | xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ | 594 | xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ |
593 | zdev->online = 0; | 595 | zdev->online = 0; |
@@ -610,7 +612,8 @@ static int convert_response_rng(struct zcrypt_device *zdev, | |||
610 | return -EINVAL; | 612 | return -EINVAL; |
611 | if (msg->cprbx.cprb_ver_id == 0x02) | 613 | if (msg->cprbx.cprb_ver_id == 0x02) |
612 | return convert_type86_rng(zdev, reply, data); | 614 | return convert_type86_rng(zdev, reply, data); |
613 | /* no break, incorrect cprb version is an unknown response */ | 615 | /* Fall through, no break, incorrect cprb version is an unknown |
616 | * response */ | ||
614 | default: /* Unknown response type, this should NEVER EVER happen */ | 617 | default: /* Unknown response type, this should NEVER EVER happen */ |
615 | zdev->online = 0; | 618 | zdev->online = 0; |
616 | return -EAGAIN; /* repeat the request on a different device. */ | 619 | return -EAGAIN; /* repeat the request on a different device. */ |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 102000d1af6f..3012355f8304 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -158,7 +158,12 @@ static int smsg_pm_restore_thaw(struct device *dev) | |||
158 | smsg_path->flags = 0; | 158 | smsg_path->flags = 0; |
159 | rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", | 159 | rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", |
160 | NULL, NULL, NULL); | 160 | NULL, NULL, NULL); |
161 | printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc); | 161 | #ifdef CONFIG_PM_DEBUG |
162 | if (rc) | ||
163 | printk(KERN_ERR | ||
164 | "iucv_path_connect returned with rc %i\n", rc); | ||
165 | #endif | ||
166 | cpcmd("SET SMSG IUCV", NULL, 0, NULL); | ||
162 | } | 167 | } |
163 | return 0; | 168 | return 0; |
164 | } | 169 | } |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 1be6bf7e8ce6..2889e5f2dfd3 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -80,28 +80,35 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) | |||
80 | 80 | ||
81 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) | 81 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) |
82 | { | 82 | { |
83 | struct ccw_device *ccwdev; | ||
83 | struct zfcp_adapter *adapter; | 84 | struct zfcp_adapter *adapter; |
84 | struct zfcp_port *port; | 85 | struct zfcp_port *port; |
85 | struct zfcp_unit *unit; | 86 | struct zfcp_unit *unit; |
86 | 87 | ||
87 | mutex_lock(&zfcp_data.config_mutex); | 88 | ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); |
88 | read_lock_irq(&zfcp_data.config_lock); | 89 | if (!ccwdev) |
89 | adapter = zfcp_get_adapter_by_busid(busid); | 90 | return; |
90 | if (adapter) | 91 | |
91 | zfcp_adapter_get(adapter); | 92 | if (ccw_device_set_online(ccwdev)) |
92 | read_unlock_irq(&zfcp_data.config_lock); | 93 | goto out_ccwdev; |
93 | 94 | ||
95 | mutex_lock(&zfcp_data.config_mutex); | ||
96 | adapter = dev_get_drvdata(&ccwdev->dev); | ||
94 | if (!adapter) | 97 | if (!adapter) |
95 | goto out_adapter; | 98 | goto out_unlock; |
96 | port = zfcp_port_enqueue(adapter, wwpn, 0, 0); | 99 | zfcp_adapter_get(adapter); |
97 | if (IS_ERR(port)) | 100 | |
101 | port = zfcp_get_port_by_wwpn(adapter, wwpn); | ||
102 | if (!port) | ||
98 | goto out_port; | 103 | goto out_port; |
104 | |||
105 | zfcp_port_get(port); | ||
99 | unit = zfcp_unit_enqueue(port, lun); | 106 | unit = zfcp_unit_enqueue(port, lun); |
100 | if (IS_ERR(unit)) | 107 | if (IS_ERR(unit)) |
101 | goto out_unit; | 108 | goto out_unit; |
102 | mutex_unlock(&zfcp_data.config_mutex); | 109 | mutex_unlock(&zfcp_data.config_mutex); |
103 | ccw_device_set_online(adapter->ccw_device); | ||
104 | 110 | ||
111 | zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); | ||
105 | zfcp_erp_wait(adapter); | 112 | zfcp_erp_wait(adapter); |
106 | flush_work(&unit->scsi_work); | 113 | flush_work(&unit->scsi_work); |
107 | 114 | ||
@@ -111,20 +118,23 @@ out_unit: | |||
111 | zfcp_port_put(port); | 118 | zfcp_port_put(port); |
112 | out_port: | 119 | out_port: |
113 | zfcp_adapter_put(adapter); | 120 | zfcp_adapter_put(adapter); |
114 | out_adapter: | 121 | out_unlock: |
115 | mutex_unlock(&zfcp_data.config_mutex); | 122 | mutex_unlock(&zfcp_data.config_mutex); |
123 | out_ccwdev: | ||
124 | put_device(&ccwdev->dev); | ||
116 | return; | 125 | return; |
117 | } | 126 | } |
118 | 127 | ||
119 | static void __init zfcp_init_device_setup(char *devstr) | 128 | static void __init zfcp_init_device_setup(char *devstr) |
120 | { | 129 | { |
121 | char *token; | 130 | char *token; |
122 | char *str; | 131 | char *str, *str_saved; |
123 | char busid[ZFCP_BUS_ID_SIZE]; | 132 | char busid[ZFCP_BUS_ID_SIZE]; |
124 | u64 wwpn, lun; | 133 | u64 wwpn, lun; |
125 | 134 | ||
126 | /* duplicate devstr and keep the original for sysfs presentation*/ | 135 | /* duplicate devstr and keep the original for sysfs presentation*/ |
127 | str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); | 136 | str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL); |
137 | str = str_saved; | ||
128 | if (!str) | 138 | if (!str) |
129 | return; | 139 | return; |
130 | 140 | ||
@@ -143,12 +153,12 @@ static void __init zfcp_init_device_setup(char *devstr) | |||
143 | if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) | 153 | if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) |
144 | goto err_out; | 154 | goto err_out; |
145 | 155 | ||
146 | kfree(str); | 156 | kfree(str_saved); |
147 | zfcp_init_device_configure(busid, wwpn, lun); | 157 | zfcp_init_device_configure(busid, wwpn, lun); |
148 | return; | 158 | return; |
149 | 159 | ||
150 | err_out: | 160 | err_out: |
151 | kfree(str); | 161 | kfree(str_saved); |
152 | pr_err("%s is not a valid SCSI device\n", devstr); | 162 | pr_err("%s is not a valid SCSI device\n", devstr); |
153 | } | 163 | } |
154 | 164 | ||
@@ -593,10 +603,8 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
593 | int retval = 0; | 603 | int retval = 0; |
594 | unsigned long flags; | 604 | unsigned long flags; |
595 | 605 | ||
596 | cancel_work_sync(&adapter->scan_work); | ||
597 | cancel_work_sync(&adapter->stat_work); | 606 | cancel_work_sync(&adapter->stat_work); |
598 | zfcp_fc_wka_ports_force_offline(adapter->gs); | 607 | zfcp_fc_wka_ports_force_offline(adapter->gs); |
599 | zfcp_adapter_scsi_unregister(adapter); | ||
600 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, | 608 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, |
601 | &zfcp_sysfs_adapter_attrs); | 609 | &zfcp_sysfs_adapter_attrs); |
602 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); | 610 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); |
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 0c90f8e71605..e08339428ecf 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -102,6 +102,14 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
102 | adapter = dev_get_drvdata(&ccw_device->dev); | 102 | adapter = dev_get_drvdata(&ccw_device->dev); |
103 | if (!adapter) | 103 | if (!adapter) |
104 | goto out; | 104 | goto out; |
105 | mutex_unlock(&zfcp_data.config_mutex); | ||
106 | |||
107 | cancel_work_sync(&adapter->scan_work); | ||
108 | |||
109 | mutex_lock(&zfcp_data.config_mutex); | ||
110 | |||
111 | /* this also removes the scsi devices, so call it first */ | ||
112 | zfcp_adapter_scsi_unregister(adapter); | ||
105 | 113 | ||
106 | write_lock_irq(&zfcp_data.config_lock); | 114 | write_lock_irq(&zfcp_data.config_lock); |
107 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { | 115 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { |
@@ -117,11 +125,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
117 | write_unlock_irq(&zfcp_data.config_lock); | 125 | write_unlock_irq(&zfcp_data.config_lock); |
118 | 126 | ||
119 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { | 127 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { |
120 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) { | 128 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) |
121 | if (unit->device) | ||
122 | scsi_remove_device(unit->device); | ||
123 | zfcp_unit_dequeue(unit); | 129 | zfcp_unit_dequeue(unit); |
124 | } | ||
125 | zfcp_port_dequeue(port); | 130 | zfcp_port_dequeue(port); |
126 | } | 131 | } |
127 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); | 132 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); |
@@ -192,13 +197,9 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) | |||
192 | 197 | ||
193 | mutex_lock(&zfcp_data.config_mutex); | 198 | mutex_lock(&zfcp_data.config_mutex); |
194 | adapter = dev_get_drvdata(&ccw_device->dev); | 199 | adapter = dev_get_drvdata(&ccw_device->dev); |
195 | if (!adapter) | ||
196 | goto out; | ||
197 | |||
198 | zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); | 200 | zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); |
199 | zfcp_erp_wait(adapter); | 201 | zfcp_erp_wait(adapter); |
200 | mutex_unlock(&zfcp_data.config_mutex); | 202 | mutex_unlock(&zfcp_data.config_mutex); |
201 | out: | ||
202 | return 0; | 203 | return 0; |
203 | } | 204 | } |
204 | 205 | ||
@@ -253,13 +254,17 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev) | |||
253 | 254 | ||
254 | mutex_lock(&zfcp_data.config_mutex); | 255 | mutex_lock(&zfcp_data.config_mutex); |
255 | adapter = dev_get_drvdata(&cdev->dev); | 256 | adapter = dev_get_drvdata(&cdev->dev); |
257 | if (!adapter) | ||
258 | goto out; | ||
259 | |||
256 | zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); | 260 | zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); |
257 | zfcp_erp_wait(adapter); | 261 | zfcp_erp_wait(adapter); |
258 | zfcp_erp_thread_kill(adapter); | 262 | zfcp_erp_thread_kill(adapter); |
263 | out: | ||
259 | mutex_unlock(&zfcp_data.config_mutex); | 264 | mutex_unlock(&zfcp_data.config_mutex); |
260 | } | 265 | } |
261 | 266 | ||
262 | static struct ccw_driver zfcp_ccw_driver = { | 267 | struct ccw_driver zfcp_ccw_driver = { |
263 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
264 | .name = "zfcp", | 269 | .name = "zfcp", |
265 | .ids = zfcp_ccw_device_id, | 270 | .ids = zfcp_ccw_device_id, |
@@ -284,20 +289,3 @@ int __init zfcp_ccw_register(void) | |||
284 | { | 289 | { |
285 | return ccw_driver_register(&zfcp_ccw_driver); | 290 | return ccw_driver_register(&zfcp_ccw_driver); |
286 | } | 291 | } |
287 | |||
288 | /** | ||
289 | * zfcp_get_adapter_by_busid - find zfcp_adapter struct | ||
290 | * @busid: bus id string of zfcp adapter to find | ||
291 | */ | ||
292 | struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid) | ||
293 | { | ||
294 | struct ccw_device *ccw_device; | ||
295 | struct zfcp_adapter *adapter = NULL; | ||
296 | |||
297 | ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); | ||
298 | if (ccw_device) { | ||
299 | adapter = dev_get_drvdata(&ccw_device->dev); | ||
300 | put_device(&ccw_device->dev); | ||
301 | } | ||
302 | return adapter; | ||
303 | } | ||
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 8305c874e86f..ef681dfed0cc 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c | |||
@@ -86,8 +86,23 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer, | |||
86 | static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) | 86 | static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) |
87 | { | 87 | { |
88 | char busid[9]; | 88 | char busid[9]; |
89 | struct ccw_device *ccwdev; | ||
90 | struct zfcp_adapter *adapter = NULL; | ||
91 | |||
89 | snprintf(busid, sizeof(busid), "0.0.%04x", devno); | 92 | snprintf(busid, sizeof(busid), "0.0.%04x", devno); |
90 | return zfcp_get_adapter_by_busid(busid); | 93 | ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); |
94 | if (!ccwdev) | ||
95 | goto out; | ||
96 | |||
97 | adapter = dev_get_drvdata(&ccwdev->dev); | ||
98 | if (!adapter) | ||
99 | goto out_put; | ||
100 | |||
101 | zfcp_adapter_get(adapter); | ||
102 | out_put: | ||
103 | put_device(&ccwdev->dev); | ||
104 | out: | ||
105 | return adapter; | ||
91 | } | 106 | } |
92 | 107 | ||
93 | static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) | 108 | static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 73d366ba31e5..f73e2180f333 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -858,10 +858,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
858 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) | 858 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
859 | return zfcp_erp_open_ptp_port(act); | 859 | return zfcp_erp_open_ptp_port(act); |
860 | if (!port->d_id) { | 860 | if (!port->d_id) { |
861 | zfcp_port_get(port); | 861 | zfcp_fc_trigger_did_lookup(port); |
862 | if (!queue_work(adapter->work_queue, | ||
863 | &port->gid_pn_work)) | ||
864 | zfcp_port_put(port); | ||
865 | return ZFCP_ERP_EXIT; | 862 | return ZFCP_ERP_EXIT; |
866 | } | 863 | } |
867 | return zfcp_erp_port_strategy_open_port(act); | 864 | return zfcp_erp_port_strategy_open_port(act); |
@@ -869,12 +866,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
869 | case ZFCP_ERP_STEP_PORT_OPENING: | 866 | case ZFCP_ERP_STEP_PORT_OPENING: |
870 | /* D_ID might have changed during open */ | 867 | /* D_ID might have changed during open */ |
871 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { | 868 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { |
872 | if (port->d_id) | 869 | if (!port->d_id) { |
873 | return ZFCP_ERP_SUCCEEDED; | 870 | zfcp_fc_trigger_did_lookup(port); |
874 | else { | 871 | return ZFCP_ERP_EXIT; |
875 | act->step = ZFCP_ERP_STEP_PORT_CLOSING; | ||
876 | return ZFCP_ERP_CONTINUES; | ||
877 | } | 872 | } |
873 | return ZFCP_ERP_SUCCEEDED; | ||
878 | } | 874 | } |
879 | if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) { | 875 | if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) { |
880 | port->d_id = 0; | 876 | port->d_id = 0; |
@@ -889,19 +885,21 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
889 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | 885 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) |
890 | { | 886 | { |
891 | struct zfcp_port *port = erp_action->port; | 887 | struct zfcp_port *port = erp_action->port; |
888 | int p_status = atomic_read(&port->status); | ||
892 | 889 | ||
893 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC) | 890 | if ((p_status & ZFCP_STATUS_COMMON_NOESC) && |
891 | !(p_status & ZFCP_STATUS_COMMON_OPEN)) | ||
894 | goto close_init_done; | 892 | goto close_init_done; |
895 | 893 | ||
896 | switch (erp_action->step) { | 894 | switch (erp_action->step) { |
897 | case ZFCP_ERP_STEP_UNINITIALIZED: | 895 | case ZFCP_ERP_STEP_UNINITIALIZED: |
898 | zfcp_erp_port_strategy_clearstati(port); | 896 | zfcp_erp_port_strategy_clearstati(port); |
899 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) | 897 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
900 | return zfcp_erp_port_strategy_close(erp_action); | 898 | return zfcp_erp_port_strategy_close(erp_action); |
901 | break; | 899 | break; |
902 | 900 | ||
903 | case ZFCP_ERP_STEP_PORT_CLOSING: | 901 | case ZFCP_ERP_STEP_PORT_CLOSING: |
904 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) | 902 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
905 | return ZFCP_ERP_FAILED; | 903 | return ZFCP_ERP_FAILED; |
906 | break; | 904 | break; |
907 | } | 905 | } |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 36935bc0818f..b3f28deb4505 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -28,7 +28,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int); | |||
28 | /* zfcp_ccw.c */ | 28 | /* zfcp_ccw.c */ |
29 | extern int zfcp_ccw_register(void); | 29 | extern int zfcp_ccw_register(void); |
30 | extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); | 30 | extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); |
31 | extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *); | 31 | extern struct ccw_driver zfcp_ccw_driver; |
32 | 32 | ||
33 | /* zfcp_cfdc.c */ | 33 | /* zfcp_cfdc.c */ |
34 | extern struct miscdevice zfcp_cfdc_misc; | 34 | extern struct miscdevice zfcp_cfdc_misc; |
@@ -96,6 +96,7 @@ extern int zfcp_fc_scan_ports(struct zfcp_adapter *); | |||
96 | extern void _zfcp_fc_scan_ports_later(struct work_struct *); | 96 | extern void _zfcp_fc_scan_ports_later(struct work_struct *); |
97 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); | 97 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); |
98 | extern void zfcp_fc_port_did_lookup(struct work_struct *); | 98 | extern void zfcp_fc_port_did_lookup(struct work_struct *); |
99 | extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *); | ||
99 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); | 100 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); |
100 | extern void zfcp_fc_test_link(struct zfcp_port *); | 101 | extern void zfcp_fc_test_link(struct zfcp_port *); |
101 | extern void zfcp_fc_link_test_work(struct work_struct *); | 102 | extern void zfcp_fc_link_test_work(struct work_struct *); |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 722f22de8753..df23bcead23d 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -361,6 +361,17 @@ out: | |||
361 | } | 361 | } |
362 | 362 | ||
363 | /** | 363 | /** |
364 | * zfcp_fc_trigger_did_lookup - trigger the d_id lookup using a GID_PN request | ||
365 | * @port: The zfcp_port to lookup the d_id for. | ||
366 | */ | ||
367 | void zfcp_fc_trigger_did_lookup(struct zfcp_port *port) | ||
368 | { | ||
369 | zfcp_port_get(port); | ||
370 | if (!queue_work(port->adapter->work_queue, &port->gid_pn_work)) | ||
371 | zfcp_port_put(port); | ||
372 | } | ||
373 | |||
374 | /** | ||
364 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload | 375 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload |
365 | * @port: zfcp_port structure | 376 | * @port: zfcp_port structure |
366 | * @plogi: plogi payload | 377 | * @plogi: plogi payload |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index f09c863dc6bd..4e41baa0c141 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1058,14 +1058,28 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, | |||
1058 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req, | 1058 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req, |
1059 | SBAL_FLAGS0_TYPE_WRITE_READ, | 1059 | SBAL_FLAGS0_TYPE_WRITE_READ, |
1060 | sg_resp, max_sbals); | 1060 | sg_resp, max_sbals); |
1061 | req->qtcb->bottom.support.resp_buf_length = bytes; | ||
1061 | if (bytes <= 0) | 1062 | if (bytes <= 0) |
1062 | return -EIO; | 1063 | return -EIO; |
1063 | 1064 | ||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | ||
1069 | struct scatterlist *sg_req, | ||
1070 | struct scatterlist *sg_resp, | ||
1071 | int max_sbals) | ||
1072 | { | ||
1073 | int ret; | ||
1074 | |||
1075 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); | ||
1076 | if (ret) | ||
1077 | return ret; | ||
1078 | |||
1064 | /* common settings for ct/gs and els requests */ | 1079 | /* common settings for ct/gs and els requests */ |
1065 | req->qtcb->bottom.support.resp_buf_length = bytes; | ||
1066 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1080 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1067 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; | 1081 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; |
1068 | zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10); | 1082 | zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ); |
1069 | 1083 | ||
1070 | return 0; | 1084 | return 0; |
1071 | } | 1085 | } |
@@ -1094,8 +1108,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool) | |||
1094 | } | 1108 | } |
1095 | 1109 | ||
1096 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1110 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1097 | ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp, | 1111 | ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, |
1098 | FSF_MAX_SBALS_PER_REQ); | 1112 | FSF_MAX_SBALS_PER_REQ); |
1099 | if (ret) | 1113 | if (ret) |
1100 | goto failed_send; | 1114 | goto failed_send; |
1101 | 1115 | ||
@@ -1192,7 +1206,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1192 | } | 1206 | } |
1193 | 1207 | ||
1194 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1208 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1195 | ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2); | 1209 | ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2); |
1196 | 1210 | ||
1197 | if (ret) | 1211 | if (ret) |
1198 | goto failed_send; | 1212 | goto failed_send; |
@@ -1461,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1461 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; | 1475 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; |
1462 | if (req->qtcb->bottom.support.els1_length >= | 1476 | if (req->qtcb->bottom.support.els1_length >= |
1463 | FSF_PLOGI_MIN_LEN) { | 1477 | FSF_PLOGI_MIN_LEN) { |
1464 | if (plogi->serv_param.wwpn != port->wwpn) | 1478 | if (plogi->serv_param.wwpn != port->wwpn) { |
1465 | port->d_id = 0; | 1479 | port->d_id = 0; |
1466 | else { | 1480 | dev_warn(&port->adapter->ccw_device->dev, |
1481 | "A port opened with WWPN 0x%016Lx " | ||
1482 | "returned data that identifies it as " | ||
1483 | "WWPN 0x%016Lx\n", | ||
1484 | (unsigned long long) port->wwpn, | ||
1485 | (unsigned long long) | ||
1486 | plogi->serv_param.wwpn); | ||
1487 | } else { | ||
1467 | port->wwnn = plogi->serv_param.wwnn; | 1488 | port->wwnn = plogi->serv_param.wwnn; |
1468 | zfcp_fc_plogi_evaluate(port, plogi); | 1489 | zfcp_fc_plogi_evaluate(port, plogi); |
1469 | } | 1490 | } |
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 079a8cf518a3..d31000886ca8 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c | |||
@@ -224,6 +224,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, | |||
224 | 224 | ||
225 | zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); | 225 | zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); |
226 | zfcp_erp_wait(unit->port->adapter); | 226 | zfcp_erp_wait(unit->port->adapter); |
227 | flush_work(&unit->scsi_work); | ||
227 | zfcp_unit_put(unit); | 228 | zfcp_unit_put(unit); |
228 | out: | 229 | out: |
229 | mutex_unlock(&zfcp_data.config_mutex); | 230 | mutex_unlock(&zfcp_data.config_mutex); |