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);