151 #include <sys/lofi_impl.h> /* for cache structure */
152 #include <sys/fcntl.h>
153 #include <sys/pathname.h>
154 #include <sys/filio.h>
155 #include <sys/fdio.h>
156 #include <sys/open.h>
157 #include <sys/disp.h>
158 #include <vm/seg_map.h>
159 #include <sys/ddi.h>
160 #include <sys/sunddi.h>
161 #include <sys/zmod.h>
162 #include <sys/id_space.h>
163 #include <sys/mkdev.h>
164 #include <sys/crypto/common.h>
165 #include <sys/crypto/api.h>
166 #include <sys/rctl.h>
167 #include <sys/vtoc.h>
168 #include <sys/scsi/scsi.h> /* for DTYPE_DIRECT */
169 #include <sys/scsi/impl/uscsi.h>
170 #include <sys/sysevent/dev.h>
171 #include <LzmaDec.h>
172
173 #define NBLOCKS_PROP_NAME "Nblocks"
174 #define SIZE_PROP_NAME "Size"
175 #define ZONE_PROP_NAME "zone"
176
177 #define SETUP_C_DATA(cd, buf, len) \
178 (cd).cd_format = CRYPTO_DATA_RAW; \
179 (cd).cd_offset = 0; \
180 (cd).cd_miscdata = NULL; \
181 (cd).cd_length = (len); \
182 (cd).cd_raw.iov_base = (buf); \
183 (cd).cd_raw.iov_len = (len);
184
185 #define UIO_CHECK(uio) \
186 if (((uio)->uio_loffset % DEV_BSIZE) != 0 || \
187 ((uio)->uio_resid % DEV_BSIZE) != 0) { \
188 return (EINVAL); \
189 }
190
1724 (offset > (((p_lba + p_nblks) << shift) + lsp->ls_crypto_offset)) ||
1725 ((offset + bp->b_bcount) > ((p_lba + p_nblks) << shift))) {
1726 bioerror(bp, ENXIO);
1727 biodone(bp);
1728 mutex_exit(&lsp->ls_vp_lock);
1729 return (0);
1730 }
1731
1732 mutex_exit(&lsp->ls_vp_lock);
1733
1734 if (lsp->ls_kstat) {
1735 mutex_enter(lsp->ls_kstat->ks_lock);
1736 kstat_waitq_enter(KSTAT_IO_PTR(lsp->ls_kstat));
1737 mutex_exit(lsp->ls_kstat->ks_lock);
1738 }
1739 bp->b_private = (void *)(uintptr_t)p_lba; /* partition start */
1740 (void) taskq_dispatch(lsp->ls_taskq, lofi_strategy_task, bp, KM_SLEEP);
1741 return (0);
1742 }
1743
1744 /*ARGSUSED2*/
1745 static int
1746 lofi_read(dev_t dev, struct uio *uio, struct cred *credp)
1747 {
1748 if (getminor(dev) == 0)
1749 return (EINVAL);
1750 UIO_CHECK(uio);
1751 return (physio(lofi_strategy, NULL, dev, B_READ, minphys, uio));
1752 }
1753
1754 /*ARGSUSED2*/
1755 static int
1756 lofi_write(dev_t dev, struct uio *uio, struct cred *credp)
1757 {
1758 if (getminor(dev) == 0)
1759 return (EINVAL);
1760 UIO_CHECK(uio);
1761 return (physio(lofi_strategy, NULL, dev, B_WRITE, minphys, uio));
1762 }
1763
1764 /*ARGSUSED2*/
1765 static int
1766 lofi_aread(dev_t dev, struct aio_req *aio, struct cred *credp)
1767 {
1768 if (getminor(dev) == 0)
1769 return (EINVAL);
1770 UIO_CHECK(aio->aio_uio);
1771 return (aphysio(lofi_strategy, anocancel, dev, B_READ, minphys, aio));
1772 }
1773
1774 /*ARGSUSED2*/
1775 static int
1776 lofi_awrite(dev_t dev, struct aio_req *aio, struct cred *credp)
1777 {
1778 if (getminor(dev) == 0)
1779 return (EINVAL);
1780 UIO_CHECK(aio->aio_uio);
1781 return (aphysio(lofi_strategy, anocancel, dev, B_WRITE, minphys, aio));
1782 }
1783
3171 }
3172 #endif /* _MULTI_DATAMODEL */
3173 if (ddi_copyin(uscmd->uscsi_cdb, cdb, uscmd->uscsi_cdblen, flag)) {
3174 rval = EFAULT;
3175 goto err;
3176 }
3177 if (cdb->scc_cmd == SCMD_INQUIRY) {
3178 return (0);
3179 }
3180 err:
3181 return (rval);
3182 }
3183
3184 static int
3185 lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
3186 int *rvalp)
3187 {
3188 int error;
3189 enum dkio_state dkstate;
3190 struct lofi_state *lsp;
3191 int id;
3192
3193 id = LOFI_MINOR2ID(getminor(dev));
3194
3195 /* lofi ioctls only apply to the master device */
3196 if (id == 0) {
3197 struct lofi_ioctl *lip = (struct lofi_ioctl *)arg;
3198
3199 /*
3200 * the query command only need read-access - i.e., normal
3201 * users are allowed to do those on the ctl device as
3202 * long as they can open it read-only.
3203 */
3204 switch (cmd) {
3205 case LOFI_MAP_FILE:
3206 if ((flag & FWRITE) == 0)
3207 return (EPERM);
3208 return (lofi_map_file(dev, lip, 1, rvalp, credp, flag));
3209 case LOFI_MAP_FILE_MINOR:
3210 if ((flag & FWRITE) == 0)
3421 uscsi_cmdtouscsi_cmd32((&uscmd), (&ucmd32));
3422 if (ddi_copyout(&ucmd32, (void *)arg, sizeof (ucmd32),
3423 flag) != 0)
3424 return (EFAULT);
3425 break;
3426 }
3427 case DDI_MODEL_NONE:
3428 if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd),
3429 flag) != 0)
3430 return (EFAULT);
3431 break;
3432 default:
3433 return (EFAULT);
3434 }
3435 #else
3436 if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd), flag) != 0)
3437 return (EFAULT);
3438 #endif /* _MULTI_DATAMODEL */
3439 return (0);
3440 }
3441 default:
3442 #ifdef DEBUG
3443 cmn_err(CE_WARN, "lofi_ioctl: %d is not implemented\n", cmd);
3444 #endif /* DEBUG */
3445 return (ENOTTY);
3446 }
3447 }
3448
3449 static int
3450 lofi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
3451 char *name, caddr_t valuep, int *lengthp)
3452 {
3453 struct lofi_state *lsp;
3454 int rc;
3455
3456 lsp = ddi_get_soft_state(lofi_statep, ddi_get_instance(dip));
3457 if (lsp == NULL) {
3458 return (ddi_prop_op(dev, dip, prop_op, mod_flags,
3459 name, valuep, lengthp));
3460 }
|
151 #include <sys/lofi_impl.h> /* for cache structure */
152 #include <sys/fcntl.h>
153 #include <sys/pathname.h>
154 #include <sys/filio.h>
155 #include <sys/fdio.h>
156 #include <sys/open.h>
157 #include <sys/disp.h>
158 #include <vm/seg_map.h>
159 #include <sys/ddi.h>
160 #include <sys/sunddi.h>
161 #include <sys/zmod.h>
162 #include <sys/id_space.h>
163 #include <sys/mkdev.h>
164 #include <sys/crypto/common.h>
165 #include <sys/crypto/api.h>
166 #include <sys/rctl.h>
167 #include <sys/vtoc.h>
168 #include <sys/scsi/scsi.h> /* for DTYPE_DIRECT */
169 #include <sys/scsi/impl/uscsi.h>
170 #include <sys/sysevent/dev.h>
171 #include <sys/efi_partition.h>
172 #include <sys/note.h>
173 #include <LzmaDec.h>
174
175 #define NBLOCKS_PROP_NAME "Nblocks"
176 #define SIZE_PROP_NAME "Size"
177 #define ZONE_PROP_NAME "zone"
178
179 #define SETUP_C_DATA(cd, buf, len) \
180 (cd).cd_format = CRYPTO_DATA_RAW; \
181 (cd).cd_offset = 0; \
182 (cd).cd_miscdata = NULL; \
183 (cd).cd_length = (len); \
184 (cd).cd_raw.iov_base = (buf); \
185 (cd).cd_raw.iov_len = (len);
186
187 #define UIO_CHECK(uio) \
188 if (((uio)->uio_loffset % DEV_BSIZE) != 0 || \
189 ((uio)->uio_resid % DEV_BSIZE) != 0) { \
190 return (EINVAL); \
191 }
192
1726 (offset > (((p_lba + p_nblks) << shift) + lsp->ls_crypto_offset)) ||
1727 ((offset + bp->b_bcount) > ((p_lba + p_nblks) << shift))) {
1728 bioerror(bp, ENXIO);
1729 biodone(bp);
1730 mutex_exit(&lsp->ls_vp_lock);
1731 return (0);
1732 }
1733
1734 mutex_exit(&lsp->ls_vp_lock);
1735
1736 if (lsp->ls_kstat) {
1737 mutex_enter(lsp->ls_kstat->ks_lock);
1738 kstat_waitq_enter(KSTAT_IO_PTR(lsp->ls_kstat));
1739 mutex_exit(lsp->ls_kstat->ks_lock);
1740 }
1741 bp->b_private = (void *)(uintptr_t)p_lba; /* partition start */
1742 (void) taskq_dispatch(lsp->ls_taskq, lofi_strategy_task, bp, KM_SLEEP);
1743 return (0);
1744 }
1745
1746 static int
1747 lofi_read(dev_t dev, struct uio *uio, struct cred *credp)
1748 {
1749 _NOTE(ARGUNUSED(credp));
1750
1751 if (getminor(dev) == 0)
1752 return (EINVAL);
1753 UIO_CHECK(uio);
1754 return (physio(lofi_strategy, NULL, dev, B_READ, minphys, uio));
1755 }
1756
1757 static int
1758 lofi_write(dev_t dev, struct uio *uio, struct cred *credp)
1759 {
1760 _NOTE(ARGUNUSED(credp));
1761
1762 if (getminor(dev) == 0)
1763 return (EINVAL);
1764 UIO_CHECK(uio);
1765 return (physio(lofi_strategy, NULL, dev, B_WRITE, minphys, uio));
1766 }
1767
1768 static int
1769 lofi_urw(struct lofi_state *lsp, uint16_t fmode, diskaddr_t off, size_t size,
1770 intptr_t arg, int flag, cred_t *credp)
1771 {
1772 struct uio uio;
1773 iovec_t iov;
1774
1775 /*
1776 * 1024 * 1024 apes cmlb_tg_max_efi_xfer as a reasonable max.
1777 */
1778 if (size == 0 || size > 1024 * 1024 ||
1779 (size % (1 << lsp->ls_lbshift)) != 0)
1780 return (EINVAL);
1781
1782 iov.iov_base = (void *)arg;
1783 iov.iov_len = size;
1784 uio.uio_iov = &iov;
1785 uio.uio_iovcnt = 1;
1786 uio.uio_loffset = off;
1787 uio.uio_segflg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
1788 uio.uio_llimit = MAXOFFSET_T;
1789 uio.uio_resid = size;
1790 uio.uio_fmode = fmode;
1791 uio.uio_extflg = 0;
1792
1793 return (fmode == FREAD ?
1794 lofi_read(lsp->ls_dev, &uio, credp) :
1795 lofi_write(lsp->ls_dev, &uio, credp));
1796 }
1797
1798 /*ARGSUSED2*/
1799 static int
1800 lofi_aread(dev_t dev, struct aio_req *aio, struct cred *credp)
1801 {
1802 if (getminor(dev) == 0)
1803 return (EINVAL);
1804 UIO_CHECK(aio->aio_uio);
1805 return (aphysio(lofi_strategy, anocancel, dev, B_READ, minphys, aio));
1806 }
1807
1808 /*ARGSUSED2*/
1809 static int
1810 lofi_awrite(dev_t dev, struct aio_req *aio, struct cred *credp)
1811 {
1812 if (getminor(dev) == 0)
1813 return (EINVAL);
1814 UIO_CHECK(aio->aio_uio);
1815 return (aphysio(lofi_strategy, anocancel, dev, B_WRITE, minphys, aio));
1816 }
1817
3205 }
3206 #endif /* _MULTI_DATAMODEL */
3207 if (ddi_copyin(uscmd->uscsi_cdb, cdb, uscmd->uscsi_cdblen, flag)) {
3208 rval = EFAULT;
3209 goto err;
3210 }
3211 if (cdb->scc_cmd == SCMD_INQUIRY) {
3212 return (0);
3213 }
3214 err:
3215 return (rval);
3216 }
3217
3218 static int
3219 lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
3220 int *rvalp)
3221 {
3222 int error;
3223 enum dkio_state dkstate;
3224 struct lofi_state *lsp;
3225 dk_efi_t user_efi;
3226 int id;
3227
3228 id = LOFI_MINOR2ID(getminor(dev));
3229
3230 /* lofi ioctls only apply to the master device */
3231 if (id == 0) {
3232 struct lofi_ioctl *lip = (struct lofi_ioctl *)arg;
3233
3234 /*
3235 * the query command only need read-access - i.e., normal
3236 * users are allowed to do those on the ctl device as
3237 * long as they can open it read-only.
3238 */
3239 switch (cmd) {
3240 case LOFI_MAP_FILE:
3241 if ((flag & FWRITE) == 0)
3242 return (EPERM);
3243 return (lofi_map_file(dev, lip, 1, rvalp, credp, flag));
3244 case LOFI_MAP_FILE_MINOR:
3245 if ((flag & FWRITE) == 0)
3456 uscsi_cmdtouscsi_cmd32((&uscmd), (&ucmd32));
3457 if (ddi_copyout(&ucmd32, (void *)arg, sizeof (ucmd32),
3458 flag) != 0)
3459 return (EFAULT);
3460 break;
3461 }
3462 case DDI_MODEL_NONE:
3463 if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd),
3464 flag) != 0)
3465 return (EFAULT);
3466 break;
3467 default:
3468 return (EFAULT);
3469 }
3470 #else
3471 if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd), flag) != 0)
3472 return (EFAULT);
3473 #endif /* _MULTI_DATAMODEL */
3474 return (0);
3475 }
3476
3477 case DKIOCGMBOOT:
3478 return (lofi_urw(lsp, FREAD, 0, 1 << lsp->ls_lbshift,
3479 arg, flag, credp));
3480
3481 case DKIOCSMBOOT:
3482 return (lofi_urw(lsp, FWRITE, 0, 1 << lsp->ls_lbshift,
3483 arg, flag, credp));
3484
3485 case DKIOCGETEFI:
3486 if (ddi_copyin((void *)arg, &user_efi,
3487 sizeof (dk_efi_t), flag) != 0)
3488 return (EFAULT);
3489
3490 return (lofi_urw(lsp, FREAD,
3491 user_efi.dki_lba * (1 << lsp->ls_lbshift),
3492 user_efi.dki_length, (intptr_t)user_efi.dki_data,
3493 flag, credp));
3494
3495 case DKIOCSETEFI:
3496 if (ddi_copyin((void *)arg, &user_efi,
3497 sizeof (dk_efi_t), flag) != 0)
3498 return (EFAULT);
3499
3500 return (lofi_urw(lsp, FWRITE,
3501 user_efi.dki_lba * (1 << lsp->ls_lbshift),
3502 user_efi.dki_length, (intptr_t)user_efi.dki_data,
3503 flag, credp));
3504
3505 default:
3506 #ifdef DEBUG
3507 cmn_err(CE_WARN, "lofi_ioctl: %d is not implemented\n", cmd);
3508 #endif /* DEBUG */
3509 return (ENOTTY);
3510 }
3511 }
3512
3513 static int
3514 lofi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
3515 char *name, caddr_t valuep, int *lengthp)
3516 {
3517 struct lofi_state *lsp;
3518 int rc;
3519
3520 lsp = ddi_get_soft_state(lofi_statep, ddi_get_instance(dip));
3521 if (lsp == NULL) {
3522 return (ddi_prop_op(dev, dip, prop_op, mod_flags,
3523 name, valuep, lengthp));
3524 }
|