Turn PCI into a character driver

Change-Id: Ia9c83af4d52e82e845b6a847c3e82e33d1920ae0
This commit is contained in:
Lionel Sambuc 2014-10-16 21:19:24 +02:00
parent 3641562f44
commit 5d8311761a
18 changed files with 455 additions and 223 deletions

View file

@ -1810,7 +1810,7 @@
./usr/include/sys/verified_exec.h minix-sys
./usr/include/sys/video.h minix-sys
./usr/include/sys/videoio.h minix-sys
./usr/include/sys/vm.h minix-sys
./usr/include/sys/vm.h minix-sys obsolete
./usr/include/sys/vmmeter.h minix-sys
./usr/include/sys/vnode.h minix-sys
./usr/include/sys/vnode_if.h minix-sys

View file

@ -26,6 +26,7 @@ RAMDISK_DEVICES="
c1d4 c1d4p0 c1d4p0s0 c1d5 c1d5p0 c1d5p0s0
c1d6 c1d6p0 c1d6p0s0 c1d7 c1d7p0 c1d7p0s0
fd0 fd1 fd0p0 fd1p0
pci
ttyc1 ttyc2 ttyc3 tty00 tty01 tty02 tty03
ttyp0 ttyp1 ttyp2 ttyp3 ttyp4 ttyp5 ttyp6 ttyp7 ttyp8 ttyp9
ttypa ttypb ttypc ttypd ttype ttypf
@ -137,6 +138,7 @@ Where key is one of the following:
fbd # Make /dev/fbd
hello # Make /dev/hello
video # Make /dev/video
pci # Make /dev/pci
vnd0 vnd0p0 vnd0p0s0 .. # Make vnode disks /dev/vnd[0-7] and (sub)partitions
input # Make /dev/kbdmux, /dev/kbd[0-3], idem /dev/mouse~
EOF
@ -363,6 +365,10 @@ do
minor=`expr ${minor} + 4`
done
;;
pci)
# PCI server, manages PCI buses
makedev pci c 134 0 ${uname} ${gname} ${permissions}
;;
ram|mem|kmem|null|boot|zero|imgrd)
# Memory devices.
makedev ram b 1 0 ${uname} kmem ${permissions}

View file

@ -9,9 +9,9 @@ SRCS= main.c pci.c pci_table.c
SRCS+= pci_verbose.c pci_subr.c
CPPFLAGS.pci_subr.c+= -D_PCI_SERVER
DPADD+= ${LIBSYS} ${LIBTIMERS}
LDADD+= -lsys -ltimers
DPADD+= ${LIBCHARDRIVER}
LDADD+= -lchardriver
WARNS?= 3
WARNS= 3
.include <minix.service.mk>

View file

