diff options
author | scottl <scottl@FreeBSD.org> | 2007-04-07 19:40:58 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-04-07 19:40:58 +0000 |
commit | 1320f9f144d11efc5e2e12e3ab69a5a4559b06fe (patch) | |
tree | f3bff966194b6ef5bf3c76fcbd41adc4ff98caa6 /sys/compat | |
parent | 9a4581bab30ccb9819a6020d5156ef862a0613f1 (diff) | |
download | FreeBSD-src-1320f9f144d11efc5e2e12e3ab69a5a4559b06fe.zip FreeBSD-src-1320f9f144d11efc5e2e12e3ab69a5a4559b06fe.tar.gz |
Add the CAM 'SG' peripheral device. This device implements a subset of the
Linux SCSI SG passthrough device API. The intention is to allow for both
running of Linux apps that want to talk to /dev/sg* nodes, and to facilitate
porting of apps from Linux to FreeBSD. As such, both native and linuxolator
entry points and definitions are provided.
Caveats:
- This does not support the procfs and sysfs nodes that the Linux SG
driver provides. Some Linux apps may rely on these for operation,
others may only use them for informational purposes.
- More ioctls need to be implemented.
- Linux uses a naming scheme of "sg[a-z]" for devices, while FreeBSD uses a
scheme of "sg[0-9]". Devfs aliasis (symlinks) are automatically created
to link the two together. However, tools like camcontrol only see the
native names.
- Some operations were originally designed to return byte counts or other
data directly as the syscall return value. The linuxolator doesn't appear
to support this well, so this driver just punts for these cases.
Now that the driver is in place, others are welcome to add missing
functionality. Thanks to Roman Divacky for pushing this work along.
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 27 | ||||
-rw-r--r-- | sys/compat/linux/linux_ioctl.h | 34 |
2 files changed, 61 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 09e1cc0..9583551 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -86,6 +86,7 @@ static linux_ioctl_function_t linux_ioctl_sound; static linux_ioctl_function_t linux_ioctl_termio; static linux_ioctl_function_t linux_ioctl_private; static linux_ioctl_function_t linux_ioctl_drm; +static linux_ioctl_function_t linux_ioctl_sg; static linux_ioctl_function_t linux_ioctl_special; static struct linux_ioctl_handler cdrom_handler = @@ -108,6 +109,8 @@ static struct linux_ioctl_handler private_handler = { linux_ioctl_private, LINUX_IOCTL_PRIVATE_MIN, LINUX_IOCTL_PRIVATE_MAX }; static struct linux_ioctl_handler drm_handler = { linux_ioctl_drm, LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX }; +static struct linux_ioctl_handler sg_handler = +{ linux_ioctl_sg, LINUX_IOCTL_SG_MIN, LINUX_IOCTL_SG_MAX }; DATA_SET(linux_ioctl_handler_set, cdrom_handler); DATA_SET(linux_ioctl_handler_set, vfat_handler); @@ -119,6 +122,7 @@ DATA_SET(linux_ioctl_handler_set, sound_handler); DATA_SET(linux_ioctl_handler_set, termio_handler); DATA_SET(linux_ioctl_handler_set, private_handler); DATA_SET(linux_ioctl_handler_set, drm_handler); +DATA_SET(linux_ioctl_handler_set, sg_handler); struct handler_element { @@ -1583,6 +1587,11 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args) break; } + case LINUX_SCSI_GET_BUS_NUMBER: + case LINUX_SCSI_GET_IDLUN: + error = linux_ioctl_sg(td, args); + break; + /* LINUX_CDROM_SEND_PACKET */ /* LINUX_CDROM_NEXT_WRITABLE */ /* LINUX_CDROM_LAST_WRITTEN */ @@ -2522,6 +2531,24 @@ linux_ioctl_drm(struct thread *td, struct linux_ioctl_args *args) return ioctl(td, (struct ioctl_args *)args); } +static int +linux_ioctl_sg(struct thread *td, struct linux_ioctl_args *args) +{ + struct file *fp; + u_long cmd; + int error; + + if ((error = fget(td, args->fd, &fp)) != 0) { + printf("sg_linux_ioctl: fget returned %d\n", error); + return (error); + } + cmd = args->cmd; + + error = (fo_ioctl(fp, cmd, (caddr_t)args->arg, td->td_ucred, td)); + fdrop(fp, td); + return (error); +} + /* * Special ioctl handler */ diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h index 17e5b164..4fc69b2 100644 --- a/sys/compat/linux/linux_ioctl.h +++ b/sys/compat/linux/linux_ioctl.h @@ -103,6 +103,8 @@ #define LINUX_CDROM_DEBUG 0x5330 #define LINUX_CDROM_GET_CAPABILITY 0x5331 #define LINUX_CDROMAUDIOBUFSIZ 0x5382 +#define LINUX_SCSI_GET_IDLUN 0x5382 +#define LINUX_SCSI_GET_BUS_NUMBER 0x5386 #define LINUX_DVD_READ_STRUCT 0x5390 #define LINUX_DVD_WRITE_STRUCT 0x5391 #define LINUX_DVD_AUTH 0x5392 @@ -130,6 +132,38 @@ #define LINUX_DVD_HOST_SEND_RPC_STATE 11 /* + * SG + */ +#define LINUX_SG_SET_TIMEOUT 0x2201 +#define LINUX_SG_GET_TIMEOUT 0x2202 +#define LINUX_SG_EMULATED_HOST 0x2203 +#define LINUX_SG_SET_TRANSFORM 0x2204 +#define LINUX_SG_GET_TRANSFORM 0x2205 +#define LINUX_SG_GET_COMMAND_Q 0x2270 +#define LINUX_SG_SET_COMMAND_Q 0x2271 +#define LINUX_SG_SET_RESERVED_SIZE 0x2275 +#define LINUX_SG_GET_RESERVED_SIZE 0x2272 +#define LINUX_SG_GET_SCSI_ID 0x2276 +#define LINUX_SG_SET_FORCE_LOW_DMA 0x2279 +#define LINUX_SG_GET_LOW_DMA 0x227a +#define LINUX_SG_SET_FORCE_PACK_ID 0x227b +#define LINUX_SG_GET_PACK_ID 0x227c +#define LINUX_SG_GET_NUM_WAITING 0x227d +#define LINUX_SG_SET_DEBUG 0x227e +#define LINUX_SG_GET_SG_TABLESIZE 0x227f +#define LINUX_SG_GET_VERSION_NUM 0x2282 +#define LINUX_SG_NEXT_CMD_LEN 0x2283 +#define LINUX_SG_SCSI_RESET 0x2284 +#define LINUX_SG_IO 0x2285 +#define LINUX_SG_GET_REQUEST_TABLE 0x2286 +#define LINUX_SG_SET_KEEP_ORPHAN 0x2287 +#define LINUX_SG_GET_KEEP_ORPHAN 0x2288 +#define LINUX_SG_GET_ACCESS_COUNT 0x2289 + +#define LINUX_IOCTL_SG_MIN 0x2200 +#define LINUX_IOCTL_SG_MAX 0x22ff + +/* * VFAT */ #define LINUX_VFAT_READDIR_BOTH 0x7201 |