aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c11
-rw-r--r--drivers/s390/block/dasd_eckd.c70
2 files changed, 40 insertions, 41 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index aa95f1001761..80e45de096a9 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1099,11 +1099,20 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1099 cqr = (struct dasd_ccw_req *) intparm; 1099 cqr = (struct dasd_ccw_req *) intparm;
1100 if (!cqr || ((scsw_cc(&irb->scsw) == 1) && 1100 if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
1101 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && 1101 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
1102 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) { 1102 ((scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND) ||
1103 (scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND |
1104 SCSW_STCTL_ALERT_STATUS))))) {
1103 if (cqr && cqr->status == DASD_CQR_IN_IO) 1105 if (cqr && cqr->status == DASD_CQR_IN_IO)
1104 cqr->status = DASD_CQR_QUEUED; 1106 cqr->status = DASD_CQR_QUEUED;
1107 if (cqr)
1108 memcpy(&cqr->irb, irb, sizeof(*irb));
1105 device = dasd_device_from_cdev_locked(cdev); 1109 device = dasd_device_from_cdev_locked(cdev);
1106 if (!IS_ERR(device)) { 1110 if (!IS_ERR(device)) {
1111 device->discipline->dump_sense_dbf(device, irb,
1112 "unsolicited");
1113 if ((device->features & DASD_FEATURE_ERPLOG))
1114 device->discipline->dump_sense(device, cqr,
1115 irb);
1107 dasd_device_clear_timer(device); 1116 dasd_device_clear_timer(device);
1108 device->discipline->handle_unsolicited_interrupt(device, 1117 device->discipline->handle_unsolicited_interrupt(device,
1109 irb); 1118 irb);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index ea0e565ebc9d..50cf96389d2c 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1776,13 +1776,13 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
1776 } 1776 }
1777 1777
1778 /* summary unit check */ 1778 /* summary unit check */
1779 if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) && 1779 sense = dasd_get_sense(irb);
1780 (irb->ecw[7] == 0x0D)) { 1780 if (sense && (sense[7] == 0x0D) &&
1781 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) {
1781 dasd_alias_handle_summary_unit_check(device, irb); 1782 dasd_alias_handle_summary_unit_check(device, irb);
1782 return; 1783 return;
1783 } 1784 }
1784 1785
1785 sense = dasd_get_sense(irb);
1786 /* service information message SIM */ 1786 /* service information message SIM */
1787 if (sense && !(sense[27] & DASD_SENSE_BIT_0) && 1787 if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
1788 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) { 1788 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
@@ -1791,26 +1791,15 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
1791 return; 1791 return;
1792 } 1792 }
1793 1793
1794 if ((scsw_cc(&irb->scsw) == 1) && 1794 if ((scsw_cc(&irb->scsw) == 1) && !sense &&
1795 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && 1795 (scsw_fctl(&irb->scsw) == SCSW_FCTL_START_FUNC) &&
1796 (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) && 1796 (scsw_actl(&irb->scsw) == SCSW_ACTL_START_PEND) &&
1797 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) { 1797 (scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND)) {
1798 /* fake irb do nothing, they are handled elsewhere */ 1798 /* fake irb do nothing, they are handled elsewhere */
1799 dasd_schedule_device_bh(device); 1799 dasd_schedule_device_bh(device);
1800 return; 1800 return;
1801 } 1801 }
1802 1802
1803 if (!sense) {
1804 /* just report other unsolicited interrupts */
1805 DBF_DEV_EVENT(DBF_ERR, device, "%s",
1806 "unsolicited interrupt received");
1807 } else {
1808 DBF_DEV_EVENT(DBF_ERR, device, "%s",
1809 "unsolicited interrupt received "
1810 "(sense available)");
1811 device->discipline->dump_sense_dbf(device, irb, "unsolicited");
1812 }
1813
1814 dasd_schedule_device_bh(device); 1803 dasd_schedule_device_bh(device);
1815 return; 1804 return;
1816}; 1805};
@@ -3093,23 +3082,19 @@ dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb,
3093 char *reason) 3082 char *reason)
3094{ 3083{
3095 u64 *sense; 3084 u64 *sense;
3096 u32 stat; 3085 u64 *stat;
3097 3086
3098 sense = (u64 *) dasd_get_sense(irb); 3087 sense = (u64 *) dasd_get_sense(irb);
3099 stat = scsw_cstat(&irb->scsw); 3088 stat = (u64 *) &irb->scsw;
3100 stat <<= 8;
3101 stat |= scsw_dstat(&irb->scsw);
3102 stat <<= 8;
3103 stat |= scsw_cc(&irb->scsw);
3104
3105 if (sense) { 3089 if (sense) {
3106 DBF_DEV_EVENT(DBF_EMERG, device, 3090 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : "
3107 "%s: %s %06x %016llx %016llx %016llx %016llx", 3091 "%016llx %016llx %016llx %016llx",
3108 reason, scsw_is_tm(&irb->scsw) ? "t" : "c", stat, 3092 reason, *stat, *((u32 *) (stat + 1)),
3109 sense[0], sense[1], sense[2], sense[3]); 3093 sense[0], sense[1], sense[2], sense[3]);
3110 } else { 3094 } else {
3111 DBF_DEV_EVENT(DBF_EMERG, device, "%s", 3095 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : %s",
3112 "SORRY - NO VALID SENSE AVAILABLE\n"); 3096 reason, *stat, *((u32 *) (stat + 1)),
3097 "NO VALID SENSE");
3113 } 3098 }
3114} 3099}
3115 3100
@@ -3135,9 +3120,12 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3135 " I/O status report for device %s:\n", 3120 " I/O status report for device %s:\n",
3136 dev_name(&device->cdev->dev)); 3121 dev_name(&device->cdev->dev));
3137 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3122 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3138 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n", 3123 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
3139 req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), 3124 "CS:%02X RC:%d\n",
3140 scsw_cc(&irb->scsw), req ? req->intrc : 0); 3125 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
3126 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
3127 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
3128 req ? req->intrc : 0);
3141 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3129 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3142 " device %s: Failing CCW: %p\n", 3130 " device %s: Failing CCW: %p\n",
3143 dev_name(&device->cdev->dev), 3131 dev_name(&device->cdev->dev),
@@ -3238,11 +3226,13 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3238 " I/O status report for device %s:\n", 3226 " I/O status report for device %s:\n",
3239 dev_name(&device->cdev->dev)); 3227 dev_name(&device->cdev->dev));
3240 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3228 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3241 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d " 3229 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
3242 "fcxs: 0x%02X schxs: 0x%02X\n", req, 3230 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n",
3243 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), 3231 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
3244 scsw_cc(&irb->scsw), req->intrc, 3232 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
3245 irb->scsw.tm.fcxs, irb->scsw.tm.schxs); 3233 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
3234 irb->scsw.tm.fcxs, irb->scsw.tm.schxs,
3235 req ? req->intrc : 0);
3246 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3236 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3247 " device %s: Failing TCW: %p\n", 3237 " device %s: Failing TCW: %p\n",
3248 dev_name(&device->cdev->dev), 3238 dev_name(&device->cdev->dev),
@@ -3250,7 +3240,7 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3250 3240
3251 tsb = NULL; 3241 tsb = NULL;
3252 sense = NULL; 3242 sense = NULL;
3253 if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01)) 3243 if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs & 0x01))
3254 tsb = tcw_get_tsb( 3244 tsb = tcw_get_tsb(
3255 (struct tcw *)(unsigned long)irb->scsw.tm.tcw); 3245 (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
3256 3246
@@ -3348,7 +3338,7 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3348static void dasd_eckd_dump_sense(struct dasd_device *device, 3338static void dasd_eckd_dump_sense(struct dasd_device *device,
3349 struct dasd_ccw_req *req, struct irb *irb) 3339 struct dasd_ccw_req *req, struct irb *irb)
3350{ 3340{
3351 if (req && scsw_is_tm(&req->irb.scsw)) 3341 if (scsw_is_tm(&irb->scsw))
3352 dasd_eckd_dump_sense_tcw(device, req, irb); 3342 dasd_eckd_dump_sense_tcw(device, req, irb);
3353 else 3343 else
3354 dasd_eckd_dump_sense_ccw(device, req, irb); 3344 dasd_eckd_dump_sense_ccw(device, req, irb);