@ -1,3 +1,8 @@
#include <sys/types.h>
#include <dev/pci/pciio.h>
#include <minix/chardriver.h>
#include <minix/driver.h>
#include <minix/rs.h>
@ -6,22 +11,9 @@
int debug = 0;
struct pci_acl pci_acl[NR_DRIVERS];
static void
sef_local_startup()
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_lu(sef_cb_init_fresh);
sef_setcb_init_restart(sef_cb_init_fresh);
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
/* Let SEF perform startup. */
sef_startup();
}
/*======================================================================*
* Helpers *
*======================================================================*/
static struct rs_pci *
find_acl(int endpoint)
{
@ -50,7 +42,6 @@ reply(message *mp, int result)
printf("reply: unable to send to %d: %d\n", mp->m_source, r);
}
static void
do_init(message *mp)
{
@ -527,58 +518,239 @@ do_rescan_bus(message *mp)
}
}
/*======================================================================*
* CharDriver Callbacks *
*======================================================================*/
static int
pci_open(devminor_t UNUSED(minor), int UNUSED(access),
endpoint_t UNUSED(user_endpt))
{
return OK;
}
static int
pci_close(devminor_t UNUSED(minor))
{
return OK;
}
static int
pci_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id)
{
int devind;
int r = ENOTTY;
switch(request)
{
case PCI_IOC_BDF_CFGREAD:
{
struct pciio_bdf_cfgreg bdf;
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&bdf,
sizeof(bdf))) != OK)
break;
r = _pci_find_dev(bdf.bus, bdf.device, bdf.function, &devind);
if (r != 1) {
r = EINVAL;
break;
}
if ((r = _pci_attr_r32(devind, bdf.cfgreg.reg,
&bdf.cfgreg.val)) != OK)
break;
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)&bdf,
sizeof(bdf));
break;
}
case PCI_IOC_BDF_CFGWRITE:
{
struct pciio_bdf_cfgreg bdf;
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&bdf,
sizeof(bdf))) != OK)
break;
r = _pci_find_dev(bdf.bus, bdf.device, bdf.function, &devind);
if (r != 1) {
r = EINVAL;
break;
}
_pci_attr_w32(devind, bdf.cfgreg.reg, bdf.cfgreg.val);
r = OK;
break;
}
case PCI_IOC_BUSINFO:
break;
case PCI_IOC_MAP:
{
struct pciio_map map;
struct minix_mem_range mr;
if ((r = sys_safecopyfrom(endpt, grant, 0,
(vir_bytes)&map, sizeof(map))) != OK)
break;
#if 1
mr.mr_base = map.phys_offset;
mr.mr_limit = map.phys_offset + map.size - 1;
r = sys_privctl(user_endpt, SYS_PRIV_ADD_MEM, &mr);
if (r != OK)
{
break;
}
#endif
map.vaddr_ret = vm_map_phys(user_endpt,
(void *)map.phys_offset, map.size);
r = sys_safecopyto(endpt, grant, 0, (vir_bytes)&map,
sizeof(map));
break;
}
case PCI_IOC_UNMAP:
{
struct pciio_map map;
if ((r = sys_safecopyfrom(endpt, grant, 0,
(vir_bytes)&map, sizeof(map))) != OK)
break;
r = vm_unmap_phys(user_endpt, map.vaddr, map.size);
break;
}
case PCI_IOC_RESERVE:
{
struct pciio_acl acl;
if ((r = sys_safecopyfrom(endpt, grant, 0,
(vir_bytes)&acl, sizeof(acl))) != OK)
break;
r = _pci_find_dev(acl.bus, acl.device, acl.function, &devind);
if (r != 1) {
r = EINVAL;
break;
}
r = _pci_grant_access(devind, user_endpt);
break;
}
case PCI_IOC_RELEASE:
{
struct pciio_acl acl;
if ((r = sys_safecopyfrom(endpt, grant, 0,
(vir_bytes)&acl, sizeof(acl))) != OK)
break;
r = _pci_find_dev(acl.bus, acl.device, acl.function, &devind);
if (r != 1) {
r = EINVAL;
break;
}
_pci_release(endpt);
r = OK;
break;
}
case PCI_IOC_CFGREAD:
case PCI_IOC_CFGWRITE:
default:
r = ENOTTY;
}
return r;
}
static void
pci_other(message *m, int ipc_status)
{
switch(m->m_type)
{
case BUSC_PCI_INIT: do_init(m); break;
case BUSC_PCI_FIRST_DEV: do_first_dev(m); break;
case BUSC_PCI_NEXT_DEV: do_next_dev(m); break;
case BUSC_PCI_FIND_DEV: do_find_dev(m); break;
case BUSC_PCI_IDS: do_ids(m); break;
case BUSC_PCI_RESERVE: do_reserve(m); break;
case BUSC_PCI_ATTR_R8: do_attr_r8(m); break;
case BUSC_PCI_ATTR_R16: do_attr_r16(m); break;
case BUSC_PCI_ATTR_R32: do_attr_r32(m); break;
case BUSC_PCI_ATTR_W8: do_attr_w8(m); break;
case BUSC_PCI_ATTR_W16: do_attr_w16(m); break;
case BUSC_PCI_ATTR_W32: do_attr_w32(m); break;
case BUSC_PCI_RESCAN: do_rescan_bus(m); break;
case BUSC_PCI_DEV_NAME_S: do_dev_name(m); break;
case BUSC_PCI_SLOT_NAME_S: do_slot_name(m); break;
case BUSC_PCI_SET_ACL: do_set_acl(m); break;
case BUSC_PCI_DEL_ACL: do_del_acl(m); break;
case BUSC_PCI_GET_BAR: do_get_bar(m); break;
default:
printf("PCI: unhandled message from %d, type %d\n",
m->m_source, m->m_type);
break;
}
}
static struct chardriver driver =
{
.cdr_open = pci_open,
.cdr_close = pci_close,
.cdr_ioctl = pci_ioctl,
.cdr_other = pci_other,
};
/*======================================================================*
* SEF Callbacks *
*======================================================================*/
/* NOTE: sef_cb_init is in pci.c. */
static void
sef_local_startup(void)
{
/*
* Register init callbacks. Use the same function for all event types
*/
sef_setcb_init_fresh(sef_cb_init);
sef_setcb_init_lu(sef_cb_init);
sef_setcb_init_restart(sef_cb_init);
/*
* Register live update callbacks.
*/
/* - Agree to update immediately when LU is requested in a valid
* state. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
/* - Support live update starting from any standard state. */
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
#if 0
/* - Register a custom routine to save the state. */
sef_setcb_lu_state_save(sef_cb_lu_state_save);
#endif
/* Let SEF perform startup. */
sef_startup();
}
/*======================================================================*
* main *
*======================================================================*/
int
main(void)
{
int r;
message m;
int ipc_status;
/* SEF local startup. */
/*
* Perform initialization.
*/
sef_local_startup();
for(;;)
{
r= driver_receive(ANY, &m, &ipc_status);
if (r < 0)
{
printf("PCI: driver_receive failed: %d\n", r);
break;
}
if (is_ipc_notify(ipc_status)) {
printf("PCI: got notify from %d\n", m.m_source);
/* done, get a new message */
continue;
}
switch(m.m_type)
{
case BUSC_PCI_INIT: do_init(&m); break;
case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
case BUSC_PCI_IDS: do_ids(&m); break;
case BUSC_PCI_RESERVE: do_reserve(&m); break;
case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
case BUSC_PCI_DEV_NAME_S: do_dev_name(&m); break;
case BUSC_PCI_SLOT_NAME_S: do_slot_name(&m); break;
case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
case BUSC_PCI_GET_BAR: do_get_bar(&m); break;
default:
printf("PCI: got message from %d, type %d\n",
m.m_source, m.m_type);
break;
}
}
return 0;
/*
* Run the main loop.
*/
chardriver_task(&driver);
return OK;
}

