Print this page
10567 lofi should support basic EFI ioctl()s


 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         }