.. | .. |
---|
103 | 103 | }; |
---|
104 | 104 | |
---|
105 | 105 | /* definitions for the path verification worker */ |
---|
106 | | -struct path_verification_work_data { |
---|
| 106 | +struct pe_handler_work_data { |
---|
107 | 107 | struct work_struct worker; |
---|
108 | 108 | struct dasd_device *device; |
---|
109 | 109 | struct dasd_ccw_req cqr; |
---|
.. | .. |
---|
112 | 112 | int isglobal; |
---|
113 | 113 | __u8 tbvpm; |
---|
114 | 114 | }; |
---|
115 | | -static struct path_verification_work_data *path_verification_worker; |
---|
116 | | -static DEFINE_MUTEX(dasd_path_verification_mutex); |
---|
| 115 | +static struct pe_handler_work_data *pe_handler_worker; |
---|
| 116 | +static DEFINE_MUTEX(dasd_pe_handler_mutex); |
---|
117 | 117 | |
---|
118 | 118 | struct check_attention_work_data { |
---|
119 | 119 | struct work_struct worker; |
---|
.. | .. |
---|
1219 | 1219 | } |
---|
1220 | 1220 | |
---|
1221 | 1221 | static int rebuild_device_uid(struct dasd_device *device, |
---|
1222 | | - struct path_verification_work_data *data) |
---|
| 1222 | + struct pe_handler_work_data *data) |
---|
1223 | 1223 | { |
---|
1224 | 1224 | struct dasd_eckd_private *private = device->private; |
---|
1225 | 1225 | __u8 lpm, opm = dasd_path_get_opm(device); |
---|
.. | .. |
---|
1257 | 1257 | return rc; |
---|
1258 | 1258 | } |
---|
1259 | 1259 | |
---|
1260 | | -static void do_path_verification_work(struct work_struct *work) |
---|
| 1260 | +static void dasd_eckd_path_available_action(struct dasd_device *device, |
---|
| 1261 | + struct pe_handler_work_data *data) |
---|
1261 | 1262 | { |
---|
1262 | | - struct path_verification_work_data *data; |
---|
1263 | | - struct dasd_device *device; |
---|
1264 | 1263 | struct dasd_eckd_private path_private; |
---|
1265 | 1264 | struct dasd_uid *uid; |
---|
1266 | 1265 | __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; |
---|
.. | .. |
---|
1269 | 1268 | char print_uid[60]; |
---|
1270 | 1269 | int rc; |
---|
1271 | 1270 | |
---|
1272 | | - data = container_of(work, struct path_verification_work_data, worker); |
---|
1273 | | - device = data->device; |
---|
1274 | | - |
---|
1275 | | - /* delay path verification until device was resumed */ |
---|
1276 | | - if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { |
---|
1277 | | - schedule_work(work); |
---|
1278 | | - return; |
---|
1279 | | - } |
---|
1280 | | - /* check if path verification already running and delay if so */ |
---|
1281 | | - if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) { |
---|
1282 | | - schedule_work(work); |
---|
1283 | | - return; |
---|
1284 | | - } |
---|
1285 | 1271 | opm = 0; |
---|
1286 | 1272 | npm = 0; |
---|
1287 | 1273 | ppm = 0; |
---|
.. | .. |
---|
1418 | 1404 | dasd_path_add_nohpfpm(device, hpfpm); |
---|
1419 | 1405 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
---|
1420 | 1406 | } |
---|
| 1407 | +} |
---|
| 1408 | + |
---|
| 1409 | +static void do_pe_handler_work(struct work_struct *work) |
---|
| 1410 | +{ |
---|
| 1411 | + struct pe_handler_work_data *data; |
---|
| 1412 | + struct dasd_device *device; |
---|
| 1413 | + |
---|
| 1414 | + data = container_of(work, struct pe_handler_work_data, worker); |
---|
| 1415 | + device = data->device; |
---|
| 1416 | + |
---|
| 1417 | + /* delay path verification until device was resumed */ |
---|
| 1418 | + if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { |
---|
| 1419 | + schedule_work(work); |
---|
| 1420 | + return; |
---|
| 1421 | + } |
---|
| 1422 | + /* check if path verification already running and delay if so */ |
---|
| 1423 | + if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) { |
---|
| 1424 | + schedule_work(work); |
---|
| 1425 | + return; |
---|
| 1426 | + } |
---|
| 1427 | + |
---|
| 1428 | + dasd_eckd_path_available_action(device, data); |
---|
| 1429 | + |
---|
1421 | 1430 | clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags); |
---|
1422 | 1431 | dasd_put_device(device); |
---|
1423 | 1432 | if (data->isglobal) |
---|
1424 | | - mutex_unlock(&dasd_path_verification_mutex); |
---|
| 1433 | + mutex_unlock(&dasd_pe_handler_mutex); |
---|
1425 | 1434 | else |
---|
1426 | 1435 | kfree(data); |
---|
1427 | 1436 | } |
---|
1428 | 1437 | |
---|
1429 | | -static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm) |
---|
| 1438 | +static int dasd_eckd_pe_handler(struct dasd_device *device, __u8 lpm) |
---|
1430 | 1439 | { |
---|
1431 | | - struct path_verification_work_data *data; |
---|
| 1440 | + struct pe_handler_work_data *data; |
---|
1432 | 1441 | |
---|
1433 | 1442 | data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA); |
---|
1434 | 1443 | if (!data) { |
---|
1435 | | - if (mutex_trylock(&dasd_path_verification_mutex)) { |
---|
1436 | | - data = path_verification_worker; |
---|
| 1444 | + if (mutex_trylock(&dasd_pe_handler_mutex)) { |
---|
| 1445 | + data = pe_handler_worker; |
---|
1437 | 1446 | data->isglobal = 1; |
---|
1438 | | - } else |
---|
| 1447 | + } else { |
---|
1439 | 1448 | return -ENOMEM; |
---|
| 1449 | + } |
---|
1440 | 1450 | } else { |
---|
1441 | 1451 | memset(data, 0, sizeof(*data)); |
---|
1442 | 1452 | data->isglobal = 0; |
---|
1443 | 1453 | } |
---|
1444 | | - INIT_WORK(&data->worker, do_path_verification_work); |
---|
| 1454 | + INIT_WORK(&data->worker, do_pe_handler_work); |
---|
1445 | 1455 | dasd_get_device(device); |
---|
1446 | 1456 | data->device = device; |
---|
1447 | 1457 | data->tbvpm = lpm; |
---|
.. | .. |
---|
6694 | 6704 | .check_device = dasd_eckd_check_characteristics, |
---|
6695 | 6705 | .uncheck_device = dasd_eckd_uncheck_device, |
---|
6696 | 6706 | .do_analysis = dasd_eckd_do_analysis, |
---|
6697 | | - .verify_path = dasd_eckd_verify_path, |
---|
| 6707 | + .pe_handler = dasd_eckd_pe_handler, |
---|
6698 | 6708 | .basic_to_ready = dasd_eckd_basic_to_ready, |
---|
6699 | 6709 | .online_to_ready = dasd_eckd_online_to_ready, |
---|
6700 | 6710 | .basic_to_known = dasd_eckd_basic_to_known, |
---|
.. | .. |
---|
6753 | 6763 | return -ENOMEM; |
---|
6754 | 6764 | dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req), |
---|
6755 | 6765 | GFP_KERNEL | GFP_DMA); |
---|
6756 | | - if (!dasd_vol_info_req) |
---|
| 6766 | + if (!dasd_vol_info_req) { |
---|
| 6767 | + kfree(dasd_reserve_req); |
---|
6757 | 6768 | return -ENOMEM; |
---|
6758 | | - path_verification_worker = kmalloc(sizeof(*path_verification_worker), |
---|
6759 | | - GFP_KERNEL | GFP_DMA); |
---|
6760 | | - if (!path_verification_worker) { |
---|
| 6769 | + } |
---|
| 6770 | + pe_handler_worker = kmalloc(sizeof(*pe_handler_worker), |
---|
| 6771 | + GFP_KERNEL | GFP_DMA); |
---|
| 6772 | + if (!pe_handler_worker) { |
---|
6761 | 6773 | kfree(dasd_reserve_req); |
---|
6762 | 6774 | kfree(dasd_vol_info_req); |
---|
6763 | 6775 | return -ENOMEM; |
---|
6764 | 6776 | } |
---|
6765 | 6777 | rawpadpage = (void *)__get_free_page(GFP_KERNEL); |
---|
6766 | 6778 | if (!rawpadpage) { |
---|
6767 | | - kfree(path_verification_worker); |
---|
| 6779 | + kfree(pe_handler_worker); |
---|
6768 | 6780 | kfree(dasd_reserve_req); |
---|
6769 | 6781 | kfree(dasd_vol_info_req); |
---|
6770 | 6782 | return -ENOMEM; |
---|
.. | .. |
---|
6773 | 6785 | if (!ret) |
---|
6774 | 6786 | wait_for_device_probe(); |
---|
6775 | 6787 | else { |
---|
6776 | | - kfree(path_verification_worker); |
---|
| 6788 | + kfree(pe_handler_worker); |
---|
6777 | 6789 | kfree(dasd_reserve_req); |
---|
6778 | 6790 | kfree(dasd_vol_info_req); |
---|
6779 | 6791 | free_page((unsigned long)rawpadpage); |
---|
.. | .. |
---|
6785 | 6797 | dasd_eckd_cleanup(void) |
---|
6786 | 6798 | { |
---|
6787 | 6799 | ccw_driver_unregister(&dasd_eckd_driver); |
---|
6788 | | - kfree(path_verification_worker); |
---|
| 6800 | + kfree(pe_handler_worker); |
---|
6789 | 6801 | kfree(dasd_reserve_req); |
---|
6790 | 6802 | free_page((unsigned long)rawpadpage); |
---|
6791 | 6803 | } |
---|