View file

@ -5,12 +5,11 @@ Configure devices on the PCI bus
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
*/
#include <minix/driver.h>
#include <minix/acpi.h>
#include <minix/param.h>
#include <minix/chardriver.h>
#include <minix/driver.h>
#include <minix/ds.h>
#include <minix/param.h>
#include <minix/rs.h>
#include <machine/pci.h>
@ -2127,9 +2126,11 @@ visible(struct rs_pci *aclp, int devind)
* sef_cb_init_fresh *
*===========================================================================*/
int
sef_cb_init_fresh(int type, sef_init_info_t *info)
sef_cb_init(int type, sef_init_info_t *info)
{
/* Initialize the pci driver. */
/* Initialize the driver. */
int do_announce_driver = -1;
long v;
int i, r;
struct rprocpub rprocpub[NR_BOOT_PROCS];
@ -2153,19 +2154,38 @@ sef_cb_init_fresh(int type, sef_init_info_t *info)
pci_intel_init();
/* Map all the services in the boot image. */
if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
if ((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
(vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
panic("sys_safecopyfrom failed: %d", r);
}
for(i=0;i < NR_BOOT_PROCS;i++) {
if(rprocpub[i].in_use) {
if((r = map_service(&rprocpub[i])) != OK) {
if (rprocpub[i].in_use) {
if ((r = map_service(&rprocpub[i])) != OK) {
panic("unable to map service: %d", r);
}
}
}
return(OK);
switch(type) {
case SEF_INIT_FRESH:
case SEF_INIT_RESTART:
do_announce_driver = TRUE;
break;
case SEF_INIT_LU:
do_announce_driver = FALSE;
break;
default:
panic("Unknown type of restart");
break;
}
/* Announce we are up when necessary. */
if (TRUE == do_announce_driver) {
chardriver_announce();
}
/* Initialization completed successfully. */
return OK;
}
/*===========================================================================*
@ -2199,7 +2219,7 @@ map_service(struct rprocpub *rpub)
pci_acl[i].inuse = 1;
pci_acl[i].acl = rpub->pci_acl;
return(OK);
return OK;
}
/*===========================================================================*
@ -2219,13 +2239,12 @@ _pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
break;
}
}
if (devind >= nr_pcidev)
return 0;
#if 0
if (pcidev[devind].pd_inuse)
return 0;
#endif
*devindp= devind;
return 1;
}
@ -2240,10 +2259,6 @@ _pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp,
for (devind= 0; devind < nr_pcidev; devind++)
{
#if 0
if (pcidev[devind].pd_inuse)
continue;
#endif
if (!visible(aclp, devind))
continue;
break;
@ -2266,10 +2281,6 @@ _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
for (devind= *devindp+1; devind < nr_pcidev; devind++)
{
#if 0
if (pcidev[devind].pd_inuse)
continue;
#endif
if (!visible(aclp, devind))
continue;
break;
@ -2283,33 +2294,16 @@ _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
}
/*===========================================================================*
* _pci_reserve *
* _pci_grant_access *
*===========================================================================*/
int
_pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
_pci_grant_access(int devind, endpoint_t proc)
{
int i, r;
int ilr;
int i, ilr;
int r = OK;
struct io_range ior;
struct minix_mem_range mr;
if (devind < 0 || devind >= nr_pcidev)
{
printf("pci_reserve_a: bad devind: %d\n", devind);
return EINVAL;
}
if (!visible(aclp, devind))
{
printf("pci_reserve_a: %u is not allowed to reserve %d\n",
proc, devind);
return EPERM;
}
if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
return EBUSY;
pcidev[devind].pd_inuse= 1;
pcidev[devind].pd_proc= proc;
for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
{
if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
@ -2361,7 +2355,34 @@ _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
}
}
return OK;
return r;
}
/*===========================================================================*
* _pci_reserve *
*===========================================================================*/
int
_pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
{
if (devind < 0 || devind >= nr_pcidev)
{
printf("pci_reserve_a: bad devind: %d\n", devind);
return EINVAL;
}
if (!visible(aclp, devind))
{
printf("pci_reserve_a: %u is not allowed to reserve %d\n",
proc, devind);
return EPERM;
}
if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
return EBUSY;
pcidev[devind].pd_inuse= 1;
pcidev[devind].pd_proc= proc;
return _pci_grant_access(devind, proc);
}
/*===========================================================================*

View file

@ -4,12 +4,6 @@ pci.h
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
*/
struct pci_intel_ctrl
{
u16_t vid;
u16_t did;
};
struct pci_isabridge
{
u16_t vid;
@ -18,13 +12,6 @@ struct pci_isabridge
int type;
};
struct pci_pcibridge
{
u16_t vid;
u16_t did;
int type;
};
struct pci_acl
{
int inuse;
@ -49,9 +36,10 @@ extern struct pci_isabridge pci_isabridge[];
extern struct pci_acl pci_acl[NR_DRIVERS];
/* Function prototypes. */
int sef_cb_init_fresh(int type, sef_init_info_t *info);
int sef_cb_init(int type, sef_init_info_t *info);
int map_service(struct rprocpub *rpub);
int _pci_grant_access(int devind, endpoint_t proc);
int _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp);
void _pci_release(endpoint_t proc);

View file

@ -13,7 +13,7 @@ then if [ -e $ACPI -a -n "`sysenv acpi`" ]
then
/bin/service -c up $ACPI
fi
/bin/service -c up /service/pci
/bin/service -c up /service/pci -dev /dev/pci
/bin/service -c up /service/input -dev /dev/kbdmux
/bin/service -c up /service/pckbd

View file

@ -20,7 +20,6 @@
#include <termios.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <sys/vm.h>
#include <sys/video.h>
#include <sys/mman.h>
#include <sys/termios.h>
@ -845,32 +844,7 @@ static int video_ioctl(devminor_t minor, unsigned long request,
endpoint_t endpt, cp_grant_id_t grant, int flags,
endpoint_t user_endpt, cdev_id_t id)
{
struct mapreqvm mapreqvm;
int r, do_map;
switch (request) {
case TIOCMAPMEM:
case TIOCUNMAPMEM:
do_map = (request == TIOCMAPMEM); /* else unmap */
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &mapreqvm,
sizeof(mapreqvm))) != OK)
return r;
if (do_map) {
mapreqvm.vaddr_ret = vm_map_phys(user_endpt,
(void *) mapreqvm.phys_offset, mapreqvm.size);
r = sys_safecopyto(endpt, grant, 0, (vir_bytes) &mapreqvm,
sizeof(mapreqvm));
} else {
r = vm_unmap_phys(user_endpt, mapreqvm.vaddr, mapreqvm.size);
}
return r;
default:
return ENOTTY;
}
}
/*===========================================================================*

View file

@ -68,8 +68,9 @@
/* 56-63 = /dev/vnd[0-7] (vnd) */
#define INPUT_MAJOR 64 /* 64 = /dev/input (input) */
#define USB_BASE_MAJOR 65 /* 65-133 = USB major range */
#define PCI_MAJOR 134 /* 134 = /dev/pci (pci) */
#define NR_DEVICES 134 /* number of (major) devices */
#define NR_DEVICES 135 /* number of (major) devices */
/* Minor device numbers for memory driver. */
# define RAM_DEV_OLD 0 /* minor device for /dev/ram */

