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();
|
now = get_clock();
|
||||||
|
|
||||||
DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
|
DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
|
||||||
cdev->dev.bus_id, ((irb->scsw.cstat<<8)|irb->scsw.dstat),
|
cdev->dev.bus_id, ((irb->scsw.cmd.cstat << 8) |
|
||||||
(unsigned int) intparm);
|
irb->scsw.cmd.dstat), (unsigned int) intparm);
|
||||||
|
|
||||||
/* check for unsolicited interrupts */
|
/* check for unsolicited interrupts */
|
||||||
cqr = (struct dasd_ccw_req *) intparm;
|
cqr = (struct dasd_ccw_req *) intparm;
|
||||||
if (!cqr || ((irb->scsw.cc == 1) &&
|
if (!cqr || ((irb->scsw.cmd.cc == 1) &&
|
||||||
(irb->scsw.fctl & SCSW_FCTL_START_FUNC) &&
|
(irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
|
||||||
(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) ) {
|
(irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
|
||||||
if (cqr && cqr->status == DASD_CQR_IN_IO)
|
if (cqr && cqr->status == DASD_CQR_IN_IO)
|
||||||
cqr->status = DASD_CQR_QUEUED;
|
cqr->status = DASD_CQR_QUEUED;
|
||||||
device = dasd_device_from_cdev_locked(cdev);
|
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 */
|
/* Check for clear pending */
|
||||||
if (cqr->status == DASD_CQR_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;
|
cqr->status = DASD_CQR_CLEARED;
|
||||||
dasd_device_clear_timer(device);
|
dasd_device_clear_timer(device);
|
||||||
wake_up(&dasd_flush_wq);
|
wake_up(&dasd_flush_wq);
|
||||||
@@ -1041,11 +1041,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
|
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;
|
next = NULL;
|
||||||
expires = 0;
|
expires = 0;
|
||||||
if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
|
if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
|
||||||
irb->scsw.cstat == 0 && !irb->esw.esw0.erw.cons) {
|
irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
|
||||||
/* request was completed successfully */
|
/* request was completed successfully */
|
||||||
cqr->status = DASD_CQR_SUCCESS;
|
cqr->status = DASD_CQR_SUCCESS;
|
||||||
cqr->stopclk = now;
|
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 */
|
/* determine the address of the CCW to be restarted */
|
||||||
/* Imprecise ending is not set -> addr from IRB-SCSW */
|
/* 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) {
|
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 */
|
/* determine the address of the CCW to be restarted */
|
||||||
/* Imprecise ending is not set -> addr from IRB-SCSW */
|
/* 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) {
|
if (cpa == 0) {
|
||||||
|
|
||||||
@@ -2171,7 +2171,7 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
|
|||||||
{
|
{
|
||||||
struct dasd_device *device = erp->startdev;
|
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)) {
|
| SCHN_STAT_CHN_CTRL_CHK)) {
|
||||||
DEV_MESSAGE(KERN_DEBUG, device, "%s",
|
DEV_MESSAGE(KERN_DEBUG, device, "%s",
|
||||||
"channel or interface control check");
|
"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) &&
|
if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
|
||||||
(cqr2->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)) ==
|
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)))
|
SCHN_STAT_CHN_CTRL_CHK)))
|
||||||
return 1; /* match with ifcc*/
|
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 */
|
/* double-check if current erp/cqr was successfull */
|
||||||
if ((cqr->irb.scsw.cstat == 0x00) &&
|
if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
|
||||||
(cqr->irb.scsw.dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
|
(cqr->irb.scsw.cmd.dstat ==
|
||||||
|
(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
|
||||||
|
|
||||||
DEV_MESSAGE(KERN_DEBUG, device,
|
DEV_MESSAGE(KERN_DEBUG, device,
|
||||||
"ERP called for successful request %p"
|
"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 */
|
/* first of all check for state change pending interrupt */
|
||||||
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
|
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);
|
dasd_generic_handle_state_change(device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* summary unit check */
|
/* 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);
|
dasd_alias_handle_summary_unit_check(device, irb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2068,11 +2069,11 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
|
|||||||
device->cdev->dev.bus_id);
|
device->cdev->dev.bus_id);
|
||||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||||
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
|
" 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
|
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||||
" device %s: Failing CCW: %p\n",
|
" device %s: Failing CCW: %p\n",
|
||||||
device->cdev->dev.bus_id,
|
device->cdev->dev.bus_id,
|
||||||
(void *) (addr_t) irb->scsw.cpa);
|
(void *) (addr_t) irb->scsw.cmd.cpa);
|
||||||
if (irb->esw.esw0.erw.cons) {
|
if (irb->esw.esw0.erw.cons) {
|
||||||
for (sl = 0; sl < 4; sl++) {
|
for (sl = 0; sl < 4; sl++) {
|
||||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
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 */
|
/* scsw->cda is either valid or zero */
|
||||||
len = 0;
|
len = 0;
|
||||||
from = ++to;
|
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) {
|
if (from < fail - 2) {
|
||||||
from = fail - 2; /* there is a gap - print header */
|
from = fail - 2; /* there is a gap - print header */
|
||||||
len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n");
|
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 */
|
/* first of all check for state change pending interrupt */
|
||||||
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
|
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);
|
dasd_generic_handle_state_change(device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -449,11 +449,11 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
|
|||||||
device->cdev->dev.bus_id);
|
device->cdev->dev.bus_id);
|
||||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||||
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
|
" 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
|
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||||
" device %s: Failing CCW: %p\n",
|
" device %s: Failing CCW: %p\n",
|
||||||
device->cdev->dev.bus_id,
|
device->cdev->dev.bus_id,
|
||||||
(void *) (addr_t) irb->scsw.cpa);
|
(void *) (addr_t) irb->scsw.cmd.cpa);
|
||||||
if (irb->esw.esw0.erw.cons) {
|
if (irb->esw.esw0.erw.cons) {
|
||||||
for (sl = 0; sl < 4; sl++) {
|
for (sl = 0; sl < 4; sl++) {
|
||||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
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 */
|
/* print failing CCW area */
|
||||||
len = 0;
|
len = 0;
|
||||||
if (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.cpa) - 2;
|
act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2;
|
||||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
|
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) {
|
while (act <= end) {
|
||||||
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
|
||||||
" CCW %p: %08X %08X DAT:",
|
" 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;
|
raw = cdev->dev.driver_data;
|
||||||
req = (struct raw3215_req *) intparm;
|
req = (struct raw3215_req *) intparm;
|
||||||
cstat = irb->scsw.cstat;
|
cstat = irb->scsw.cmd.cstat;
|
||||||
dstat = irb->scsw.dstat;
|
dstat = irb->scsw.cmd.dstat;
|
||||||
if (cstat != 0) {
|
if (cstat != 0) {
|
||||||
raw->message = KERN_WARNING
|
raw->message = KERN_WARNING
|
||||||
"Got nonzero channel status in raw3215_irq "
|
"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 ... */
|
return; /* That shouldn't happen ... */
|
||||||
if (req->type == RAW3215_READ) {
|
if (req->type == RAW3215_READ) {
|
||||||
/* store residual count, then wait for device end */
|
/* store residual count, then wait for device end */
|
||||||
req->residual = irb->scsw.count;
|
req->residual = irb->scsw.cmd.count;
|
||||||
}
|
}
|
||||||
if (dstat == 0x08)
|
if (dstat == 0x08)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -411,15 +411,15 @@ static int
|
|||||||
con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb)
|
con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb)
|
||||||
{
|
{
|
||||||
/* Handle ATTN. Schedule tasklet to read aid. */
|
/* 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);
|
con3270_issue_read(cp);
|
||||||
|
|
||||||
if (rq) {
|
if (rq) {
|
||||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||||
rq->rc = -EIO;
|
rq->rc = -EIO;
|
||||||
else
|
else
|
||||||
/* Normal end. Copy residual count. */
|
/* Normal end. Copy residual count. */
|
||||||
rq->rescnt = irb->scsw.count;
|
rq->rescnt = irb->scsw.cmd.count;
|
||||||
}
|
}
|
||||||
return RAW3270_IO_DONE;
|
return RAW3270_IO_DONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,17 +216,17 @@ static int
|
|||||||
fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
|
fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
|
||||||
{
|
{
|
||||||
/* Handle ATTN. Set indication and wake waiters for attention. */
|
/* 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;
|
fp->attention = 1;
|
||||||
wake_up(&fp->wait);
|
wake_up(&fp->wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rq) {
|
if (rq) {
|
||||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||||
rq->rc = -EIO;
|
rq->rc = -EIO;
|
||||||
else
|
else
|
||||||
/* Normal end. Copy residual count. */
|
/* Normal end. Copy residual count. */
|
||||||
rq->rescnt = irb->scsw.count;
|
rq->rescnt = irb->scsw.cmd.count;
|
||||||
}
|
}
|
||||||
return RAW3270_IO_DONE;
|
return RAW3270_IO_DONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,17 +372,17 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
|||||||
|
|
||||||
if (IS_ERR(irb))
|
if (IS_ERR(irb))
|
||||||
rc = RAW3270_IO_RETRY;
|
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;
|
rq->rc = -EIO;
|
||||||
rc = RAW3270_IO_DONE;
|
rc = RAW3270_IO_DONE;
|
||||||
} 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 |
|
||||||
DEV_STAT_UNIT_EXCEP)) {
|
DEV_STAT_UNIT_EXCEP)) {
|
||||||
/* Handle CE-DE-UE and subsequent UDE */
|
/* Handle CE-DE-UE and subsequent UDE */
|
||||||
set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
|
set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
|
||||||
rc = RAW3270_IO_BUSY;
|
rc = RAW3270_IO_BUSY;
|
||||||
} else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
|
} else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
|
||||||
/* Wait for UDE if busy flag is set. */
|
/* 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);
|
clear_bit(RAW3270_FLAGS_BUSY, &rp->flags);
|
||||||
/* Got it, now retry. */
|
/* Got it, now retry. */
|
||||||
rc = RAW3270_IO_RETRY;
|
rc = RAW3270_IO_RETRY;
|
||||||
@@ -497,7 +497,7 @@ raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
|
|||||||
* Unit-Check Processing:
|
* Unit-Check Processing:
|
||||||
* Expect Command Reject or Intervention Required.
|
* 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. */
|
/* Request finished abnormally. */
|
||||||
if (irb->ecw[0] & SNS0_INTERVENTION_REQ) {
|
if (irb->ecw[0] & SNS0_INTERVENTION_REQ) {
|
||||||
set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags);
|
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 (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)
|
if (irb->ecw[0] & SNS0_CMD_REJECT)
|
||||||
rq->rc = -EOPNOTSUPP;
|
rq->rc = -EOPNOTSUPP;
|
||||||
else
|
else
|
||||||
rq->rc = -EIO;
|
rq->rc = -EIO;
|
||||||
} else
|
} else
|
||||||
/* Request finished normally. Copy residual count. */
|
/* 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);
|
set_bit(RAW3270_FLAGS_ATTN, &view->dev->flags);
|
||||||
wake_up(&raw3270_wait_queue);
|
wake_up(&raw3270_wait_queue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ tape_34xx_erp_retry(struct tape_request *request)
|
|||||||
static int
|
static int
|
||||||
tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)
|
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. */
|
/* A medium was inserted in the drive. */
|
||||||
DBF_EVENT(6, "xuud med\n");
|
DBF_EVENT(6, "xuud med\n");
|
||||||
tape_34xx_delete_sbid_from(device, 0);
|
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)
|
if (request == NULL)
|
||||||
return tape_34xx_unsolicited_irq(device, irb);
|
return tape_34xx_unsolicited_irq(device, irb);
|
||||||
|
|
||||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) &&
|
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&
|
||||||
(irb->scsw.dstat & DEV_STAT_DEV_END) &&
|
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
|
||||||
(request->op == TO_WRI)) {
|
(request->op == TO_WRI)) {
|
||||||
/* Write at end of volume */
|
/* Write at end of volume */
|
||||||
PRINT_INFO("End of volume\n"); /* XXX */
|
PRINT_INFO("End of volume\n"); /* XXX */
|
||||||
return tape_34xx_erp_failed(request, -ENOSPC);
|
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);
|
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.
|
* 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)
|
if (request->op == TO_BSB || request->op == TO_FSB)
|
||||||
request->rescnt++;
|
request->rescnt++;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -837,13 +837,13 @@ tape_3590_erp_retry(struct tape_device *device, struct tape_request *request,
|
|||||||
static int
|
static int
|
||||||
tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
|
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 */
|
/* Probably result of halt ssch */
|
||||||
return TAPE_IO_PENDING;
|
return TAPE_IO_PENDING;
|
||||||
else if (irb->scsw.dstat == 0x85)
|
else if (irb->scsw.cmd.dstat == 0x85)
|
||||||
/* Device Ready */
|
/* Device Ready */
|
||||||
DBF_EVENT(3, "unsol.irq! tape ready: %08x\n", device->cdev_id);
|
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);
|
tape_3590_schedule_work(device, TO_READ_ATTMSG);
|
||||||
} else {
|
} else {
|
||||||
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
|
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)
|
if (request == NULL)
|
||||||
return tape_3590_unsolicited_irq(device, irb);
|
return tape_3590_unsolicited_irq(device, irb);
|
||||||
|
|
||||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) &&
|
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&
|
||||||
(irb->scsw.dstat & DEV_STAT_DEV_END) && (request->op == TO_WRI)) {
|
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
|
||||||
|
(request->op == TO_WRI)) {
|
||||||
/* Write at end of volume */
|
/* Write at end of volume */
|
||||||
DBF_EVENT(2, "End of volume\n");
|
DBF_EVENT(2, "End of volume\n");
|
||||||
return tape_3590_erp_failed(device, request, irb, -ENOSPC);
|
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);
|
return tape_3590_unit_check(device, request, irb);
|
||||||
|
|
||||||
if (irb->scsw.dstat & DEV_STAT_DEV_END) {
|
if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
|
||||||
if (irb->scsw.dstat == DEV_STAT_UNIT_EXCEP) {
|
if (irb->scsw.cmd.dstat == DEV_STAT_UNIT_EXCEP) {
|
||||||
if (request->op == TO_FSB || request->op == TO_BSB)
|
if (request->op == TO_FSB || request->op == TO_BSB)
|
||||||
request->rescnt++;
|
request->rescnt++;
|
||||||
else
|
else
|
||||||
@@ -1536,12 +1537,12 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request,
|
|||||||
return tape_3590_done(device, 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");
|
DBF_EVENT(2, "cannel end\n");
|
||||||
return TAPE_IO_PENDING;
|
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");
|
DBF_EVENT(2, "Unit Attention when busy..\n");
|
||||||
return TAPE_IO_PENDING;
|
return TAPE_IO_PENDING;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ tape_dump_sense(struct tape_device* device, struct tape_request *request,
|
|||||||
|
|
||||||
PRINT_INFO("-------------------------------------------------\n");
|
PRINT_INFO("-------------------------------------------------\n");
|
||||||
PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\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);
|
PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id);
|
||||||
if (request != NULL)
|
if (request != NULL)
|
||||||
PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]);
|
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
|
else
|
||||||
op = "---";
|
op = "---";
|
||||||
DBF_EVENT(3, "DSTAT : %02x CSTAT: %02x\n",
|
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);
|
DBF_EVENT(3, "DEVICE: %08x OP\t: %s\n", device->cdev_id, op);
|
||||||
sptr = (unsigned int *) irb->ecw;
|
sptr = (unsigned int *) irb->ecw;
|
||||||
DBF_EVENT(3, "%08x %08x\n", sptr[0], sptr[1]);
|
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
|
* error might still apply. So we just schedule the request to be
|
||||||
* started later.
|
* 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)) {
|
(request->status == TAPE_REQUEST_IN_IO)) {
|
||||||
DBF_EVENT(3,"(%08x): deferred cc=%i, fctl=%i. restarting\n",
|
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;
|
request->status = TAPE_REQUEST_QUEUED;
|
||||||
schedule_delayed_work(&device->tape_dnr, HZ);
|
schedule_delayed_work(&device->tape_dnr, HZ);
|
||||||
return;
|
return;
|
||||||
@@ -1094,8 +1095,8 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
|||||||
|
|
||||||
/* May be an unsolicited irq */
|
/* May be an unsolicited irq */
|
||||||
if(request != NULL)
|
if(request != NULL)
|
||||||
request->rescnt = irb->scsw.count;
|
request->rescnt = irb->scsw.cmd.count;
|
||||||
else if ((irb->scsw.dstat == 0x85 || irb->scsw.dstat == 0x80) &&
|
else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) &&
|
||||||
!list_empty(&device->req_queue)) {
|
!list_empty(&device->req_queue)) {
|
||||||
/* Not Ready to Ready after long busy ? */
|
/* Not Ready to Ready after long busy ? */
|
||||||
struct tape_request *req;
|
struct tape_request *req;
|
||||||
@@ -1111,7 +1112,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (irb->scsw.dstat != 0x0c) {
|
if (irb->scsw.cmd.dstat != 0x0c) {
|
||||||
/* Set the 'ONLINE' flag depending on sense byte 1 */
|
/* Set the 'ONLINE' flag depending on sense byte 1 */
|
||||||
if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
|
if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
|
||||||
device->tape_generic_status |= GMT_ONLINE(~0);
|
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)
|
tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb)
|
||||||
{
|
{
|
||||||
/* Handle ATTN. Schedule tasklet to read aid. */
|
/* 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)
|
if (!tp->throttle)
|
||||||
tty3270_issue_read(tp, 0);
|
tty3270_issue_read(tp, 0);
|
||||||
else
|
else
|
||||||
@@ -671,11 +671,11 @@ tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rq) {
|
if (rq) {
|
||||||
if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
|
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
|
||||||
rq->rc = -EIO;
|
rq->rc = -EIO;
|
||||||
else
|
else
|
||||||
/* Normal end. Copy residual count. */
|
/* Normal end. Copy residual count. */
|
||||||
rq->rescnt = irb->scsw.count;
|
rq->rescnt = irb->scsw.cmd.count;
|
||||||
}
|
}
|
||||||
return RAW3270_IO_DONE;
|
return RAW3270_IO_DONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,7 +277,8 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
|
|||||||
struct urdev *urd;
|
struct urdev *urd;
|
||||||
|
|
||||||
TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
|
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) {
|
if (!intparm) {
|
||||||
TRACE("ur_int_handler: unsolicited interrupt\n");
|
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 */
|
/* On special conditions irb is an error pointer */
|
||||||
if (IS_ERR(irb))
|
if (IS_ERR(irb))
|
||||||
urd->io_request_rc = PTR_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;
|
urd->io_request_rc = 0;
|
||||||
else
|
else
|
||||||
urd->io_request_rc = -EIO;
|
urd->io_request_rc = -EIO;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Makefile for the S/390 common i/o drivers
|
# 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.o device_fsm.o device_ops.o
|
||||||
ccw_device-objs += device_id.o device_pgid.o device_status.o
|
ccw_device-objs += device_id.o device_pgid.o device_status.o
|
||||||
obj-y += ccw_device.o cmf.o
|
obj-y += ccw_device.o cmf.o
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ cio_tpi(void)
|
|||||||
local_bh_disable();
|
local_bh_disable();
|
||||||
irq_enter ();
|
irq_enter ();
|
||||||
spin_lock(sch->lock);
|
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)
|
if (sch->driver && sch->driver->irq)
|
||||||
sch->driver->irq(sch);
|
sch->driver->irq(sch);
|
||||||
spin_unlock(sch->lock);
|
spin_unlock(sch->lock);
|
||||||
@@ -202,7 +202,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
|
|||||||
/*
|
/*
|
||||||
* initialize device status information
|
* initialize device status information
|
||||||
*/
|
*/
|
||||||
sch->schib.scsw.actl |= SCSW_ACTL_START_PEND;
|
sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
|
||||||
return 0;
|
return 0;
|
||||||
case 1: /* status pending */
|
case 1: /* status pending */
|
||||||
case 2: /* busy */
|
case 2: /* busy */
|
||||||
@@ -237,7 +237,7 @@ cio_resume (struct subchannel *sch)
|
|||||||
|
|
||||||
switch (ccode) {
|
switch (ccode) {
|
||||||
case 0:
|
case 0:
|
||||||
sch->schib.scsw.actl |= SCSW_ACTL_RESUME_PEND;
|
sch->schib.scsw.cmd.actl |= SCSW_ACTL_RESUME_PEND;
|
||||||
return 0;
|
return 0;
|
||||||
case 1:
|
case 1:
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
@@ -277,7 +277,7 @@ cio_halt(struct subchannel *sch)
|
|||||||
|
|
||||||
switch (ccode) {
|
switch (ccode) {
|
||||||
case 0:
|
case 0:
|
||||||
sch->schib.scsw.actl |= SCSW_ACTL_HALT_PEND;
|
sch->schib.scsw.cmd.actl |= SCSW_ACTL_HALT_PEND;
|
||||||
return 0;
|
return 0;
|
||||||
case 1: /* status pending */
|
case 1: /* status pending */
|
||||||
case 2: /* busy */
|
case 2: /* busy */
|
||||||
@@ -312,7 +312,7 @@ cio_clear(struct subchannel *sch)
|
|||||||
|
|
||||||
switch (ccode) {
|
switch (ccode) {
|
||||||
case 0:
|
case 0:
|
||||||
sch->schib.scsw.actl |= SCSW_ACTL_CLEAR_PEND;
|
sch->schib.scsw.cmd.actl |= SCSW_ACTL_CLEAR_PEND;
|
||||||
return 0;
|
return 0;
|
||||||
default: /* device not operational */
|
default: /* device not operational */
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@@ -458,7 +458,7 @@ int cio_disable_subchannel(struct subchannel *sch)
|
|||||||
if (ccode == 3) /* Not operational. */
|
if (ccode == 3) /* Not operational. */
|
||||||
return -ENODEV;
|
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
|
* the disable function must not be called while there are
|
||||||
* requests pending for completion !
|
* requests pending for completion !
|
||||||
@@ -708,7 +708,7 @@ void wait_cons_dev(void)
|
|||||||
if (!cio_tpi())
|
if (!cio_tpi())
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
spin_lock(console_subchannel.lock);
|
spin_lock(console_subchannel.lock);
|
||||||
} while (console_subchannel.schib.scsw.actl != 0);
|
} while (console_subchannel.schib.scsw.cmd.actl != 0);
|
||||||
/*
|
/*
|
||||||
* restore previous isc value
|
* restore previous isc value
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ struct pmcw {
|
|||||||
*/
|
*/
|
||||||
struct schib {
|
struct schib {
|
||||||
struct pmcw pmcw; /* path management control word */
|
struct pmcw pmcw; /* path management control word */
|
||||||
struct scsw scsw; /* subchannel status word */
|
union scsw scsw; /* subchannel status word */
|
||||||
__u64 mba; /* measurement block address */
|
__u64 mba; /* measurement block address */
|
||||||
__u8 mda[4]; /* model dependent area */
|
__u8 mda[4]; /* model dependent area */
|
||||||
} __attribute__ ((packed,aligned(4)));
|
} __attribute__ ((packed,aligned(4)));
|
||||||
|
|||||||
@@ -341,12 +341,12 @@ static int cmf_copy_block(struct ccw_device *cdev)
|
|||||||
if (stsch(sch->schid, &sch->schib))
|
if (stsch(sch->schid, &sch->schib))
|
||||||
return -ENODEV;
|
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. */
|
/* Don't copy if a start function is in progress. */
|
||||||
if ((!(sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED)) &&
|
if ((!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_SUSPENDED)) &&
|
||||||
(sch->schib.scsw.actl &
|
(scsw_actl(&sch->schib.scsw) &
|
||||||
(SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) &&
|
(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;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
cmb_data = cdev->private->cmb;
|
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);
|
cc = stsch(sch->schid, &sch->schib);
|
||||||
if (cc)
|
if (cc)
|
||||||
return 0;
|
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 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,15 +133,15 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
|
|||||||
/* Not operational -> done. */
|
/* Not operational -> done. */
|
||||||
return 0;
|
return 0;
|
||||||
/* Stage 1: cancel io. */
|
/* Stage 1: cancel io. */
|
||||||
if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) &&
|
if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) &&
|
||||||
!(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) {
|
!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
|
||||||
ret = cio_cancel(sch);
|
ret = cio_cancel(sch);
|
||||||
if (ret != -EINVAL)
|
if (ret != -EINVAL)
|
||||||
return ret;
|
return ret;
|
||||||
/* cancel io unsuccessful. From now on it is asynchronous. */
|
/* cancel io unsuccessful. From now on it is asynchronous. */
|
||||||
cdev->private->iretry = 3; /* 3 halt retries. */
|
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. */
|
/* Stage 2: halt io. */
|
||||||
if (cdev->private->iretry) {
|
if (cdev->private->iretry) {
|
||||||
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. */
|
/* Deliver fake irb to device driver, if needed. */
|
||||||
if (cdev->private->flags.fake_irb) {
|
if (cdev->private->flags.fake_irb) {
|
||||||
memset(&cdev->private->irb, 0, sizeof(struct irb));
|
memset(&cdev->private->irb, 0, sizeof(struct irb));
|
||||||
cdev->private->irb.scsw.cc = 1;
|
cdev->private->irb.scsw.cmd.cc = 1;
|
||||||
cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC;
|
cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC;
|
||||||
cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND;
|
cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND;
|
||||||
cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND;
|
cdev->private->irb.scsw.cmd.stctl =
|
||||||
|
SCSW_STCTL_STATUS_PEND;
|
||||||
cdev->private->flags.fake_irb = 0;
|
cdev->private->flags.fake_irb = 0;
|
||||||
if (cdev->handler)
|
if (cdev->handler)
|
||||||
cdev->handler(cdev, cdev->private->intparm,
|
cdev->handler(cdev, cdev->private->intparm,
|
||||||
@@ -648,13 +649,10 @@ ccw_device_offline(struct ccw_device *cdev)
|
|||||||
sch = to_subchannel(cdev->dev.parent);
|
sch = to_subchannel(cdev->dev.parent);
|
||||||
if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv)
|
if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
if (cdev->private->state != DEV_STATE_ONLINE) {
|
if (scsw_actl(&sch->schib.scsw) != 0)
|
||||||
if (sch->schib.scsw.actl != 0)
|
|
||||||
return -EBUSY;
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (sch->schib.scsw.actl != 0)
|
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
if (cdev->private->state != DEV_STATE_ONLINE)
|
||||||
|
return -EINVAL;
|
||||||
/* Are we doing path grouping? */
|
/* Are we doing path grouping? */
|
||||||
if (!cdev->private->options.pgroup) {
|
if (!cdev->private->options.pgroup) {
|
||||||
/* No, set state offline immediately. */
|
/* 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);
|
stsch(sch->schid, &sch->schib);
|
||||||
|
|
||||||
if (sch->schib.scsw.actl != 0 ||
|
if (scsw_actl(&sch->schib.scsw) != 0 ||
|
||||||
(sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) ||
|
(scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) ||
|
||||||
(cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) {
|
(scsw_stctl(&cdev->private->irb.scsw) & SCSW_STCTL_STATUS_PEND)) {
|
||||||
/*
|
/*
|
||||||
* No final status yet or final status not yet delivered
|
* No final status yet or final status not yet delivered
|
||||||
* to the device driver. Can't do path verfication now,
|
* 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;
|
irb = (struct irb *) __LC_IRB;
|
||||||
/* Check for unsolicited interrupt. */
|
/* Check for unsolicited interrupt. */
|
||||||
if ((irb->scsw.stctl ==
|
if (!scsw_is_solicited(&irb->scsw)) {
|
||||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
|
if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
|
||||||
&& (!irb->scsw.cc)) {
|
|
||||||
if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
|
|
||||||
!irb->esw.esw0.erw.cons) {
|
!irb->esw.esw0.erw.cons) {
|
||||||
/* Unit check but no sense data. Need basic sense. */
|
/* Unit check but no sense data. Need basic sense. */
|
||||||
if (ccw_device_do_sense(cdev, irb) != 0)
|
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;
|
irb = (struct irb *) __LC_IRB;
|
||||||
/* Check for unsolicited interrupt. */
|
/* Check for unsolicited interrupt. */
|
||||||
if (irb->scsw.stctl ==
|
if (scsw_stctl(&irb->scsw) ==
|
||||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
|
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
|
||||||
if (irb->scsw.cc == 1)
|
if (scsw_cc(&irb->scsw) == 1)
|
||||||
/* Basic sense hasn't started. Try again. */
|
/* Basic sense hasn't started. Try again. */
|
||||||
ccw_device_do_sense(cdev, irb);
|
ccw_device_do_sense(cdev, irb);
|
||||||
else {
|
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
|
* only deliver the halt/clear interrupt to the device driver as if it
|
||||||
* had killed the original request.
|
* 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. */
|
/* Retry Basic Sense if requested. */
|
||||||
if (cdev->private->flags.intretry) {
|
if (cdev->private->flags.intretry) {
|
||||||
cdev->private->flags.intretry = 0;
|
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:
|
case DEV_EVENT_INTERRUPT:
|
||||||
irb = (struct irb *) __LC_IRB;
|
irb = (struct irb *) __LC_IRB;
|
||||||
/* Check for unsolicited interrupt. */
|
/* Check for unsolicited interrupt. */
|
||||||
if ((irb->scsw.stctl ==
|
if ((scsw_stctl(&irb->scsw) ==
|
||||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
|
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
|
||||||
(!irb->scsw.cc))
|
(!scsw_cc(&irb->scsw)))
|
||||||
/* FIXME: we should restart stlck here, but this
|
/* FIXME: we should restart stlck here, but this
|
||||||
* is extremely unlikely ... */
|
* is extremely unlikely ... */
|
||||||
goto out_wakeup;
|
goto out_wakeup;
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
|
|||||||
irb = &cdev->private->irb;
|
irb = &cdev->private->irb;
|
||||||
|
|
||||||
/* Check the error cases. */
|
/* 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. */
|
/* Retry Sense ID if requested. */
|
||||||
if (cdev->private->flags.intretry) {
|
if (cdev->private->flags.intretry) {
|
||||||
cdev->private->flags.intretry = 0;
|
cdev->private->flags.intretry = 0;
|
||||||
@@ -234,7 +234,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
|
|||||||
irb->ecw[6], irb->ecw[7]);
|
irb->ecw[6], irb->ecw[7]);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (irb->scsw.cc == 3) {
|
if (irb->scsw.cmd.cc == 3) {
|
||||||
u8 lpm;
|
u8 lpm;
|
||||||
|
|
||||||
lpm = to_io_private(sch)->orb.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 ? */
|
/* 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) {
|
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;
|
cdev->private->flags.esid = 1;
|
||||||
return 0; /* Success */
|
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",
|
"subchannel 0.%x.%04x returns status %02X%02X\n",
|
||||||
cdev->private->dev_id.devno, sch->schid.ssid,
|
cdev->private->dev_id.devno, sch->schid.ssid,
|
||||||
sch->schid.sch_no,
|
sch->schid.sch_no,
|
||||||
irb->scsw.dstat, irb->scsw.cstat);
|
irb->scsw.cmd.dstat, irb->scsw.cmd.cstat);
|
||||||
return -EAGAIN;
|
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);
|
sch = to_subchannel(cdev->dev.parent);
|
||||||
irb = (struct irb *) __LC_IRB;
|
irb = (struct irb *) __LC_IRB;
|
||||||
/* Retry sense id, if needed. */
|
/* Retry sense id, if needed. */
|
||||||
if (irb->scsw.stctl ==
|
if (irb->scsw.cmd.stctl ==
|
||||||
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
|
(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);
|
ret = __ccw_device_sense_id_start(cdev);
|
||||||
if (ret && ret != -EBUSY)
|
if (ret && ret != -EBUSY)
|
||||||
ccw_device_sense_id_done(cdev, ret);
|
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