1110 }
1111 if ((rv = bd_check_state(bd, &state)) != 0) {
1112 return (rv);
1113 }
1114 if (ddi_copyout(&state, ptr, sizeof (state), flag)) {
1115 return (EFAULT);
1116 }
1117 return (0);
1118 }
1119 case DKIOCFLUSHWRITECACHE: {
1120 struct dk_callback *dkc = NULL;
1121
1122 if (flag & FKIOCTL)
1123 dkc = (void *)arg;
1124
1125 rv = bd_flush_write_cache(bd, dkc);
1126 return (rv);
1127 }
1128
1129 default:
1130 break;
1131
1132 }
1133 return (ENOTTY);
1134 }
1135
1136 static int
1137 bd_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
1138 char *name, caddr_t valuep, int *lengthp)
1139 {
1140 bd_t *bd;
1141
1142 bd = ddi_get_soft_state(bd_state, ddi_get_instance(dip));
1143 if (bd == NULL)
1144 return (ddi_prop_op(dev, dip, prop_op, mod_flags,
1145 name, valuep, lengthp));
1146
1147 return (cmlb_prop_op(bd->d_cmlbh, dev, dip, prop_op, mod_flags, name,
1148 valuep, lengthp, BDPART(dev), 0));
1149 }
1150
1151
1152 static int
1153 bd_tg_rdwr(dev_info_t *dip, uchar_t cmd, void *bufaddr, diskaddr_t start,
1509
1510 case DDI_CTLOPS_UNINITCHILD:
1511 ddi_set_name_addr((dev_info_t *)arg, NULL);
1512 ndi_prop_remove_all((dev_info_t *)arg);
1513 return (DDI_SUCCESS);
1514
1515 default:
1516 return (ddi_ctlops(dip, rdip, ctlop, arg, result));
1517 }
1518 }
1519
1520 /*
1521 * Functions for device drivers.
1522 */
1523 bd_handle_t
1524 bd_alloc_handle(void *private, bd_ops_t *ops, ddi_dma_attr_t *dma, int kmflag)
1525 {
1526 bd_handle_t hdl;
1527
1528 hdl = kmem_zalloc(sizeof (*hdl), kmflag);
1529 if (hdl != NULL) {
1530 hdl->h_ops = *ops;
1531 hdl->h_dma = dma;
1532 hdl->h_private = private;
1533 }
1534
1535 return (hdl);
1536 }
1537
1538 void
1539 bd_free_handle(bd_handle_t hdl)
1540 {
1541 kmem_free(hdl, sizeof (*hdl));
1542 }
1543
1544 int
1545 bd_attach_handle(dev_info_t *dip, bd_handle_t hdl)
1546 {
1547 dev_info_t *child;
1548 bd_drive_t drive;
1549
1550 /* if drivers don't override this, make it assume none */
1551 drive.d_lun = -1;
1552 hdl->h_ops.o_drive_info(hdl->h_private, &drive);
1553
|
1110 }
1111 if ((rv = bd_check_state(bd, &state)) != 0) {
1112 return (rv);
1113 }
1114 if (ddi_copyout(&state, ptr, sizeof (state), flag)) {
1115 return (EFAULT);
1116 }
1117 return (0);
1118 }
1119 case DKIOCFLUSHWRITECACHE: {
1120 struct dk_callback *dkc = NULL;
1121
1122 if (flag & FKIOCTL)
1123 dkc = (void *)arg;
1124
1125 rv = bd_flush_write_cache(bd, dkc);
1126 return (rv);
1127 }
1128
1129 default:
1130 if (bd->d_ops.o_ioctl != NULL) {
1131 rv = bd->d_ops.o_ioctl(dev, cmd, arg, flag, credp,
1132 rvalp);
1133 } else {
1134 /* Unsupported ioctl ==> return ENOTTY. */
1135 rv = ENOTTY;
1136 }
1137 /* FALLTHRU */
1138 }
1139 return (rv);
1140 }
1141
1142 static int
1143 bd_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
1144 char *name, caddr_t valuep, int *lengthp)
1145 {
1146 bd_t *bd;
1147
1148 bd = ddi_get_soft_state(bd_state, ddi_get_instance(dip));
1149 if (bd == NULL)
1150 return (ddi_prop_op(dev, dip, prop_op, mod_flags,
1151 name, valuep, lengthp));
1152
1153 return (cmlb_prop_op(bd->d_cmlbh, dev, dip, prop_op, mod_flags, name,
1154 valuep, lengthp, BDPART(dev), 0));
1155 }
1156
1157
1158 static int
1159 bd_tg_rdwr(dev_info_t *dip, uchar_t cmd, void *bufaddr, diskaddr_t start,
1515
1516 case DDI_CTLOPS_UNINITCHILD:
1517 ddi_set_name_addr((dev_info_t *)arg, NULL);
1518 ndi_prop_remove_all((dev_info_t *)arg);
1519 return (DDI_SUCCESS);
1520
1521 default:
1522 return (ddi_ctlops(dip, rdip, ctlop, arg, result));
1523 }
1524 }
1525
1526 /*
1527 * Functions for device drivers.
1528 */
1529 bd_handle_t
1530 bd_alloc_handle(void *private, bd_ops_t *ops, ddi_dma_attr_t *dma, int kmflag)
1531 {
1532 bd_handle_t hdl;
1533
1534 hdl = kmem_zalloc(sizeof (*hdl), kmflag);
1535 if (hdl == NULL)
1536 return (NULL);
1537
1538 /*
1539 * Cheesy versioning handling. We've only appended members into
1540 * bd_ops as we grew from v0 to v1. Since we zalloc hdl, the
1541 * ioctl ops will be NULL anyway. So for the old version, we
1542 * copy over only the v0 elements.
1543 */
1544 switch (ops->o_version) {
1545 case BD_OPS_VERSION_0:
1546 /* Don't copy the last pointer in the structure. */
1547 bcopy(ops, &hdl->h_ops, sizeof (*ops) - sizeof (void *));
1548 break;
1549 case BD_OPS_VERSION_1:
1550 hdl->h_ops = *ops;
1551 break;
1552 default:
1553 kmem_free(hdl, sizeof (*hdl));
1554 cmn_err(CE_WARN, "Unsupported blkdev ops version %d.\n",
1555 ops->o_version);
1556 return (NULL);
1557 /* NOTREACHED */
1558 }
1559 hdl->h_dma = dma;
1560 hdl->h_private = private;
1561
1562 return (hdl);
1563 }
1564
1565 void
1566 bd_free_handle(bd_handle_t hdl)
1567 {
1568 kmem_free(hdl, sizeof (*hdl));
1569 }
1570
1571 int
1572 bd_attach_handle(dev_info_t *dip, bd_handle_t hdl)
1573 {
1574 dev_info_t *child;
1575 bd_drive_t drive;
1576
1577 /* if drivers don't override this, make it assume none */
1578 drive.d_lun = -1;
1579 hdl->h_ops.o_drive_info(hdl->h_private, &drive);
1580
|