View file

@ -6,6 +6,6 @@ INCS= elf64.h elf_common.h elf_core.h elf_generic.h \
ioc_block.h ioc_disk.h ioc_fb.h ioc_fbd.h ioc_file.h ioc_memory.h \
ioc_net.h ioc_sound.h ioc_tape.h \
kbdio.h \
procfs.h statfs.h svrctl.h video.h vm.h
procfs.h statfs.h svrctl.h video.h
.include <bsd.kinc.mk>

View file

@ -1,20 +0,0 @@
#ifndef __SYS_VM_H__
#define __SYS_VM_H__
/*
sys/vm.h
*/
/* used in ioctl to tty for mapvm map and unmap request. */
struct mapreqvm
{
int flags; /* reserved, must be 0 */
phys_bytes phys_offset;
size_t size;
int readonly;
char reserved[36]; /* reserved, must be 0 */
void *vaddr;
void *vaddr_ret;
};
#endif /* __SYS_VM_H__ */

View file

@ -176,10 +176,6 @@ int do_privctl(struct proc * caller, message * m_ptr)
if (RTS_ISSET(rp, RTS_NO_PRIV))
return(EPERM);
/* Only system processes get I/O resources? */
if (!(priv(rp)->s_flags & SYS_PROC))
return EPERM;
#if 0 /* XXX -- do we need a call for this? */
if (strcmp(rp->p_name, "fxp") == 0 ||
strcmp(rp->p_name, "rtl8139") == 0)
@ -217,10 +213,6 @@ int do_privctl(struct proc * caller, message * m_ptr)
if (RTS_ISSET(rp, RTS_NO_PRIV))
return(EPERM);
/* Only system processes get memory resources? */
if (!(priv(rp)->s_flags & SYS_PROC))
return EPERM;
/* Get the memory range */
if((r=data_copy(caller->p_endpoint,
m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
@ -252,10 +244,11 @@ int do_privctl(struct proc * caller, message * m_ptr)
if (RTS_ISSET(rp, RTS_NO_PRIV))
return(EPERM);
#if 0
/* Only system processes get IRQs? */
if (!(priv(rp)->s_flags & SYS_PROC))
return EPERM;
#endif
data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
KERNEL, (vir_bytes) &irq, sizeof(irq));
priv(rp)->s_flags |= CHECK_IRQ; /* Check IRQs */
@ -289,8 +282,6 @@ int do_privctl(struct proc * caller, message * m_ptr)
return EPERM;
if(!(sp = priv(rp)))
return EPERM;
if (!(sp->s_flags & SYS_PROC))
return EPERM;
for(i = 0; i < sp->s_nr_mem_range; i++) {
if(addr >= sp->s_mem_tab[i].mr_base &&
limit <= sp->s_mem_tab[i].mr_limit)

View file

@ -18,7 +18,6 @@
#include <machine/param.h>
#include <machine/vm.h>
#include <machine/vmparam.h>
#include <sys/vm.h>
#include <lib.h>
#include <time.h>

View file

@ -294,15 +294,13 @@ static int map_perm_check(endpoint_t caller, endpoint_t target,
*/
if(caller == TTY_PROC_NR)
return OK;
if(caller != target)
return EPERM;
if(caller == MEM_PROC_NR)
return OK;
/* Anyone else needs explicit permission from the kernel (ultimately
* set by PCI).
*/
r = sys_privquery_mem(caller, physaddr, len);
r = sys_privquery_mem(target, physaddr, len);
return r;
}
@ -337,8 +335,8 @@ int do_map_phys(message *m)
* help it if we can't map in lower than page granularity.
*/
if(map_perm_check(m->m_source, target, startaddr, len) != OK) {
printf("VM: unauthorized mapping of 0x%lx by %d\n",
startaddr, m->m_source);
printf("VM: unauthorized mapping of 0x%lx by %d for %d\n",
startaddr, m->m_source, target);
return EPERM;
}

View file

@ -3,7 +3,6 @@
#include <sys/ioctl.h>
#include <minix/partition.h>
#include <sys/vm.h>
#include <sys/mtio.h>
const char *

View file

@ -1,16 +1,18 @@
#include "inc.h"
#include <sys/ioctl.h>
#include <minix/i2c.h>
#include <dev/pci/pciio.h>
#include <minix/fb.h>
#include <minix/i2c.h>
#include <minix/keymap.h>
#include <minix/sound.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/kbdio.h>
#include <sys/termios.h>
#include <sys/time.h>
#include <sys/kbdio.h>
#include <minix/keymap.h>
#include <sys/vm.h>
#include <sys/fcntl.h>
const char *
char_ioctl_name(unsigned long req)
@ -93,8 +95,15 @@ char_ioctl_name(unsigned long req)
NAME(KIOCBELL);
NAME(KIOCSLEDS);
NAME(KIOCSMAP); /* not worth interpreting */
NAME(TIOCMAPMEM);
NAME(TIOCUNMAPMEM);
NAME(PCI_IOC_CFGREAD);
NAME(PCI_IOC_CFGWRITE);
NAME(PCI_IOC_BDF_CFGREAD);
NAME(PCI_IOC_BDF_CFGWRITE);
NAME(PCI_IOC_BUSINFO);
NAME(PCI_IOC_MAP);
NAME(PCI_IOC_UNMAP);
NAME(PCI_IOC_RESERVE);
NAME(PCI_IOC_RELEASE);
}
return NULL;
@ -267,7 +276,12 @@ char_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
struct winsize *ws;
struct kio_bell *bell;
struct kio_leds *leds;
struct mapreqvm *mapreq;
struct pciio_cfgreg *pci_cfgreg;
struct pciio_bdf_cfgreg *pci_bdf_cfgreg;
struct pciio_businfo *pci_businfo;
struct pciio_map *pci_iomap;
struct pciio_acl *pci_acl;
switch (req) {
case MINIX_I2C_IOCTL_EXEC:
@ -482,25 +496,93 @@ char_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
leds->kl_bits);
return IF_ALL;
case TIOCMAPMEM:
if ((mapreq = (struct mapreqvm *)ptr) == NULL)
return dir;
case PCI_IOC_CFGREAD:
if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL)
return IF_IN;
/* This structure has more fields, but they're all unused.. */
if (dir == IF_OUT) {
put_value(proc, "phys_offset", "%"PRIu64,
(uint64_t)mapreq->phys_offset); /* future compat */
put_value(proc, "size", "%zu", mapreq->size);
} else
put_ptr(proc, "vaddr_ret", (vir_bytes)mapreq->vaddr);
put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg);
put_value(proc, "val", "%08x", pci_cfgreg->val);
return IF_ALL;
case TIOCUNMAPMEM:
if ((mapreq = (struct mapreqvm *)ptr) == NULL)
case PCI_IOC_CFGWRITE:
if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL)
return IF_OUT;
put_ptr(proc, "vaddr", (vir_bytes)mapreq->vaddr);
put_value(proc, "size", "%zu", mapreq->size);
put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg);
put_value(proc, "val", "%08x", pci_cfgreg->val);
return IF_ALL;
case PCI_IOC_BDF_CFGREAD:
if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL)
return IF_IN;
put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus);
put_value(proc, "device", "%u", pci_bdf_cfgreg->device);
put_value(proc, "function", "%u", pci_bdf_cfgreg->function);
put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg);
put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val);
return IF_ALL;
case PCI_IOC_BDF_CFGWRITE:
if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL)
return IF_OUT;
put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus);
put_value(proc, "device", "%u", pci_bdf_cfgreg->device);
put_value(proc, "function", "%u", pci_bdf_cfgreg->function);
put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg);
put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val);
return IF_ALL;
case PCI_IOC_BUSINFO:
if ((pci_businfo = (struct pciio_businfo *)ptr) == NULL)
return IF_IN;
put_value(proc, "busno", "%u", pci_businfo->busno);
put_value(proc, "maxdevs", "%u", pci_businfo->maxdevs);
return IF_ALL;
case PCI_IOC_MAP:
if ((pci_iomap = (struct pciio_map *)ptr) == NULL)
return IF_OUT|IF_IN;
put_value(proc, "flags", "%x", pci_iomap->flags);
put_value(proc, "phys_offset", "%08x", pci_iomap->phys_offset);
put_value(proc, "size", "%zu", pci_iomap->size);
put_value(proc, "readonly", "%x", pci_iomap->readonly);
if (IF_IN == dir)
put_ptr(proc, "vaddr_ret", (vir_bytes)pci_iomap->vaddr_ret);
return IF_ALL;
case PCI_IOC_UNMAP:
if ((pci_iomap = (struct pciio_map *)ptr) == NULL)
return IF_OUT;
put_ptr(proc, "vaddr", (vir_bytes)pci_iomap->vaddr);
return IF_ALL;
case PCI_IOC_RESERVE:
if ((pci_acl = (struct pciio_acl *)ptr) == NULL)
return IF_OUT;
put_value(proc, "domain", "%u", pci_acl->domain);
put_value(proc, "bus", "%u", pci_acl->bus);
put_value(proc, "device", "%u", pci_acl->device);
put_value(proc, "function", "%u", pci_acl->function);
return IF_ALL;
case PCI_IOC_RELEASE:
if ((pci_acl = (struct pciio_acl *)ptr) == NULL)
return IF_OUT;
put_value(proc, "domain", "%u", pci_acl->domain);
put_value(proc, "bus", "%u", pci_acl->bus);
put_value(proc, "device", "%u", pci_acl->device);
put_value(proc, "function", "%u", pci_acl->function);
return IF_ALL;
default:

