X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fs390%2Fcio%2Fdevice_id.c;h=997f46874537fda00c4d0fc6f05da99fdf889883;hb=572543d8b410c9734b530e811139120e36371ebd;hp=438db483035d033a85013e184fcef818a75dcfd2;hpb=b4bc7b53ccfa0cb793591ba11af49db8f1bc5a4d;p=powerpc.git diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 438db48303..997f468745 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -42,18 +43,15 @@ diag210(struct diag210 * addr) spin_lock_irqsave(&diag210_lock, flags); diag210_tmp = *addr; - asm volatile ( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous" - : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory" ); + asm volatile( + " lhi %0,-1\n" + " sam31\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1: sam64\n" + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); *addr = diag210_tmp; spin_unlock_irqrestore(&diag210_lock, flags); @@ -66,17 +64,14 @@ diag210(struct diag210 * addr) { int ccode; - asm volatile ( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" + asm volatile( + " lhi %0,-1\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" "1:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous" - : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory" ); + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); return ccode; } @@ -144,7 +139,7 @@ VM_virtual_device_info (__u16 devno, struct senseid *ps) ps->cu_model = 0x60; return; } - for (i = 0; i < sizeof(vm_devices) / sizeof(vm_devices[0]); i++) + for (i = 0; i < ARRAY_SIZE(vm_devices); i++) if (diag_data.vrdcvcla == vm_devices[i].vrdcvcla && diag_data.vrdcvtyp == vm_devices[i].vrdcvtyp) { ps->cu_type = vm_devices[i].cu_type; @@ -197,6 +192,8 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) if ((sch->opm & cdev->private->imask) != 0 && cdev->private->iretry > 0) { cdev->private->iretry--; + /* Reset internal retry indication. */ + cdev->private->flags.intretry = 0; ret = cio_start (sch, cdev->private->iccws, cdev->private->imask); /* ret is 0, -EBUSY, -EACCES or -ENODEV */ @@ -243,8 +240,14 @@ ccw_device_check_sense_id(struct ccw_device *cdev) return 0; /* Success */ } /* Check the error cases. */ - if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) + if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { + /* Retry Sense ID if requested. */ + if (cdev->private->flags.intretry) { + cdev->private->flags.intretry = 0; + return -EAGAIN; + } return -ETIME; + } if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) { /* * if the device doesn't support the SenseID @@ -257,7 +260,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) */ CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " "0.%x.%04x reports cmd reject\n", - cdev->private->devno, sch->schid.ssid, + cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no); return -EOPNOTSUPP; } @@ -265,7 +268,8 @@ ccw_device_check_sense_id(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, " "lpum %02X, cnt %02d, sns :" " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", - cdev->private->ssid, cdev->private->devno, + cdev->private->dev_id.ssid, + cdev->private->dev_id.devno, irb->esw.esw0.sublog.lpum, irb->esw.esw0.erw.scnt, irb->ecw[0], irb->ecw[1], @@ -280,14 +284,15 @@ ccw_device_check_sense_id(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " "on subchannel 0.%x.%04x is " "'not operational'\n", sch->orb.lpm, - cdev->private->devno, sch->schid.ssid, - sch->schid.sch_no); + cdev->private->dev_id.devno, + sch->schid.ssid, sch->schid.sch_no); return -EACCES; } /* Hmm, whatever happened, try again. */ CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " "subchannel 0.%x.%04x returns status %02X%02X\n", - cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, + cdev->private->dev_id.devno, sch->schid.ssid, + sch->schid.sch_no, irb->scsw.dstat, irb->scsw.cstat); return -EAGAIN; } @@ -336,7 +341,7 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) /* fall through. */ default: /* Sense ID failed. Try asking VM. */ if (MACHINE_IS_VM) { - VM_virtual_device_info (cdev->private->devno, + VM_virtual_device_info (cdev->private->dev_id.devno, &cdev->private->senseid); if (cdev->private->senseid.cu_type != 0xFFFF) { /* Got the device information from VM. */