]> err.no Git - linux-2.6/commitdiff
[S390] tape: Fix medium state handling
authorMichael Holzheu <holzheu@de.ibm.com>
Fri, 12 Oct 2007 14:11:47 +0000 (16:11 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 12 Oct 2007 14:13:10 +0000 (16:13 +0200)
Currently there are situations, where the tape medium state (loaded, unloaded,
unknown) is not set correctly. The reason is that the medium association
field is used to determine the medium state. This not always leads to
correct results. To fix that we use another field of the medium sense
data instead.

Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/char/tape_3590.c

index 9f244c591eeb320c3533368f84a53595d6c5ae4c..da25f8e24152b7da94a52c79eff4903fabe17eae 100644 (file)
@@ -708,16 +708,22 @@ static void tape_3590_med_state_set(struct tape_device *device,
 
        c_info = &TAPE_3590_CRYPT_INFO(device);
 
-       if (sense->masst == MSENSE_UNASSOCIATED) {
+       DBF_EVENT(6, "medium state: %x:%x\n", sense->macst, sense->masst);
+       switch (sense->macst) {
+       case 0x04:
+       case 0x05:
+       case 0x06:
                tape_med_state_set(device, MS_UNLOADED);
                TAPE_3590_CRYPT_INFO(device).medium_status = 0;
                return;
-       }
-       if (sense->masst != MSENSE_ASSOCIATED_MOUNT) {
-               PRINT_ERR("Unknown medium state: %x\n", sense->masst);
+       case 0x08:
+       case 0x09:
+               tape_med_state_set(device, MS_LOADED);
+               break;
+       default:
+               tape_med_state_set(device, MS_UNKNOWN);
                return;
        }
-       tape_med_state_set(device, MS_LOADED);
        c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
        if (sense->flags & MSENSE_CRYPT_MASK) {
                PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
@@ -835,15 +841,17 @@ tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
                /* Probably result of halt ssch */
                return TAPE_IO_PENDING;
        else if (irb->scsw.dstat == 0x85)
-               /* Device Ready -> check medium state */
-               tape_3590_schedule_work(device, TO_MSEN);
-       else if (irb->scsw.dstat & DEV_STAT_ATTENTION)
+               /* Device Ready */
+               DBF_EVENT(3, "unsol.irq! tape ready: %08x\n", device->cdev_id);
+       else if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
                tape_3590_schedule_work(device, TO_READ_ATTMSG);
-       else {
+       else {
                DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
                PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
                tape_dump_sense(device, NULL, irb);
        }
+       /* check medium state */
+       tape_3590_schedule_work(device, TO_MSEN);
        return TAPE_IO_SUCCESS;
 }