View file

@ -93,4 +93,28 @@ struct pciio_businfo {
#define PCI_IOC_BUSINFO _IOR('P', 4, struct pciio_businfo)
#if defined(__minix)
struct pciio_map {
int flags; /* reserved, must be 0 */
u_int phys_offset;
size_t size;
int readonly;
char reserved[36]; /* reserved, must be 0 */
void *vaddr;
void *vaddr_ret;
};
#define PCI_IOC_MAP _IOWR('P', 100, struct pciio_map)
#define PCI_IOC_UNMAP _IOW('P', 101, struct pciio_map)
struct pciio_acl {
u_int domain;
u_int bus;
u_int device;
u_int function;
};
#define PCI_IOC_RESERVE _IOW('P', 102, struct pciio_acl)
#define PCI_IOC_RELEASE _IOW('P', 103, struct pciio_acl)
#endif /* defined(__minix) */
#endif /* _DEV_PCI_PCIIO_H_ */

View file

@ -174,9 +174,6 @@ typedef char linedn_t[TTLINEDNAMELEN];
#define KIOCSLEDS _IOW('k', 2, struct kio_leds)
#define KIOCSMAP _IOW('k', 3, keymap_t)
/* /dev/video ioctls. */
#define TIOCMAPMEM _IOWR('v', 1, struct mapreqvm)
#define TIOCUNMAPMEM _IOWR('v', 2, struct mapreqvm)
#endif /* defined(__minix) */
#endif /* !_SYS_TTYCOM_H_ */