You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
[S390] cio: introduce fcx enabled scsw format
Extend the scsw data structure to the format required by fcx. Also provide helper functions for easier access to fields which are present in both the traditional as well as the modified format. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
This commit is contained in:
committed by
Heiko Carstens
parent
4f2bd92e3b
commit
23d805b647
@@ -995,14 +995,14 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
now = get_clock();
|
||||
|
||||
DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
|
||||
cdev->dev.bus_id, ((irb->scsw.cstat<<8)|irb->scsw.dstat),
|
||||
(unsigned int) intparm);
|
||||
cdev->dev.bus_id, ((irb->scsw.cmd.cstat << 8) |
|
||||
irb->scsw.cmd.dstat), (unsigned int) intparm);
|
||||
|
||||
/* check for unsolicited interrupts */
|
||||
cqr = (struct dasd_ccw_req *) intparm;
|
||||
if (!cqr || ((irb->scsw.cc == 1) &&
|
||||
(irb->scsw.fctl & SCSW_FCTL_START_FUNC) &&
|
||||
(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) ) {
|
||||
if (!cqr || ((irb->scsw.cmd.cc == 1) &&
|
||||
(irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
|
||||
(irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
|
||||
if (cqr && cqr->status == DASD_CQR_IN_IO)
|
||||
cqr->status = DASD_CQR_QUEUED;
|
||||
device = dasd_device_from_cdev_locked(cdev);
|
||||
@@ -1025,7 +1025,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
|
||||
/* Check for clear pending */
|
||||
if (cqr->status == DASD_CQR_CLEAR_PENDING &&
|
||||
irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
|
||||
irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
|
||||
cqr->status = DASD_CQR_CLEARED;
|
||||
dasd_device_clear_timer(device);
|
||||
wake_up(&dasd_flush_wq);
|
||||
@@ -1041,11 +1041,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
return;
|
||||
}
|
||||
DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
|
||||
((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr);
|
||||
((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
|
||||
next = NULL;
|
||||
expires = 0;
|
||||
if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
|
||||
irb->scsw.cstat == 0 && !irb->esw.esw0.erw.cons) {
|
||||
if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
|
||||
irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
|
||||
/* request was completed successfully */
|
||||
cqr->status = DASD_CQR_SUCCESS;
|
||||
cqr->stopclk = now;
|
||||
|
||||
@@ -1572,7 +1572,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
|
||||
|
||||
/* determine the address of the CCW to be restarted */
|
||||
/* Imprecise ending is not set -> addr from IRB-SCSW */
|
||||
cpa = default_erp->refers->irb.scsw.cpa;
|
||||
cpa = default_erp->refers->irb.scsw.cmd.cpa;
|
||||
|
||||
if (cpa == 0) {
|
||||
|
||||
@@ -1725,7 +1725,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
|
||||
|
||||
/* determine the address of the CCW to be restarted */
|
||||
/* Imprecise ending is not set -> addr from IRB-SCSW */
|
||||
cpa = previous_erp->irb.scsw.cpa;
|
||||
cpa = previous_erp->irb.scsw.cmd.cpa;
|
||||
|
||||
if (cpa == 0) {
|
||||
|
||||
@@ -2171,7 +2171,7 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
|
||||
{
|
||||
struct dasd_device *device = erp->startdev;
|
||||
|
||||
if (erp->refers->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK
|
||||
if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
|
||||
| SCHN_STAT_CHN_CTRL_CHK)) {
|
||||
DEV_MESSAGE(KERN_DEBUG, device, "%s",
|
||||
"channel or interface control check");
|
||||
@@ -2352,9 +2352,9 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
|
||||
|
||||
if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
|
||||
(cqr2->irb.esw.esw0.erw.cons == 0)) {
|
||||
if ((cqr1->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK |
|
||||
if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
|
||||
SCHN_STAT_CHN_CTRL_CHK)) ==
|
||||
(cqr2->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK |
|
||||
(cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
|
||||
SCHN_STAT_CHN_CTRL_CHK)))
|
||||
return 1; /* match with ifcc*/
|
||||
}
|
||||
@@ -2622,8 +2622,9 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
|
||||
}
|
||||
|
||||
/* double-check if current erp/cqr was successfull */
|
||||
if ((cqr->irb.scsw.cstat == 0x00) &&
|
||||
(cqr->irb.scsw.dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
|
||||
if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
|
||||
(cqr->irb.scsw.cmd.dstat ==
|
||||
(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
|
||||
|
||||
DEV_MESSAGE(KERN_DEBUG, device,
|
||||
"ERP called for successful request %p"
|
||||
|
||||
@@ -1404,13 +1404,14 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
|
||||
|
||||
/* first of all check for state change pending interrupt */
|
||||
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
|
||||
if ((irb->scsw.dstat & mask) == mask) {
|
||||
if ((irb->scsw.cmd.dstat & mask) == mask) {
|
||||
dasd_generic_handle_state_change(device);
|
||||
return;
|
||||
}
|
||||
|
||||
/* summary unit check */
|
||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && irb->ecw[7] == 0x0D) {
|
||||
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
|
||||
(irb->ecw[7] == 0x0D)) {
|
||||
dasd_alias_handle_summary_unit_check(device, irb);
|
||||
return;
|
||||
}
|
||||
@@ -2068,11 +2069,11 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
|
||||
device->cdev->dev.bus_id);
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
|
||||
irb->scsw.cstat, irb->scsw.dstat);
|
||||
irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
" device %s: Failing CCW: %p\n",
|
||||
device->cdev->dev.bus_id,
|
||||
(void *) (addr_t) irb->scsw.cpa);
|
||||
(void *) (addr_t) irb->scsw.cmd.cpa);
|
||||
if (irb->esw.esw0.erw.cons) {
|
||||
for (sl = 0; sl < 4; sl++) {
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
@@ -2122,7 +2123,8 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
|
||||
/* scsw->cda is either valid or zero */
|
||||
len = 0;
|
||||
from = ++to;
|
||||
fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */
|
||||
fail = (struct ccw1 *)(addr_t)
|
||||
irb->scsw.cmd.cpa; /* failing CCW */
|
||||
if (from < fail - 2) {
|
||||
from = fail - 2; /* there is a gap - print header */
|
||||
len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n");
|
||||
|
||||
@@ -222,7 +222,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,
|
||||
|
||||
/* first of all check for state change pending interrupt */
|
||||
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
|
||||
if ((irb->scsw.dstat & mask) == mask) {
|
||||
if ((irb->scsw.cmd.dstat & mask) == mask) {
|
||||
dasd_generic_handle_state_change(device);
|
||||
return;
|
||||
}
|
||||
@@ -449,11 +449,11 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
|
||||
device->cdev->dev.bus_id);
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
|
||||
irb->scsw.cstat, irb->scsw.dstat);
|
||||
irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
" device %s: Failing CCW: %p\n",
|
||||
device->cdev->dev.bus_id,
|
||||
(void *) (addr_t) irb->scsw.cpa);
|
||||
(void *) (addr_t) irb->scsw.cmd.cpa);
|
||||
if (irb->esw.esw0.erw.cons) {
|
||||
for (sl = 0; sl < 4; sl++) {
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
@@ -498,11 +498,11 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
|
||||
|
||||
/* print failing CCW area */
|
||||
len = 0;
|
||||
if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
|
||||
act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
|
||||
if (act < ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2) {
|
||||
act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2;
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
|
||||
}
|
||||
end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
|
||||
end = min((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa + 2, last);
|
||||
while (act <= end) {
|
||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||
" CCW %p: %08X %08X DAT:",
|
||||
|
||||
@@ -385,8 +385,8 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
||||
|
||||
raw = cdev->dev.driver_data;
|
||||
req = (struct raw3215_req *) intparm;
|
||||
cstat = irb->scsw.cstat;
|
||||
dstat = irb->scsw.dstat;
|
||||
cstat = irb->scsw.cmd.cstat;
|
||||
dstat = irb->scsw.cmd.dstat;
|
||||
if (cstat != 0) {
|
||||
raw->message = KERN_WARNING
|
||||
"Got nonzero channel status in raw3215_irq "
|
||||
@@ -415,7 +415,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
||||
return; /* That shouldn't happen ... */
|
||||
if (req->type == RAW3215_READ) {
|
||||
/* store residual count, then wait for device end */
|
||||
req->residual = irb->scsw.count;
|
||||
req->residual = irb->scsw.cmd.count;
|
||||
}
|
||||
if (dstat == 0x08)
|
||||
break;
|
||||
|
||||
@@ -411,15 +411,15 @@ static int
|
||||
con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb)
|
||||
{
|
||||
/* Handle ATTN. Schedule tasklet to read aid. */
|
||||
if (irb->scsw.dstat & DEV_STAT_ATTENTION)
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION)
|
||||
con3270_issue_read(cp);
|
||||
|
||||
if (rq) {
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||
rq->rc = -EIO;
|
||||
else
|
||||
/* Normal end. Copy residual count. */
|
||||
rq->rescnt = irb->scsw.count;
|
||||
rq->rescnt = irb->scsw.cmd.count;
|
||||
}
|
||||
return RAW3270_IO_DONE;
|
||||
}
|
||||
|
||||
@@ -216,17 +216,17 @@ static int
|
||||
fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
|
||||
{
|
||||
/* Handle ATTN. Set indication and wake waiters for attention. */
|
||||
if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
|
||||
fp->attention = 1;
|
||||
wake_up(&fp->wait);
|
||||
}
|
||||
|
||||
if (rq) {
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||
rq->rc = -EIO;
|
||||
else
|
||||
/* Normal end. Copy residual count. */
|
||||
rq->rescnt = irb->scsw.count;
|
||||
rq->rescnt = irb->scsw.cmd.count;
|
||||
}
|
||||
return RAW3270_IO_DONE;
|
||||
}
|
||||
|
||||
@@ -372,17 +372,17 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
||||
|
||||
if (IS_ERR(irb))
|
||||
rc = RAW3270_IO_RETRY;
|
||||
else if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
|
||||
else if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) {
|
||||
rq->rc = -EIO;
|
||||
rc = RAW3270_IO_DONE;
|
||||
} else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END |
|
||||
DEV_STAT_UNIT_EXCEP)) {
|
||||
} else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END |
|
||||
DEV_STAT_UNIT_EXCEP)) {
|
||||
/* Handle CE-DE-UE and subsequent UDE */
|
||||
set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
|
||||
rc = RAW3270_IO_BUSY;
|
||||
} else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
|
||||
/* Wait for UDE if busy flag is set. */
|
||||
if (irb->scsw.dstat & DEV_STAT_DEV_END) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
|
||||
clear_bit(RAW3270_FLAGS_BUSY, &rp->flags);
|
||||
/* Got it, now retry. */
|
||||
rc = RAW3270_IO_RETRY;
|
||||
@@ -497,7 +497,7 @@ raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
|
||||
* Unit-Check Processing:
|
||||
* Expect Command Reject or Intervention Required.
|
||||
*/
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
|
||||
/* Request finished abnormally. */
|
||||
if (irb->ecw[0] & SNS0_INTERVENTION_REQ) {
|
||||
set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags);
|
||||
@@ -505,16 +505,16 @@ raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
|
||||
}
|
||||
}
|
||||
if (rq) {
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
|
||||
if (irb->ecw[0] & SNS0_CMD_REJECT)
|
||||
rq->rc = -EOPNOTSUPP;
|
||||
else
|
||||
rq->rc = -EIO;
|
||||
} else
|
||||
/* Request finished normally. Copy residual count. */
|
||||
rq->rescnt = irb->scsw.count;
|
||||
rq->rescnt = irb->scsw.cmd.count;
|
||||
}
|
||||
if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
|
||||
set_bit(RAW3270_FLAGS_ATTN, &view->dev->flags);
|
||||
wake_up(&raw3270_wait_queue);
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ tape_34xx_erp_retry(struct tape_request *request)
|
||||
static int
|
||||
tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)
|
||||
{
|
||||
if (irb->scsw.dstat == 0x85 /* READY */) {
|
||||
if (irb->scsw.cmd.dstat == 0x85) { /* READY */
|
||||
/* A medium was inserted in the drive. */
|
||||
DBF_EVENT(6, "xuud med\n");
|
||||
tape_34xx_delete_sbid_from(device, 0);
|
||||
@@ -844,22 +844,22 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
|
||||
if (request == NULL)
|
||||
return tape_34xx_unsolicited_irq(device, irb);
|
||||
|
||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) &&
|
||||
(irb->scsw.dstat & DEV_STAT_DEV_END) &&
|
||||
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&
|
||||
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
|
||||
(request->op == TO_WRI)) {
|
||||
/* Write at end of volume */
|
||||
PRINT_INFO("End of volume\n"); /* XXX */
|
||||
return tape_34xx_erp_failed(request, -ENOSPC);
|
||||
}
|
||||
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||
return tape_34xx_unit_check(device, request, irb);
|
||||
|
||||
if (irb->scsw.dstat & DEV_STAT_DEV_END) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
|
||||
/*
|
||||
* A unit exception occurs on skipping over a tapemark block.
|
||||
*/
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {
|
||||
if (request->op == TO_BSB || request->op == TO_FSB)
|
||||
request->rescnt++;
|
||||
else
|
||||
|
||||
@@ -837,13 +837,13 @@ tape_3590_erp_retry(struct tape_device *device, struct tape_request *request,
|
||||
static int
|
||||
tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
|
||||
{
|
||||
if (irb->scsw.dstat == DEV_STAT_CHN_END)
|
||||
if (irb->scsw.cmd.dstat == DEV_STAT_CHN_END)
|
||||
/* Probably result of halt ssch */
|
||||
return TAPE_IO_PENDING;
|
||||
else if (irb->scsw.dstat == 0x85)
|
||||
else if (irb->scsw.cmd.dstat == 0x85)
|
||||
/* Device Ready */
|
||||
DBF_EVENT(3, "unsol.irq! tape ready: %08x\n", device->cdev_id);
|
||||
else if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
|
||||
else if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
|
||||
tape_3590_schedule_work(device, TO_READ_ATTMSG);
|
||||
} else {
|
||||
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
|
||||
@@ -1515,18 +1515,19 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request,
|
||||
if (request == NULL)
|
||||
return tape_3590_unsolicited_irq(device, irb);
|
||||
|
||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) &&
|
||||
(irb->scsw.dstat & DEV_STAT_DEV_END) && (request->op == TO_WRI)) {
|
||||
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&
|
||||
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
|
||||
(request->op == TO_WRI)) {
|
||||
/* Write at end of volume */
|
||||
DBF_EVENT(2, "End of volume\n");
|
||||
return tape_3590_erp_failed(device, request, irb, -ENOSPC);
|
||||
}
|
||||
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||
return tape_3590_unit_check(device, request, irb);
|
||||
|
||||
if (irb->scsw.dstat & DEV_STAT_DEV_END) {
|
||||
if (irb->scsw.dstat == DEV_STAT_UNIT_EXCEP) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
|
||||
if (irb->scsw.cmd.dstat == DEV_STAT_UNIT_EXCEP) {
|
||||
if (request->op == TO_FSB || request->op == TO_BSB)
|
||||
request->rescnt++;
|
||||
else
|
||||
@@ -1536,12 +1537,12 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request,
|
||||
return tape_3590_done(device, request);
|
||||
}
|
||||
|
||||
if (irb->scsw.dstat & DEV_STAT_CHN_END) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) {
|
||||
DBF_EVENT(2, "cannel end\n");
|
||||
return TAPE_IO_PENDING;
|
||||
}
|
||||
|
||||
if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
|
||||
DBF_EVENT(2, "Unit Attention when busy..\n");
|
||||
return TAPE_IO_PENDING;
|
||||
}
|
||||
|
||||
@@ -839,7 +839,7 @@ tape_dump_sense(struct tape_device* device, struct tape_request *request,
|
||||
|
||||
PRINT_INFO("-------------------------------------------------\n");
|
||||
PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n",
|
||||
irb->scsw.dstat, irb->scsw.cstat, irb->scsw.cpa);
|
||||
irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
|
||||
PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id);
|
||||
if (request != NULL)
|
||||
PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]);
|
||||
@@ -867,7 +867,7 @@ tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request,
|
||||
else
|
||||
op = "---";
|
||||
DBF_EVENT(3, "DSTAT : %02x CSTAT: %02x\n",
|
||||
irb->scsw.dstat,irb->scsw.cstat);
|
||||
irb->scsw.cmd.dstat, irb->scsw.cmd.cstat);
|
||||
DBF_EVENT(3, "DEVICE: %08x OP\t: %s\n", device->cdev_id, op);
|
||||
sptr = (unsigned int *) irb->ecw;
|
||||
DBF_EVENT(3, "%08x %08x\n", sptr[0], sptr[1]);
|
||||
@@ -1083,10 +1083,11 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
||||
* error might still apply. So we just schedule the request to be
|
||||
* started later.
|
||||
*/
|
||||
if (irb->scsw.cc != 0 && (irb->scsw.fctl & SCSW_FCTL_START_FUNC) &&
|
||||
if (irb->scsw.cmd.cc != 0 &&
|
||||
(irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
|
||||
(request->status == TAPE_REQUEST_IN_IO)) {
|
||||
DBF_EVENT(3,"(%08x): deferred cc=%i, fctl=%i. restarting\n",
|
||||
device->cdev_id, irb->scsw.cc, irb->scsw.fctl);
|
||||
device->cdev_id, irb->scsw.cmd.cc, irb->scsw.cmd.fctl);
|
||||
request->status = TAPE_REQUEST_QUEUED;
|
||||
schedule_delayed_work(&device->tape_dnr, HZ);
|
||||
return;
|
||||
@@ -1094,8 +1095,8 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
||||
|
||||
/* May be an unsolicited irq */
|
||||
if(request != NULL)
|
||||
request->rescnt = irb->scsw.count;
|
||||
else if ((irb->scsw.dstat == 0x85 || irb->scsw.dstat == 0x80) &&
|
||||
request->rescnt = irb->scsw.cmd.count;
|
||||
else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) &&
|
||||
!list_empty(&device->req_queue)) {
|
||||
/* Not Ready to Ready after long busy ? */
|
||||
struct tape_request *req;
|
||||
@@ -1111,7 +1112,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (irb->scsw.dstat != 0x0c) {
|
||||
if (irb->scsw.cmd.dstat != 0x0c) {
|
||||
/* Set the 'ONLINE' flag depending on sense byte 1 */
|
||||
if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
|
||||
device->tape_generic_status |= GMT_ONLINE(~0);
|
||||
|
||||
@@ -663,7 +663,7 @@ static int
|
||||
tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb)
|
||||
{
|
||||
/* Handle ATTN. Schedule tasklet to read aid. */
|
||||
if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
|
||||
if (!tp->throttle)
|
||||
tty3270_issue_read(tp, 0);
|
||||
else
|
||||
@@ -671,11 +671,11 @@ tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb)
|
||||
}
|
||||
|
||||
if (rq) {
|
||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||
rq->rc = -EIO;
|
||||
else
|
||||
/* Normal end. Copy residual count. */
|
||||
rq->rescnt = irb->scsw.count;
|
||||
rq->rescnt = irb->scsw.cmd.count;
|
||||
}
|
||||
return RAW3270_IO_DONE;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,8 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
struct urdev *urd;
|
||||
|
||||
TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
|
||||
intparm, irb->scsw.cstat, irb->scsw.dstat, irb->scsw.count);
|
||||
intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
|
||||
irb->scsw.cmd.count);
|
||||
|
||||
if (!intparm) {
|
||||
TRACE("ur_int_handler: unsolicited interrupt\n");
|
||||
@@ -288,7 +289,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
||||
/* On special conditions irb is an error pointer */
|
||||
if (IS_ERR(irb))
|
||||
urd->io_request_rc = PTR_ERR(irb);
|
||||
else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
|
||||
else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
|
||||
urd->io_request_rc = 0;
|
||||
else
|
||||
urd->io_request_rc = -EIO;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Makefile for the S/390 common i/o drivers
|
||||
#
|
||||
|
||||
obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o
|
||||
obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o
|
||||
ccw_device-objs += device.o device_fsm.o device_ops.o
|
||||
ccw_device-objs += device_id.o device_pgid.o device_status.o
|
||||
obj-y += ccw_device.o cmf.o
|
||||
|
||||
@@ -128,7 +128,7 @@ cio_tpi(void)
|
||||
local_bh_disable();
|
||||
irq_enter ();
|
||||
spin_lock(sch->lock);
|
||||
memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw));
|
||||
memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
|
||||
if (sch->driver && sch->driver->irq)
|
||||
sch->driver->irq(sch);
|
||||
spin_unlock(sch->lock);
|
||||
@@ -202,7 +202,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
|
||||
/*
|
||||
* initialize device status information
|
||||
*/
|
||||
sch->schib.scsw.actl |= SCSW_ACTL_START_PEND;
|
||||
sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
|
||||
return 0;
|
||||
case 1: /* status pending */
|
||||
case 2: /* busy */
|
||||
@@ -237,7 +237,7 @@ cio_resume (struct subchannel *sch)
|
||||
|
||||
switch (ccode) {
|
||||
case 0:
|
||||
sch->schib.scsw.actl |= SCSW_ACTL_RESUME_PEND;
|
||||
sch->schib.scsw.cmd.actl |= SCSW_ACTL_RESUME_PEND;
|
||||
return 0;
|
||||
case 1:
|
||||
return -EBUSY;
|
||||
@@ -277,7 +277,7 @@ cio_halt(struct subchannel *sch)
|
||||
|
||||
switch (ccode) {
|
||||
case 0:
|
||||
sch->schib.scsw.actl |= SCSW_ACTL_HALT_PEND;
|
||||
sch->schib.scsw.cmd.actl |= SCSW_ACTL_HALT_PEND;
|
||||
return 0;
|
||||
case 1: /* status pending */
|
||||
case 2: /* busy */
|
||||
@@ -312,7 +312,7 @@ cio_clear(struct subchannel *sch)
|
||||
|
||||
switch (ccode) {
|
||||
case 0:
|
||||
sch->schib.scsw.actl |= SCSW_ACTL_CLEAR_PEND;
|
||||
sch->schib.scsw.cmd.actl |= SCSW_ACTL_CLEAR_PEND;
|
||||
return 0;
|
||||
default: /* device not operational */
|
||||
return -ENODEV;
|
||||
@@ -458,7 +458,7 @@ int cio_disable_subchannel(struct subchannel *sch)
|
||||
if (ccode == 3) /* Not operational. */
|
||||
return -ENODEV;
|
||||
|
||||
if (sch->schib.scsw.actl != 0)
|
||||
if (scsw_actl(&sch->schib.scsw) != 0)
|
||||
/*
|
||||
* the disable function must not be called while there are
|
||||
* requests pending for completion !
|
||||
@@ -708,7 +708,7 @@ void wait_cons_dev(void)
|
||||
if (!cio_tpi())
|
||||
cpu_relax();
|
||||
spin_lock(console_subchannel.lock);
|
||||
} while (console_subchannel.schib.scsw.actl != 0);
|
||||
} while (console_subchannel.schib.scsw.cmd.actl != 0);
|
||||
/*
|
||||
* restore previous isc value
|
||||
*/
|
||||
|
||||
@@ -48,7 +48,7 @@ struct pmcw {
|
||||
*/
|
||||
struct schib {
|
||||
struct pmcw pmcw; /* path management control word */
|
||||
struct scsw scsw; /* subchannel status word */
|
||||
union scsw scsw; /* subchannel status word */
|
||||
__u64 mba; /* measurement block address */
|
||||
__u8 mda[4]; /* model dependent area */
|
||||
} __attribute__ ((packed,aligned(4)));
|
||||
|
||||
@@ -341,12 +341,12 @@ static int cmf_copy_block(struct ccw_device *cdev)
|
||||
if (stsch(sch->schid, &sch->schib))
|
||||
return -ENODEV;
|
||||
|
||||
if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) {
|
||||
if (scsw_fctl(&sch->schib.scsw) & SCSW_FCTL_START_FUNC) {
|
||||
/* Don't copy if a start function is in progress. */
|
||||
if ((!(sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED)) &&
|
||||
(sch->schib.scsw.actl &
|
||||
if ((!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_SUSPENDED)) &&
|
||||
(scsw_actl(&sch->schib.scsw) &
|
||||
(SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) &&
|
||||
(!(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)))
|
||||
(!(scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_SEC_STATUS)))
|
||||
return -EBUSY;
|
||||
}
|
||||
cmb_data = cdev->private->cmb;
|
||||
|
||||
@@ -1281,7 +1281,7 @@ static int check_for_io_on_path(struct subchannel *sch, int mask)
|
||||
cc = stsch(sch->schid, &sch->schib);
|
||||
if (cc)
|
||||
return 0;
|
||||
if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == mask)
|
||||
if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -133,15 +133,15 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
|
||||
/* Not operational -> done. */
|
||||
return 0;
|
||||
/* Stage 1: cancel io. */
|
||||
if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) &&
|
||||
!(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) {
|
||||
if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) &&
|
||||
!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
|
||||
ret = cio_cancel(sch);
|
||||
if (ret != -EINVAL)
|
||||
return ret;
|
||||
/* cancel io unsuccessful. From now on it is asynchronous. */
|
||||
cdev->private->iretry = 3; /* 3 halt retries. */
|
||||
}
|
||||
if (!(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) {
|
||||
if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
|
||||
/* Stage 2: halt io. */
|
||||
if (cdev->private->iretry) {
|
||||
cdev->private->iretry--;
|
||||
@@ -551,10 +551,11 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
|
||||
/* Deliver fake irb to device driver, if needed. */
|
||||
if (cdev->private->flags.fake_irb) {
|
||||
memset(&cdev->private->irb, 0, sizeof(struct irb));
|
||||
cdev->private->irb.scsw.cc = 1;
|
||||
cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC;
|
||||
cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND;
|
||||
cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND;
|
||||
cdev->private->irb.scsw.cmd.cc = 1;
|
||||
cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC;
|
||||
cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND;
|
||||
cdev->private->irb.scsw.cmd.stctl =
|
||||
SCSW_STCTL_STATUS_PEND;
|
||||
cdev->private->flags.fake_irb = 0;
|
||||
if (cdev->handler)
|
||||
cdev->handler(cdev, cdev->private->intparm,
|
||||
@@ -648,13 +649,10 @@ ccw_device_offline(struct ccw_device *cdev)
|
||||
sch = to_subchannel(cdev->dev.parent);
|
||||
if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv)
|
||||
return -ENODEV;
|
||||
if (cdev->private->state != DEV_STATE_ONLINE) {
|
||||
if (sch->schib.scsw.actl != 0)
|
||||
return -EBUSY;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (sch->schib.scsw.actl != 0)
|
||||
if (scsw_actl(&sch->schib.scsw) != 0)
|
||||
return -EBUSY;
|
||||
if (cdev->private->state != DEV_STATE_ONLINE)
|
||||
return -EINVAL;
|
||||
/* Are we doing path grouping? */
|
||||
if (!cdev->private->options.pgroup) {
|
||||
/* No, set state offline immediately. */
|
||||
@@ -729,9 +727,9 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
|
||||
*/
|
||||
stsch(sch->schid, &sch->schib);
|
||||
|
||||
if (sch->schib.scsw.actl != 0 ||
|
||||
(sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) ||
|
||||
(cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) {
|
||||
if (scsw_actl(&sch->schib.scsw) != 0 ||
|
||||
(scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) ||
|
||||
(scsw_stctl(&cdev->private->irb.scsw) & SCSW_STCTL_STATUS_PEND)) {
|
||||
/*
|
||||
* No final status yet or final status not yet delivered
|
||||
* to the device driver. Can't do path verfication now,
|
||||
@@ -756,10 +754,8 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
|
||||
|
||||
irb = (struct irb *) __LC_IRB;
|
||||
/* Check for unsolicited interrupt. */
|
||||
if ((irb->scsw.stctl ==
|
||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
|
||||
&& (!irb->scsw.cc)) {
|
||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
|
||||
if (!scsw_is_solicited(&irb->scsw)) {
|
||||
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
|
||||
!irb->esw.esw0.erw.cons) {
|
||||
/* Unit check but no sense data. Need basic sense. */
|
||||
if (ccw_device_do_sense(cdev, irb) != 0)
|
||||
@@ -822,9 +818,9 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
|
||||
|
||||
irb = (struct irb *) __LC_IRB;
|
||||
/* Check for unsolicited interrupt. */
|
||||
if (irb->scsw.stctl ==
|
||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
|
||||
if (irb->scsw.cc == 1)
|
||||
if (scsw_stctl(&irb->scsw) ==
|
||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
|
||||
if (scsw_cc(&irb->scsw) == 1)
|
||||
/* Basic sense hasn't started. Try again. */
|
||||
ccw_device_do_sense(cdev, irb);
|
||||
else {
|
||||
@@ -842,7 +838,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
|
||||
* only deliver the halt/clear interrupt to the device driver as if it
|
||||
* had killed the original request.
|
||||
*/
|
||||
if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
|
||||
if (scsw_fctl(&irb->scsw) &
|
||||
(SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
|
||||
/* Retry Basic Sense if requested. */
|
||||
if (cdev->private->flags.intretry) {
|
||||
cdev->private->flags.intretry = 0;
|
||||
@@ -949,9 +946,9 @@ ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event)
|
||||
case DEV_EVENT_INTERRUPT:
|
||||
irb = (struct irb *) __LC_IRB;
|
||||
/* Check for unsolicited interrupt. */
|
||||
if ((irb->scsw.stctl ==
|
||||
if ((scsw_stctl(&irb->scsw) ==
|
||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
|
||||
(!irb->scsw.cc))
|
||||
(!scsw_cc(&irb->scsw)))
|
||||
/* FIXME: we should restart stlck here, but this
|
||||
* is extremely unlikely ... */
|
||||
goto out_wakeup;
|
||||
|
||||
@@ -196,7 +196,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
|
||||
irb = &cdev->private->irb;
|
||||
|
||||
/* Check the error cases. */
|
||||
if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
|
||||
if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
|
||||
/* Retry Sense ID if requested. */
|
||||
if (cdev->private->flags.intretry) {
|
||||
cdev->private->flags.intretry = 0;
|
||||
@@ -234,7 +234,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
|
||||
irb->ecw[6], irb->ecw[7]);
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (irb->scsw.cc == 3) {
|
||||
if (irb->scsw.cmd.cc == 3) {
|
||||
u8 lpm;
|
||||
|
||||
lpm = to_io_private(sch)->orb.lpm;
|
||||
@@ -248,9 +248,9 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
|
||||
}
|
||||
|
||||
/* Did we get a proper answer ? */
|
||||
if (irb->scsw.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF &&
|
||||
if (irb->scsw.cmd.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF &&
|
||||
cdev->private->senseid.reserved == 0xFF) {
|
||||
if (irb->scsw.count < sizeof(struct senseid) - 8)
|
||||
if (irb->scsw.cmd.count < sizeof(struct senseid) - 8)
|
||||
cdev->private->flags.esid = 1;
|
||||
return 0; /* Success */
|
||||
}
|
||||
@@ -260,7 +260,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
|
||||
"subchannel 0.%x.%04x returns status %02X%02X\n",
|
||||
cdev->private->dev_id.devno, sch->schid.ssid,
|
||||
sch->schid.sch_no,
|
||||
irb->scsw.dstat, irb->scsw.cstat);
|
||||
irb->scsw.cmd.dstat, irb->scsw.cmd.cstat);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
@@ -277,9 +277,9 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
|
||||
sch = to_subchannel(cdev->dev.parent);
|
||||
irb = (struct irb *) __LC_IRB;
|
||||
/* Retry sense id, if needed. */
|
||||
if (irb->scsw.stctl ==
|
||||
if (irb->scsw.cmd.stctl ==
|
||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
|
||||
if ((irb->scsw.cc == 1) || !irb->scsw.actl) {
|
||||
if ((irb->scsw.cmd.cc == 1) || !irb->scsw.cmd.actl) {
|
||||
ret = __ccw_device_sense_id_start(cdev);
|
||||
if (ret && ret != -EBUSY)
|
||||
ccw_device_sense_id_done(cdev, ret);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user