diff options
author | Stefan Haberland <stefan.haberland@de.ibm.com> | 2012-01-18 12:03:41 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-01-18 12:03:42 -0500 |
commit | f16330316321d1c388d13096f6858f5d2dac29dc (patch) | |
tree | 0dda4b86553b3e5881c8a53391f24210b17a2eb6 /drivers/s390 | |
parent | f9f8d02fae0dc47d8868fd069bb88d12f8d1d71f (diff) |
[S390] dasd: revalidate server for new pathgroup
If a pathgroup is established we get an event and have to revalidate
the server to propagate supported features like PAV and enable them.
Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 6 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 22 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 2 |
3 files changed, 30 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index eef27a197c00..110137e7ec81 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -3261,6 +3261,12 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event) | |||
3261 | device->path_data.tbvpm |= eventlpm; | 3261 | device->path_data.tbvpm |= eventlpm; |
3262 | dasd_schedule_device_bh(device); | 3262 | dasd_schedule_device_bh(device); |
3263 | } | 3263 | } |
3264 | if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) { | ||
3265 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | ||
3266 | "Pathgroup re-established\n"); | ||
3267 | if (device->discipline->kick_validate) | ||
3268 | device->discipline->kick_validate(device); | ||
3269 | } | ||
3264 | } | 3270 | } |
3265 | dasd_put_device(device); | 3271 | dasd_put_device(device); |
3266 | } | 3272 | } |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 1b6e7ea9347f..70880be26015 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1550,6 +1550,24 @@ static void dasd_eckd_validate_server(struct dasd_device *device) | |||
1550 | "returned rc=%d", private->uid.ssid, rc); | 1550 | "returned rc=%d", private->uid.ssid, rc); |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | /* | ||
1554 | * worker to do a validate server in case of a lost pathgroup | ||
1555 | */ | ||
1556 | static void dasd_eckd_do_validate_server(struct work_struct *work) | ||
1557 | { | ||
1558 | struct dasd_device *device = container_of(work, struct dasd_device, | ||
1559 | kick_validate); | ||
1560 | dasd_eckd_validate_server(device); | ||
1561 | dasd_put_device(device); | ||
1562 | } | ||
1563 | |||
1564 | static void dasd_eckd_kick_validate_server(struct dasd_device *device) | ||
1565 | { | ||
1566 | dasd_get_device(device); | ||
1567 | /* queue call to do_validate_server to the kernel event daemon. */ | ||
1568 | schedule_work(&device->kick_validate); | ||
1569 | } | ||
1570 | |||
1553 | static u32 get_fcx_max_data(struct dasd_device *device) | 1571 | static u32 get_fcx_max_data(struct dasd_device *device) |
1554 | { | 1572 | { |
1555 | #if defined(CONFIG_64BIT) | 1573 | #if defined(CONFIG_64BIT) |
@@ -1595,6 +1613,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1595 | int readonly; | 1613 | int readonly; |
1596 | unsigned long value; | 1614 | unsigned long value; |
1597 | 1615 | ||
1616 | /* setup work queue for validate server*/ | ||
1617 | INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server); | ||
1618 | |||
1598 | if (!ccw_device_is_pathgroup(device->cdev)) { | 1619 | if (!ccw_device_is_pathgroup(device->cdev)) { |
1599 | dev_warn(&device->cdev->dev, | 1620 | dev_warn(&device->cdev->dev, |
1600 | "A channel path group could not be established\n"); | 1621 | "A channel path group could not be established\n"); |
@@ -4259,6 +4280,7 @@ static struct dasd_discipline dasd_eckd_discipline = { | |||
4259 | .restore = dasd_eckd_restore_device, | 4280 | .restore = dasd_eckd_restore_device, |
4260 | .reload = dasd_eckd_reload_device, | 4281 | .reload = dasd_eckd_reload_device, |
4261 | .get_uid = dasd_eckd_get_uid, | 4282 | .get_uid = dasd_eckd_get_uid, |
4283 | .kick_validate = dasd_eckd_kick_validate_server, | ||
4262 | }; | 4284 | }; |
4263 | 4285 | ||
4264 | static int __init | 4286 | static int __init |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index afe8c33422ed..33a6743ddc55 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -355,6 +355,7 @@ struct dasd_discipline { | |||
355 | int (*reload) (struct dasd_device *); | 355 | int (*reload) (struct dasd_device *); |
356 | 356 | ||
357 | int (*get_uid) (struct dasd_device *, struct dasd_uid *); | 357 | int (*get_uid) (struct dasd_device *, struct dasd_uid *); |
358 | void (*kick_validate) (struct dasd_device *); | ||
358 | }; | 359 | }; |
359 | 360 | ||
360 | extern struct dasd_discipline *dasd_diag_discipline_pointer; | 361 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
@@ -455,6 +456,7 @@ struct dasd_device { | |||
455 | struct work_struct kick_work; | 456 | struct work_struct kick_work; |
456 | struct work_struct restore_device; | 457 | struct work_struct restore_device; |
457 | struct work_struct reload_device; | 458 | struct work_struct reload_device; |
459 | struct work_struct kick_validate; | ||
458 | struct timer_list timer; | 460 | struct timer_list timer; |
459 | 461 | ||
460 | debug_info_t *debug_area; | 462 | debug_info_t *debug_area; |