}
 
        fp->private_data = dd;
-       ipath_diag_inuse = 1;
+       ipath_diag_inuse = -2;
        diag_set_link = 0;
        ret = 0;
 
        else if ((count % 4) || (*off % 4))
                /* address or length is not 32-bit aligned, hence invalid */
                ret = -EINVAL;
+       else if (ipath_diag_inuse < 1 && (*off || count != 8))
+               ret = -EINVAL;  /* prevent cat /dev/ipath_diag* */
        else if ((count % 8) || (*off % 8))
                /* address or length not 64-bit aligned; do 32-bit reads */
                ret = ipath_read_umem32(dd, data, kreg_base + *off, count);
        if (ret >= 0) {
                *off += count;
                ret = count;
+               if (ipath_diag_inuse == -2)
+                       ipath_diag_inuse++;
        }
 
        return ret;
        else if ((count % 4) || (*off % 4))
                /* address or length is not 32-bit aligned, hence invalid */
                ret = -EINVAL;
+       else if ((ipath_diag_inuse == -1 && (*off || count != 8)) ||
+                ipath_diag_inuse == -2)  /* read qw off 0, write qw off 0 */
+               ret = -EINVAL;  /* before any other write allowed */
        else if ((count % 8) || (*off % 8))
                /* address or length not 64-bit aligned; do 32-bit writes */
                ret = ipath_write_umem32(dd, kreg_base + *off, data, count);
        if (ret >= 0) {
                *off += count;
                ret = count;
+               if (ipath_diag_inuse == -1)
+                       ipath_diag_inuse = 1; /* all read/write OK now */
        }
 
        return ret;