mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-18 22:33:39 +00:00
Add support for more linux ioctls.
I've had this sitting in my tree for a long time and I can't seem to find who sent it to me in the first place, apologies to whoever is missing out on a Contributed by: line here. I belive it works as it should.
This commit is contained in:
parent
a67ed623d0
commit
71e9d5f9c8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=130453
|
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/uio.h>
|
||||
#include <net/if.h>
|
||||
|
@ -65,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
|||
static linux_ioctl_function_t linux_ioctl_cdrom;
|
||||
static linux_ioctl_function_t linux_ioctl_vfat;
|
||||
static linux_ioctl_function_t linux_ioctl_console;
|
||||
static linux_ioctl_function_t linux_ioctl_hdio;
|
||||
static linux_ioctl_function_t linux_ioctl_disk;
|
||||
static linux_ioctl_function_t linux_ioctl_socket;
|
||||
static linux_ioctl_function_t linux_ioctl_sound;
|
||||
|
@ -79,6 +81,8 @@ static struct linux_ioctl_handler vfat_handler =
|
|||
{ linux_ioctl_vfat, LINUX_IOCTL_VFAT_MIN, LINUX_IOCTL_VFAT_MAX };
|
||||
static struct linux_ioctl_handler console_handler =
|
||||
{ linux_ioctl_console, LINUX_IOCTL_CONSOLE_MIN, LINUX_IOCTL_CONSOLE_MAX };
|
||||
static struct linux_ioctl_handler hdio_handler =
|
||||
{ linux_ioctl_hdio, LINUX_IOCTL_HDIO_MIN, LINUX_IOCTL_HDIO_MAX };
|
||||
static struct linux_ioctl_handler disk_handler =
|
||||
{ linux_ioctl_disk, LINUX_IOCTL_DISK_MIN, LINUX_IOCTL_DISK_MAX };
|
||||
static struct linux_ioctl_handler socket_handler =
|
||||
|
@ -95,6 +99,7 @@ static struct linux_ioctl_handler drm_handler =
|
|||
DATA_SET(linux_ioctl_handler_set, cdrom_handler);
|
||||
DATA_SET(linux_ioctl_handler_set, vfat_handler);
|
||||
DATA_SET(linux_ioctl_handler_set, console_handler);
|
||||
DATA_SET(linux_ioctl_handler_set, hdio_handler);
|
||||
DATA_SET(linux_ioctl_handler_set, disk_handler);
|
||||
DATA_SET(linux_ioctl_handler_set, socket_handler);
|
||||
DATA_SET(linux_ioctl_handler_set, sound_handler);
|
||||
|
@ -112,6 +117,105 @@ struct handler_element
|
|||
static TAILQ_HEAD(, handler_element) handlers =
|
||||
TAILQ_HEAD_INITIALIZER(handlers);
|
||||
|
||||
/*
|
||||
* hdio related ioctls for VMWare support
|
||||
*/
|
||||
|
||||
struct linux_hd_geometry {
|
||||
u_int8_t heads;
|
||||
u_int8_t sectors;
|
||||
u_int16_t cylinders;
|
||||
u_int32_t start;
|
||||
};
|
||||
|
||||
struct linux_hd_big_geometry {
|
||||
u_int8_t heads;
|
||||
u_int8_t sectors;
|
||||
u_int32_t cylinders;
|
||||
u_int32_t start;
|
||||
};
|
||||
|
||||
static int
|
||||
linux_ioctl_hdio(struct thread *td, struct linux_ioctl_args *args)
|
||||
{
|
||||
struct file *fp;
|
||||
int error;
|
||||
u_int sectorsize, fwcylinders, fwheads, fwsectors;
|
||||
off_t mediasize, bytespercyl;
|
||||
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
switch (args->cmd & 0xffff) {
|
||||
case LINUX_HDIO_GET_GEO:
|
||||
case LINUX_HDIO_GET_GEO_BIG:
|
||||
error = fo_ioctl(fp, DIOCGMEDIASIZE,
|
||||
(caddr_t)&mediasize, td->td_ucred, td);
|
||||
if (!error)
|
||||
error = fo_ioctl(fp, DIOCGSECTORSIZE,
|
||||
(caddr_t)§orsize, td->td_ucred, td);
|
||||
if (!error)
|
||||
error = fo_ioctl(fp, DIOCGFWHEADS,
|
||||
(caddr_t)&fwheads, td->td_ucred, td);
|
||||
if (!error)
|
||||
error = fo_ioctl(fp, DIOCGFWSECTORS,
|
||||
(caddr_t)&fwsectors, td->td_ucred, td);
|
||||
/*
|
||||
* XXX: DIOCGFIRSTOFFSET is not yet implemented, so
|
||||
* so pretend that GEOM always says 0. This is NOT VALID
|
||||
* for slices or partitions, only the per-disk raw devices.
|
||||
*/
|
||||
|
||||
fdrop(fp, td);
|
||||
if (error)
|
||||
return (error);
|
||||
/*
|
||||
* 1. Calculate the number of bytes in a cylinder,
|
||||
* given the firmware's notion of heads and sectors
|
||||
* per cylinder.
|
||||
* 2. Calculate the number of cylinders, given the total
|
||||
* size of the media.
|
||||
* All internal calculations should have 64-bit precision.
|
||||
*/
|
||||
bytespercyl = (off_t) sectorsize * fwheads * fwsectors;
|
||||
fwcylinders = mediasize / bytespercyl;
|
||||
#if defined(DEBUG)
|
||||
linux_msg(td, "HDIO_GET_GEO: mediasize %jd, c/h/s %d/%d/%d, "
|
||||
"bpc %jd",
|
||||
(intmax_t)mediasize, fwcylinders, fwheads, fwsectors,
|
||||
(intmax_t)bytespercyl);
|
||||
#endif
|
||||
if ((args->cmd & 0xffff) == LINUX_HDIO_GET_GEO) {
|
||||
struct linux_hd_geometry hdg;
|
||||
|
||||
hdg.cylinders = fwcylinders;
|
||||
hdg.heads = fwheads;
|
||||
hdg.sectors = fwsectors;
|
||||
hdg.start = 0;
|
||||
error = copyout(&hdg, (void *)args->arg, sizeof(hdg));
|
||||
} else if ((args->cmd & 0xffff) == LINUX_HDIO_GET_GEO_BIG) {
|
||||
struct linux_hd_big_geometry hdbg;
|
||||
|
||||
hdbg.cylinders = fwcylinders;
|
||||
hdbg.heads = fwheads;
|
||||
hdbg.sectors = fwsectors;
|
||||
hdbg.start = 0;
|
||||
error = copyout(&hdbg, (void *)args->arg, sizeof(hdbg));
|
||||
}
|
||||
return (error);
|
||||
break;
|
||||
default:
|
||||
/* XXX */
|
||||
linux_msg(td,
|
||||
"ioctl fd=%d, cmd=0x%x ('%c',%d) is not implemented",
|
||||
args->fd, (int)(args->cmd & 0xffff),
|
||||
(int)(args->cmd & 0xff00) >> 8,
|
||||
(int)(args->cmd & 0xff));
|
||||
break;
|
||||
}
|
||||
fdrop(fp, td);
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
|
||||
static int
|
||||
linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args)
|
||||
{
|
||||
|
@ -138,6 +242,7 @@ linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args)
|
|||
*/
|
||||
return (copyout(§orsize, (void *)args->arg,
|
||||
sizeof(sectorsize)));
|
||||
break;
|
||||
}
|
||||
fdrop(fp, td);
|
||||
return (ENOIOCTL);
|
||||
|
|
|
@ -47,8 +47,18 @@
|
|||
#define LINUX_BLKSECTGET 0x1267
|
||||
#define LINUX_BLKSSZGET 0x1268
|
||||
|
||||
#define LINUX_IOCTL_DISK_MIN LINUX_BLKROSET
|
||||
#define LINUX_IOCTL_DISK_MAX LINUX_BLKSSZGET
|
||||
#define LINUX_IOCTL_DISK_MIN LINUX_BLKROSET
|
||||
#define LINUX_IOCTL_DISK_MAX LINUX_BLKSSZGET
|
||||
|
||||
/*
|
||||
* hdio
|
||||
*/
|
||||
#define LINUX_HDIO_GET_GEO 0x0301
|
||||
#define LINUX_HDIO_GET_IDENTITY 0x030D /* not yet implemented */
|
||||
#define LINUX_HDIO_GET_GEO_BIG 0x0330
|
||||
|
||||
#define LINUX_IOCTL_HDIO_MIN LINUX_HDIO_GET_GEO
|
||||
#define LINUX_IOCTL_HDIO_MAX LINUX_HDIO_GET_GEO_BIG
|
||||
|
||||
/*
|
||||
* cdrom
|
||||
|
|
Loading…
Reference in a new issue