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

*** 166,175 **** --- 166,177 ---- #include <sys/rctl.h> #include <sys/vtoc.h> #include <sys/scsi/scsi.h> /* for DTYPE_DIRECT */ #include <sys/scsi/impl/uscsi.h> #include <sys/sysevent/dev.h> + #include <sys/efi_partition.h> + #include <sys/note.h> #include <LzmaDec.h> #define NBLOCKS_PROP_NAME "Nblocks" #define SIZE_PROP_NAME "Size" #define ZONE_PROP_NAME "zone"
*** 1739,1768 **** bp->b_private = (void *)(uintptr_t)p_lba; /* partition start */ (void) taskq_dispatch(lsp->ls_taskq, lofi_strategy_task, bp, KM_SLEEP); return (0); } - /*ARGSUSED2*/ static int lofi_read(dev_t dev, struct uio *uio, struct cred *credp) { if (getminor(dev) == 0) return (EINVAL); UIO_CHECK(uio); return (physio(lofi_strategy, NULL, dev, B_READ, minphys, uio)); } - /*ARGSUSED2*/ static int lofi_write(dev_t dev, struct uio *uio, struct cred *credp) { if (getminor(dev) == 0) return (EINVAL); UIO_CHECK(uio); return (physio(lofi_strategy, NULL, dev, B_WRITE, minphys, uio)); } /*ARGSUSED2*/ static int lofi_aread(dev_t dev, struct aio_req *aio, struct cred *credp) { if (getminor(dev) == 0) --- 1741,1802 ---- bp->b_private = (void *)(uintptr_t)p_lba; /* partition start */ (void) taskq_dispatch(lsp->ls_taskq, lofi_strategy_task, bp, KM_SLEEP); return (0); } static int lofi_read(dev_t dev, struct uio *uio, struct cred *credp) { + _NOTE(ARGUNUSED(credp)); + if (getminor(dev) == 0) return (EINVAL); UIO_CHECK(uio); return (physio(lofi_strategy, NULL, dev, B_READ, minphys, uio)); } static int lofi_write(dev_t dev, struct uio *uio, struct cred *credp) { + _NOTE(ARGUNUSED(credp)); + if (getminor(dev) == 0) return (EINVAL); UIO_CHECK(uio); return (physio(lofi_strategy, NULL, dev, B_WRITE, minphys, uio)); } + static int + lofi_urw(struct lofi_state *lsp, uint16_t fmode, diskaddr_t off, size_t size, + intptr_t arg, int flag, cred_t *credp) + { + struct uio uio; + iovec_t iov; + + /* + * 1024 * 1024 apes cmlb_tg_max_efi_xfer as a reasonable max. + */ + if (size == 0 || size > 1024 * 1024 || + (size % (1 << lsp->ls_lbshift)) != 0) + return (EINVAL); + + iov.iov_base = (void *)arg; + iov.iov_len = size; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_loffset = off; + uio.uio_segflg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE; + uio.uio_llimit = MAXOFFSET_T; + uio.uio_resid = size; + uio.uio_fmode = fmode; + uio.uio_extflg = 0; + + return (fmode == FREAD ? + lofi_read(lsp->ls_dev, &uio, credp) : + lofi_write(lsp->ls_dev, &uio, credp)); + } + /*ARGSUSED2*/ static int lofi_aread(dev_t dev, struct aio_req *aio, struct cred *credp) { if (getminor(dev) == 0)
*** 3186,3195 **** --- 3220,3230 ---- int *rvalp) { int error; enum dkio_state dkstate; struct lofi_state *lsp; + dk_efi_t user_efi; int id; id = LOFI_MINOR2ID(getminor(dev)); /* lofi ioctls only apply to the master device */
*** 3436,3445 **** --- 3471,3509 ---- if (ddi_copyout(&uscmd, (void *)arg, sizeof (uscmd), flag) != 0) return (EFAULT); #endif /* _MULTI_DATAMODEL */ return (0); } + + case DKIOCGMBOOT: + return (lofi_urw(lsp, FREAD, 0, 1 << lsp->ls_lbshift, + arg, flag, credp)); + + case DKIOCSMBOOT: + return (lofi_urw(lsp, FWRITE, 0, 1 << lsp->ls_lbshift, + arg, flag, credp)); + + case DKIOCGETEFI: + if (ddi_copyin((void *)arg, &user_efi, + sizeof (dk_efi_t), flag) != 0) + return (EFAULT); + + return (lofi_urw(lsp, FREAD, + user_efi.dki_lba * (1 << lsp->ls_lbshift), + user_efi.dki_length, (intptr_t)user_efi.dki_data, + flag, credp)); + + case DKIOCSETEFI: + if (ddi_copyin((void *)arg, &user_efi, + sizeof (dk_efi_t), flag) != 0) + return (EFAULT); + + return (lofi_urw(lsp, FWRITE, + user_efi.dki_lba * (1 << lsp->ls_lbshift), + user_efi.dki_length, (intptr_t)user_efi.dki_data, + flag, credp)); + default: #ifdef DEBUG cmn_err(CE_WARN, "lofi_ioctl: %d is not implemented\n", cmd); #endif /* DEBUG */ return (ENOTTY);