summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Höppner <hoeppner@linux.ibm.com>2018-07-03 04:56:51 -0400
committerVasily Gorbik <gor@linux.ibm.com>2019-07-11 14:39:54 -0400
commit9e12e54c7a8f616190beffb0f7ce778a86aec175 (patch)
treead64419a0817aa9e476abac0e65effdb4248b2c2
parent7e64db1597fe114b83fe17d0ba96c6aa5fca419a (diff)
s390/dasd: Handle out-of-space constraint
The storage server issues three different types of out-of-space messages whenever the Extent Pool or Extent Repository space runs short. When a configured warning watermark is reached, the physical space is completeley exhausted, or the capacity constraints have been relieved, a message is received. A log entry for the sysadmin to react to is generated in any case. In case the physical space is completely exhausted, sense data that reads "no space left on device" is received. In this case, currently running I/O will be blocked until space has either been released or added to the extent pool, and a relieve message was received via an attention interrupt. Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com> Reviewed-by: Stefan Haberland <sth@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--drivers/s390/block/dasd.c58
-rw-r--r--drivers/s390/block/dasd_eckd.c159
-rw-r--r--drivers/s390/block/dasd_eckd.h23
-rw-r--r--drivers/s390/block/dasd_eer.c1
-rw-r--r--drivers/s390/block/dasd_int.h5
5 files changed, 243 insertions, 3 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index ae460543f59d..6cca72782af6 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1659,6 +1659,14 @@ static int dasd_ese_needs_format(struct dasd_block *block, struct irb *irb)
1659 scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN; 1659 scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN;
1660} 1660}
1661 1661
1662static int dasd_ese_oos_cond(u8 *sense)
1663{
1664 return sense[0] & SNS0_EQUIPMENT_CHECK &&
1665 sense[1] & SNS1_PERM_ERR &&
1666 sense[1] & SNS1_WRITE_INHIBITED &&
1667 sense[25] == 0x01;
1668}
1669
1662/* 1670/*
1663 * Interrupt handler for "normal" ssch-io based dasd devices. 1671 * Interrupt handler for "normal" ssch-io based dasd devices.
1664 */ 1672 */
@@ -1727,6 +1735,17 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1727 test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); 1735 test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
1728 nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) && 1736 nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) &&
1729 test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); 1737 test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
1738
1739 /*
1740 * Extent pool probably out-of-space.
1741 * Stop device and check exhaust level.
1742 */
1743 if (dasd_ese_oos_cond(sense)) {
1744 dasd_generic_space_exhaust(device, cqr);
1745 device->discipline->ext_pool_exhaust(device, cqr);
1746 dasd_put_device(device);
1747 return;
1748 }
1730 } 1749 }
1731 if (!(fp_suppressed || nrf_suppressed)) 1750 if (!(fp_suppressed || nrf_suppressed))
1732 device->discipline->dump_sense_dbf(device, irb, "int"); 1751 device->discipline->dump_sense_dbf(device, irb, "int");
@@ -2021,7 +2040,7 @@ static void __dasd_device_check_expire(struct dasd_device *device)
2021static int __dasd_device_is_unusable(struct dasd_device *device, 2040static int __dasd_device_is_unusable(struct dasd_device *device,
2022 struct dasd_ccw_req *cqr) 2041 struct dasd_ccw_req *cqr)
2023{ 2042{
2024 int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM); 2043 int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM | DASD_STOPPED_NOSPC);
2025 2044
2026 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) && 2045 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) &&
2027 !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { 2046 !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
@@ -3877,6 +3896,43 @@ int dasd_generic_verify_path(struct dasd_device *device, __u8 lpm)
3877} 3896}
3878EXPORT_SYMBOL_GPL(dasd_generic_verify_path); 3897EXPORT_SYMBOL_GPL(dasd_generic_verify_path);
3879 3898
3899void dasd_generic_space_exhaust(struct dasd_device *device,
3900 struct dasd_ccw_req *cqr)
3901{
3902 dasd_eer_write(device, NULL, DASD_EER_NOSPC);
3903
3904 if (device->state < DASD_STATE_BASIC)
3905 return;
3906
3907 if (cqr->status == DASD_CQR_IN_IO ||
3908 cqr->status == DASD_CQR_CLEAR_PENDING) {
3909 cqr->status = DASD_CQR_QUEUED;
3910 cqr->retries++;
3911 }
3912 dasd_device_set_stop_bits(device, DASD_STOPPED_NOSPC);
3913 dasd_device_clear_timer(device);
3914 dasd_schedule_device_bh(device);
3915}
3916EXPORT_SYMBOL_GPL(dasd_generic_space_exhaust);
3917
3918void dasd_generic_space_avail(struct dasd_device *device)
3919{
3920 dev_info(&device->cdev->dev, "Extent pool space is available\n");
3921 DBF_DEV_EVENT(DBF_WARNING, device, "%s", "space available");
3922
3923 dasd_device_remove_stop_bits(device, DASD_STOPPED_NOSPC);
3924 dasd_schedule_device_bh(device);
3925
3926 if (device->block) {
3927 dasd_schedule_block_bh(device->block);
3928 if (device->block->request_queue)
3929 blk_mq_run_hw_queues(device->block->request_queue, true);
3930 }
3931 if (!device->stopped)
3932 wake_up(&generic_waitq);
3933}
3934EXPORT_SYMBOL_GPL(dasd_generic_space_avail);
3935
3880/* 3936/*
3881 * clear active requests and requeue them to block layer if possible 3937 * clear active requests and requeue them to block layer if possible
3882 */ 3938 */
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 7f7429a99a67..fc53e1e221f0 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -89,6 +89,19 @@ static struct {
89} *dasd_reserve_req; 89} *dasd_reserve_req;
90static DEFINE_MUTEX(dasd_reserve_mutex); 90static DEFINE_MUTEX(dasd_reserve_mutex);
91 91
92static struct {
93 struct dasd_ccw_req cqr;
94 struct ccw1 ccw[2];
95 char data[40];
96} *dasd_vol_info_req;
97static DEFINE_MUTEX(dasd_vol_info_mutex);
98
99struct ext_pool_exhaust_work_data {
100 struct work_struct worker;
101 struct dasd_device *device;
102 struct dasd_device *base;
103};
104
92/* definitions for the path verification worker */ 105/* definitions for the path verification worker */
93struct path_verification_work_data { 106struct path_verification_work_data {
94 struct work_struct worker; 107 struct work_struct worker;
@@ -1479,6 +1492,7 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device)
1479 struct dasd_rssd_vsq *vsq; 1492 struct dasd_rssd_vsq *vsq;
1480 struct dasd_ccw_req *cqr; 1493 struct dasd_ccw_req *cqr;
1481 struct ccw1 *ccw; 1494 struct ccw1 *ccw;
1495 int useglobal;
1482 int rc; 1496 int rc;
1483 1497
1484 /* This command cannot be executed on an alias device */ 1498 /* This command cannot be executed on an alias device */
@@ -1486,12 +1500,20 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device)
1486 private->uid.type == UA_HYPER_PAV_ALIAS) 1500 private->uid.type == UA_HYPER_PAV_ALIAS)
1487 return 0; 1501 return 0;
1488 1502
1503 useglobal = 0;
1489 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 /* PSF + RSSD */, 1504 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 /* PSF + RSSD */,
1490 sizeof(*prssdp) + sizeof(*vsq), device, NULL); 1505 sizeof(*prssdp) + sizeof(*vsq), device, NULL);
1491 if (IS_ERR(cqr)) { 1506 if (IS_ERR(cqr)) {
1492 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", 1507 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1493 "Could not allocate initialization request"); 1508 "Could not allocate initialization request");
1494 return PTR_ERR(cqr); 1509 mutex_lock(&dasd_vol_info_mutex);
1510 useglobal = 1;
1511 cqr = &dasd_vol_info_req->cqr;
1512 memset(cqr, 0, sizeof(*cqr));
1513 memset(dasd_vol_info_req, 0, sizeof(*dasd_vol_info_req));
1514 cqr->cpaddr = &dasd_vol_info_req->ccw;
1515 cqr->data = &dasd_vol_info_req->data;
1516 cqr->magic = DASD_ECKD_MAGIC;
1495 } 1517 }
1496 1518
1497 /* Prepare for Read Subsystem Data */ 1519 /* Prepare for Read Subsystem Data */
@@ -1535,7 +1557,10 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device)
1535 "Reading the volume storage information failed with rc=%d\n", rc); 1557 "Reading the volume storage information failed with rc=%d\n", rc);
1536 } 1558 }
1537 1559
1538 dasd_sfree_request(cqr, cqr->memdev); 1560 if (useglobal)
1561 mutex_unlock(&dasd_vol_info_mutex);
1562 else
1563 dasd_sfree_request(cqr, cqr->memdev);
1539 1564
1540 return rc; 1565 return rc;
1541} 1566}
@@ -1590,6 +1615,53 @@ static int dasd_eckd_logical_capacity(struct dasd_device *device)
1590 return private->vsq.logical_capacity; 1615 return private->vsq.logical_capacity;
1591} 1616}
1592 1617
1618static void dasd_eckd_ext_pool_exhaust_work(struct work_struct *work)
1619{
1620 struct ext_pool_exhaust_work_data *data;
1621 struct dasd_device *device;
1622 struct dasd_device *base;
1623
1624 data = container_of(work, struct ext_pool_exhaust_work_data, worker);
1625 device = data->device;
1626 base = data->base;
1627
1628 if (!base)
1629 base = device;
1630 if (dasd_eckd_space_configured(base) != 0) {
1631 dasd_generic_space_avail(device);
1632 } else {
1633 dev_warn(&device->cdev->dev, "No space left in the extent pool\n");
1634 DBF_DEV_EVENT(DBF_WARNING, device, "%s", "out of space");
1635 }
1636
1637 dasd_put_device(device);
1638 kfree(data);
1639}
1640
1641static int dasd_eckd_ext_pool_exhaust(struct dasd_device *device,
1642 struct dasd_ccw_req *cqr)
1643{
1644 struct ext_pool_exhaust_work_data *data;
1645
1646 data = kzalloc(sizeof(*data), GFP_ATOMIC);
1647 if (!data)
1648 return -ENOMEM;
1649 INIT_WORK(&data->worker, dasd_eckd_ext_pool_exhaust_work);
1650 dasd_get_device(device);
1651 data->device = device;
1652
1653 if (cqr->block)
1654 data->base = cqr->block->base;
1655 else if (cqr->basedev)
1656 data->base = cqr->basedev;
1657 else
1658 data->base = NULL;
1659
1660 schedule_work(&data->worker);
1661
1662 return 0;
1663}
1664
1593static void dasd_eckd_cpy_ext_pool_data(struct dasd_device *device, 1665static void dasd_eckd_cpy_ext_pool_data(struct dasd_device *device,
1594 struct dasd_rssd_lcq *lcq) 1666 struct dasd_rssd_lcq *lcq)
1595{ 1667{
@@ -2099,6 +2171,9 @@ dasd_eckd_analysis_ccw(struct dasd_device *device)
2099 cqr->retries = 255; 2171 cqr->retries = 255;
2100 cqr->buildclk = get_tod_clock(); 2172 cqr->buildclk = get_tod_clock();
2101 cqr->status = DASD_CQR_FILLED; 2173 cqr->status = DASD_CQR_FILLED;
2174 /* Set flags to suppress output for expected errors */
2175 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
2176
2102 return cqr; 2177 return cqr;
2103} 2178}
2104 2179
@@ -6267,6 +6342,73 @@ static void dasd_eckd_handle_cuir(struct dasd_device *device, void *messages,
6267 device->discipline->check_attention(device, lpum); 6342 device->discipline->check_attention(device, lpum);
6268} 6343}
6269 6344
6345static void dasd_eckd_oos_resume(struct dasd_device *device)
6346{
6347 struct dasd_eckd_private *private = device->private;
6348 struct alias_pav_group *pavgroup, *tempgroup;
6349 struct dasd_device *dev, *n;
6350 unsigned long flags;
6351
6352 spin_lock_irqsave(&private->lcu->lock, flags);
6353 list_for_each_entry_safe(dev, n, &private->lcu->active_devices,
6354 alias_list) {
6355 if (dev->stopped & DASD_STOPPED_NOSPC)
6356 dasd_generic_space_avail(dev);
6357 }
6358 list_for_each_entry_safe(dev, n, &private->lcu->inactive_devices,
6359 alias_list) {
6360 if (dev->stopped & DASD_STOPPED_NOSPC)
6361 dasd_generic_space_avail(dev);
6362 }
6363 /* devices in PAV groups */
6364 list_for_each_entry_safe(pavgroup, tempgroup,
6365 &private->lcu->grouplist,
6366 group) {
6367 list_for_each_entry_safe(dev, n, &pavgroup->baselist,
6368 alias_list) {
6369 if (dev->stopped & DASD_STOPPED_NOSPC)
6370 dasd_generic_space_avail(dev);
6371 }
6372 list_for_each_entry_safe(dev, n, &pavgroup->aliaslist,
6373 alias_list) {
6374 if (dev->stopped & DASD_STOPPED_NOSPC)
6375 dasd_generic_space_avail(dev);
6376 }
6377 }
6378 spin_unlock_irqrestore(&private->lcu->lock, flags);
6379}
6380
6381static void dasd_eckd_handle_oos(struct dasd_device *device, void *messages,
6382 __u8 lpum)
6383{
6384 struct dasd_oos_message *oos = messages;
6385
6386 switch (oos->code) {
6387 case REPO_WARN:
6388 case POOL_WARN:
6389 dev_warn(&device->cdev->dev,
6390 "Extent pool usage has reached a critical value\n");
6391 dasd_eckd_oos_resume(device);
6392 break;
6393 case REPO_EXHAUST:
6394 case POOL_EXHAUST:
6395 dev_warn(&device->cdev->dev,
6396 "Extent pool is exhausted\n");
6397 break;
6398 case REPO_RELIEVE:
6399 case POOL_RELIEVE:
6400 dev_info(&device->cdev->dev,
6401 "Extent pool physical space constraint has been relieved\n");
6402 break;
6403 }
6404
6405 /* In any case, update related data */
6406 dasd_eckd_read_ext_pool_info(device);
6407
6408 /* to make sure there is no attention left schedule work again */
6409 device->discipline->check_attention(device, lpum);
6410}
6411
6270static void dasd_eckd_check_attention_work(struct work_struct *work) 6412static void dasd_eckd_check_attention_work(struct work_struct *work)
6271{ 6413{
6272 struct check_attention_work_data *data; 6414 struct check_attention_work_data *data;
@@ -6285,9 +6427,14 @@ static void dasd_eckd_check_attention_work(struct work_struct *work)
6285 rc = dasd_eckd_read_message_buffer(device, messages, data->lpum); 6427 rc = dasd_eckd_read_message_buffer(device, messages, data->lpum);
6286 if (rc) 6428 if (rc)
6287 goto out; 6429 goto out;
6430
6288 if (messages->length == ATTENTION_LENGTH_CUIR && 6431 if (messages->length == ATTENTION_LENGTH_CUIR &&
6289 messages->format == ATTENTION_FORMAT_CUIR) 6432 messages->format == ATTENTION_FORMAT_CUIR)
6290 dasd_eckd_handle_cuir(device, messages, data->lpum); 6433 dasd_eckd_handle_cuir(device, messages, data->lpum);
6434 if (messages->length == ATTENTION_LENGTH_OOS &&
6435 messages->format == ATTENTION_FORMAT_OOS)
6436 dasd_eckd_handle_oos(device, messages, data->lpum);
6437
6291out: 6438out:
6292 dasd_put_device(device); 6439 dasd_put_device(device);
6293 kfree(messages); 6440 kfree(messages);
@@ -6501,6 +6648,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
6501 .ext_pool_cap_at_warnlevel = dasd_eckd_ext_pool_cap_at_warnlevel, 6648 .ext_pool_cap_at_warnlevel = dasd_eckd_ext_pool_cap_at_warnlevel,
6502 .ext_pool_warn_thrshld = dasd_eckd_ext_pool_warn_thrshld, 6649 .ext_pool_warn_thrshld = dasd_eckd_ext_pool_warn_thrshld,
6503 .ext_pool_oos = dasd_eckd_ext_pool_oos, 6650 .ext_pool_oos = dasd_eckd_ext_pool_oos,
6651 .ext_pool_exhaust = dasd_eckd_ext_pool_exhaust,
6504 .ese_format = dasd_eckd_ese_format, 6652 .ese_format = dasd_eckd_ese_format,
6505 .ese_read = dasd_eckd_ese_read, 6653 .ese_read = dasd_eckd_ese_read,
6506}; 6654};
@@ -6515,16 +6663,22 @@ dasd_eckd_init(void)
6515 GFP_KERNEL | GFP_DMA); 6663 GFP_KERNEL | GFP_DMA);
6516 if (!dasd_reserve_req) 6664 if (!dasd_reserve_req)
6517 return -ENOMEM; 6665 return -ENOMEM;
6666 dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req),
6667 GFP_KERNEL | GFP_DMA);
6668 if (!dasd_vol_info_req)
6669 return -ENOMEM;
6518 path_verification_worker = kmalloc(sizeof(*path_verification_worker), 6670 path_verification_worker = kmalloc(sizeof(*path_verification_worker),
6519 GFP_KERNEL | GFP_DMA); 6671 GFP_KERNEL | GFP_DMA);
6520 if (!path_verification_worker) { 6672 if (!path_verification_worker) {
6521 kfree(dasd_reserve_req); 6673 kfree(dasd_reserve_req);
6674 kfree(dasd_vol_info_req);
6522 return -ENOMEM; 6675 return -ENOMEM;
6523 } 6676 }
6524 rawpadpage = (void *)__get_free_page(GFP_KERNEL); 6677 rawpadpage = (void *)__get_free_page(GFP_KERNEL);
6525 if (!rawpadpage) { 6678 if (!rawpadpage) {
6526 kfree(path_verification_worker); 6679 kfree(path_verification_worker);
6527 kfree(dasd_reserve_req); 6680 kfree(dasd_reserve_req);
6681 kfree(dasd_vol_info_req);
6528 return -ENOMEM; 6682 return -ENOMEM;
6529 } 6683 }
6530 ret = ccw_driver_register(&dasd_eckd_driver); 6684 ret = ccw_driver_register(&dasd_eckd_driver);
@@ -6533,6 +6687,7 @@ dasd_eckd_init(void)
6533 else { 6687 else {
6534 kfree(path_verification_worker); 6688 kfree(path_verification_worker);
6535 kfree(dasd_reserve_req); 6689 kfree(dasd_reserve_req);
6690 kfree(dasd_vol_info_req);
6536 free_page((unsigned long)rawpadpage); 6691 free_page((unsigned long)rawpadpage);
6537 } 6692 }
6538 return ret; 6693 return ret;
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 13112ba9f93f..6943508d0f1d 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -90,10 +90,22 @@
90#define CUIR_RESUME 0x02 90#define CUIR_RESUME 0x02
91 91
92/* 92/*
93 * Out-of-space (OOS) Codes
94 */
95#define REPO_WARN 0x01
96#define REPO_EXHAUST 0x02
97#define POOL_WARN 0x03
98#define POOL_EXHAUST 0x04
99#define REPO_RELIEVE 0x05
100#define POOL_RELIEVE 0x06
101
102/*
93 * attention message definitions 103 * attention message definitions
94 */ 104 */
95#define ATTENTION_LENGTH_CUIR 0x0e 105#define ATTENTION_LENGTH_CUIR 0x0e
96#define ATTENTION_FORMAT_CUIR 0x01 106#define ATTENTION_FORMAT_CUIR 0x01
107#define ATTENTION_LENGTH_OOS 0x10
108#define ATTENTION_FORMAT_OOS 0x06
97 109
98#define DASD_ECKD_PG_GROUPED 0x10 110#define DASD_ECKD_PG_GROUPED 0x10
99 111
@@ -449,6 +461,17 @@ struct dasd_rssd_lcq {
449 struct dasd_ext_pool_sum ext_pool_sum[448]; 461 struct dasd_ext_pool_sum ext_pool_sum[448];
450} __packed; 462} __packed;
451 463
464struct dasd_oos_message {
465 __u16 length;
466 __u8 format;
467 __u8 code;
468 __u8 percentage_empty;
469 __u8 reserved;
470 __u16 ext_pool_id;
471 __u16 token;
472 __u8 unused[6];
473} __packed;
474
452struct dasd_cuir_message { 475struct dasd_cuir_message {
453 __u16 length; 476 __u16 length;
454 __u8 format; 477 __u8 format;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 93bb09da7fdc..5ae64af9ccea 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -386,6 +386,7 @@ void dasd_eer_write(struct dasd_device *device, struct dasd_ccw_req *cqr,
386 dasd_eer_write_standard_trigger(device, cqr, id); 386 dasd_eer_write_standard_trigger(device, cqr, id);
387 break; 387 break;
388 case DASD_EER_NOPATH: 388 case DASD_EER_NOPATH:
389 case DASD_EER_NOSPC:
389 dasd_eer_write_standard_trigger(device, NULL, id); 390 dasd_eer_write_standard_trigger(device, NULL, id);
390 break; 391 break;
391 case DASD_EER_STATECHANGE: 392 case DASD_EER_STATECHANGE:
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index aa4fd0d206bb..91c9f9586e0f 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -386,6 +386,7 @@ struct dasd_discipline {
386 int (*ext_pool_cap_at_warnlevel)(struct dasd_device *); 386 int (*ext_pool_cap_at_warnlevel)(struct dasd_device *);
387 int (*ext_pool_warn_thrshld)(struct dasd_device *); 387 int (*ext_pool_warn_thrshld)(struct dasd_device *);
388 int (*ext_pool_oos)(struct dasd_device *); 388 int (*ext_pool_oos)(struct dasd_device *);
389 int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *);
389 struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *); 390 struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *);
390 void (*ese_read)(struct dasd_ccw_req *); 391 void (*ese_read)(struct dasd_ccw_req *);
391}; 392};
@@ -407,6 +408,7 @@ extern struct dasd_discipline *dasd_diag_discipline_pointer;
407#define DASD_EER_NOPATH 2 408#define DASD_EER_NOPATH 2
408#define DASD_EER_STATECHANGE 3 409#define DASD_EER_STATECHANGE 3
409#define DASD_EER_PPRCSUSPEND 4 410#define DASD_EER_PPRCSUSPEND 4
411#define DASD_EER_NOSPC 5
410 412
411/* DASD path handling */ 413/* DASD path handling */
412 414
@@ -581,6 +583,7 @@ struct dasd_queue {
581#define DASD_STOPPED_SU 16 /* summary unit check handling */ 583#define DASD_STOPPED_SU 16 /* summary unit check handling */
582#define DASD_STOPPED_PM 32 /* pm state transition */ 584#define DASD_STOPPED_PM 32 /* pm state transition */
583#define DASD_UNRESUMED_PM 64 /* pm resume failed state */ 585#define DASD_UNRESUMED_PM 64 /* pm resume failed state */
586#define DASD_STOPPED_NOSPC 128 /* no space left */
584 587
585/* per device flags */ 588/* per device flags */
586#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 589#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
@@ -776,6 +779,8 @@ int dasd_generic_restore_device(struct ccw_device *);
776enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *); 779enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *);
777void dasd_generic_path_event(struct ccw_device *, int *); 780void dasd_generic_path_event(struct ccw_device *, int *);
778int dasd_generic_verify_path(struct dasd_device *, __u8); 781int dasd_generic_verify_path(struct dasd_device *, __u8);
782void dasd_generic_space_exhaust(struct dasd_device *, struct dasd_ccw_req *);
783void dasd_generic_space_avail(struct dasd_device *);
779 784
780int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); 785int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
781char *dasd_get_sense(struct irb *); 786char *dasd_get_sense(struct irb *);