Print this page
*** NO COMMENTS ***

@@ -1125,14 +1125,20 @@
                 rv = bd_flush_write_cache(bd, dkc);
                 return (rv);
         }
 
         default:
-                break;
-
+                if (bd->d_ops.o_ioctl != NULL) {
+                        rv = bd->d_ops.o_ioctl(dev, cmd, arg, flag, credp,
+                            rvalp);
+                } else {
+                        /* Unsupported ioctl ==> return ENOTTY. */
+                        rv = ENOTTY;
         }
-        return (ENOTTY);
+                /* FALLTHRU */
+        }
+        return (rv);
 }
 
 static int
 bd_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
     char *name, caddr_t valuep, int *lengthp)

@@ -1524,15 +1530,36 @@
 bd_alloc_handle(void *private, bd_ops_t *ops, ddi_dma_attr_t *dma, int kmflag)
 {
         bd_handle_t     hdl;
 
         hdl = kmem_zalloc(sizeof (*hdl), kmflag);
-        if (hdl != NULL) {
+        if (hdl == NULL)
+                return (NULL);
+
+        /*
+         * Cheesy versioning handling.  We've only appended members into
+         * bd_ops as we grew from v0 to v1.  Since we zalloc hdl, the
+         * ioctl ops will be NULL anyway.  So for the old version, we
+         * copy over only the v0 elements.
+         */
+        switch (ops->o_version) {
+        case BD_OPS_VERSION_0:
+                /* Don't copy the last pointer in the structure. */
+                bcopy(ops, &hdl->h_ops, sizeof (*ops) - sizeof (void *));
+                break;
+        case BD_OPS_VERSION_1:
                 hdl->h_ops = *ops;
+                break;
+        default:
+                kmem_free(hdl, sizeof (*hdl));
+                cmn_err(CE_WARN, "Unsupported blkdev ops version %d.\n",
+                    ops->o_version);
+                return (NULL);
+                /* NOTREACHED */
+        }
                 hdl->h_dma = dma;
                 hdl->h_private = private;
-        }
 
         return (hdl);
 }
 
 void