3 #include <dev/pci/pciio.h>
5 #include <minix/chardriver.h>
6 #include <minix/driver.h>
12 struct pci_acl pci_acl
[NR_DRIVERS
];
14 /*======================================================================*
16 *======================================================================*/
17 static struct rs_pci
*
18 find_acl(int endpoint
)
22 /* Find ACL entry for caller */
23 for (i
= 0; i
<NR_DRIVERS
; i
++)
25 if (!pci_acl
[i
].inuse
)
27 if (pci_acl
[i
].acl
.rsp_endpoint
== endpoint
)
28 return &pci_acl
[i
].acl
;
34 reply(message
*mp
, int result
)
40 r
= ipc_send(mp
->m_source
, &m
);
42 printf("reply: unable to send to %d: %d\n", mp
->m_source
, r
);
51 printf("PCI: do_init: called by '%d'\n", mp
->m_source
);
55 r
= ipc_send(mp
->m_source
, mp
);
57 printf("PCI: do_init: unable to send to %d: %d\n",
62 do_first_dev(message
*mp
)
68 aclp
= find_acl(mp
->m_source
);
71 printf("PCI: do_first_dev: no acl for caller %d\n",
74 r
= _pci_first_dev(aclp
, &devind
, &vid
, &did
);
82 r
= ipc_send(mp
->m_source
, mp
);
85 printf("PCI: do_first_dev: unable to send to %d: %d\n",
91 do_next_dev(message
*mp
)
98 aclp
= find_acl(mp
->m_source
);
100 r
= _pci_next_dev(aclp
, &devind
, &vid
, &did
);
108 r
= ipc_send(mp
->m_source
, mp
);
111 printf("PCI: do_next_dev: unable to send to %d: %d\n",
117 do_find_dev(message
*mp
)
126 r
= _pci_find_dev(bus
, dev
, func
, &devind
);
130 r
= ipc_send(mp
->m_source
, mp
);
133 printf("PCI: do_find_dev: unable to send to %d: %d\n",
146 r
= _pci_ids(devind
, &vid
, &did
);
149 printf("pci:do_ids: failed for devind %d: %d\n",
156 r
= ipc_send(mp
->m_source
, mp
);
159 printf("PCI: do_ids: unable to send to %d: %d\n",
165 do_dev_name(message
*mp
)
167 int r
, name_len
, len
;
169 cp_grant_id_t name_gid
;
177 name
= _pci_dev_name(vid
, did
);
188 r
= sys_safecopyto(mp
->m_source
, name_gid
, 0, (vir_bytes
)name
,
193 r
= ipc_send(mp
->m_source
, mp
);
196 printf("PCI: do_dev_name: unable to send to %d: %d\n",
202 do_slot_name(message
*mp
)
204 int r
, devind
, name_len
, len
;
212 r
= _pci_slot_name(devind
, &name
);
215 printf("pci:do_slot_name_s: failed for devind %d: %d\n",
224 r
= sys_safecopyto(mp
->m_source
, gid
, 0,
225 (vir_bytes
)name
, len
);
229 r
= ipc_send(mp
->m_source
, mp
);
232 printf("PCI: do_slot_name: unable to send to %d: %d\n",
238 do_set_acl(message
*mp
)
242 if (mp
->m_source
!= RS_PROC_NR
)
244 printf("PCI: do_set_acl: not from RS\n");
249 for (i
= 0; i
<NR_DRIVERS
; i
++)
251 if (!pci_acl
[i
].inuse
)
256 printf("PCI: do_set_acl: table is full\n");
263 r
= sys_safecopyfrom(mp
->m_source
, gid
, 0, (vir_bytes
)&pci_acl
[i
].acl
,
264 sizeof(pci_acl
[i
].acl
));
267 printf("PCI: do_set_acl: safecopyfrom failed\n");
273 printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
274 pci_acl
[i
].acl
.rsp_endpoint
, pci_acl
[i
].acl
.rsp_label
,
281 do_del_acl(message
*mp
)
285 if (mp
->m_source
!= RS_PROC_NR
)
287 printf("do_del_acl: not from RS\n");
294 for (i
= 0; i
<NR_DRIVERS
; i
++)
296 if (!pci_acl
[i
].inuse
)
298 if (pci_acl
[i
].acl
.rsp_endpoint
== proc_nr
)
304 printf("do_del_acl: nothing found for %d\n", proc_nr
);
311 printf("do_acl: deleting ACL for %d ('%s') at entry %d\n",
312 pci_acl
[i
].acl
.rsp_endpoint
, pci_acl
[i
].acl
.rsp_label
, i
);
315 /* Also release all devices held by this process */
316 _pci_release(proc_nr
);
322 do_reserve(message
*mp
)
329 aclp
= find_acl(mp
->m_source
);
331 mp
->m_type
= _pci_reserve(devind
, mp
->m_source
, aclp
);
332 r
= ipc_send(mp
->m_source
, mp
);
335 printf("do_reserve: unable to send to %d: %d\n",
341 do_attr_r8(message
*mp
)
349 r
= _pci_attr_r8(devind
, port
, &v
);
353 "pci:do_attr_r8: pci_attr_r8(%d, %d, ...) failed: %d\n",
358 r
= ipc_send(mp
->m_source
, mp
);
361 printf("do_attr_r8: unable to send to %d: %d\n",
367 do_attr_r16(message
*mp
)
375 r
= _pci_attr_r16(devind
, port
, &v
);
379 "pci:do_attr_r16: pci_attr_r16(%d, %d, ...) failed: %d\n",
384 r
= ipc_send(mp
->m_source
, mp
);
387 printf("do_attr_r16: unable to send to %d: %d\n",
393 do_attr_r32(message
*mp
)
401 r
= _pci_attr_r32(devind
, port
, &v
);
405 "pci:do_attr_r32: pci_attr_r32(%d, %d, ...) failed: %d\n",
410 r
= ipc_send(mp
->m_source
, mp
);
413 printf("do_attr_r32: unable to send to %d: %d\n",
419 do_attr_w8(message
*mp
)
428 _pci_attr_w8(devind
, port
, v
);
430 r
= ipc_send(mp
->m_source
, mp
);
433 printf("do_attr_w8: unable to send to %d: %d\n",
439 do_attr_w16(message
*mp
)
448 _pci_attr_w16(devind
, port
, v
);
450 r
= ipc_send(mp
->m_source
, mp
);
453 printf("do_attr_w16: unable to send to %d: %d\n",
459 do_attr_w32(message
*mp
)
468 _pci_attr_w32(devind
, port
, v
);
470 r
= ipc_send(mp
->m_source
, mp
);
473 printf("do_attr_w32: unable to send to %d: %d\n",
479 do_get_bar(message
*mp
)
481 int r
, devind
, port
, ioflag
;
484 devind
= mp
->m_lsys_pci_busc_get_bar
.devind
;
485 port
= mp
->m_lsys_pci_busc_get_bar
.port
;
487 mp
->m_type
= _pci_get_bar(devind
, port
, &base
, &size
, &ioflag
);
489 if (mp
->m_type
== OK
)
491 mp
->m_pci_lsys_busc_get_bar
.base
= base
;
492 mp
->m_pci_lsys_busc_get_bar
.size
= size
;
493 mp
->m_pci_lsys_busc_get_bar
.flags
= ioflag
;
496 r
= ipc_send(mp
->m_source
, mp
);
499 printf("do_get_bar: unable to send to %d: %d\n",
505 do_rescan_bus(message
*mp
)
511 _pci_rescan_bus(busnr
);
513 r
= ipc_send(mp
->m_source
, mp
);
516 printf("do_rescan_bus: unable to send to %d: %d\n",
521 /*======================================================================*
522 * CharDriver Callbacks *
523 *======================================================================*/
525 pci_open(devminor_t
UNUSED(minor
), int UNUSED(access
),
526 endpoint_t
UNUSED(user_endpt
))
532 pci_close(devminor_t
UNUSED(minor
))
538 pci_ioctl(devminor_t minor
, unsigned long request
, endpoint_t endpt
,
539 cp_grant_id_t grant
, int flags
, endpoint_t user_endpt
, cdev_id_t id
)
546 case PCI_IOC_BDF_CFGREAD
:
548 struct pciio_bdf_cfgreg bdf
;
550 if ((r
= sys_safecopyfrom(endpt
, grant
, 0, (vir_bytes
)&bdf
,
554 r
= _pci_find_dev(bdf
.bus
, bdf
.device
, bdf
.function
, &devind
);
560 if ((r
= _pci_attr_r32(devind
, bdf
.cfgreg
.reg
,
561 &bdf
.cfgreg
.val
)) != OK
)
564 r
= sys_safecopyto(endpt
, grant
, 0, (vir_bytes
)&bdf
,
568 case PCI_IOC_BDF_CFGWRITE
:
570 struct pciio_bdf_cfgreg bdf
;
572 if ((r
= sys_safecopyfrom(endpt
, grant
, 0, (vir_bytes
)&bdf
,
576 r
= _pci_find_dev(bdf
.bus
, bdf
.device
, bdf
.function
, &devind
);
582 _pci_attr_w32(devind
, bdf
.cfgreg
.reg
, bdf
.cfgreg
.val
);
586 case PCI_IOC_BUSINFO
:
590 struct pciio_map map
;
591 struct minix_mem_range mr
;
593 if ((r
= sys_safecopyfrom(endpt
, grant
, 0,
594 (vir_bytes
)&map
, sizeof(map
))) != OK
)
598 mr
.mr_base
= map
.phys_offset
;
599 mr
.mr_limit
= map
.phys_offset
+ map
.size
- 1;
601 r
= sys_privctl(user_endpt
, SYS_PRIV_ADD_MEM
, &mr
);
608 map
.vaddr_ret
= vm_map_phys(user_endpt
,
609 (void *)map
.phys_offset
, map
.size
);
610 r
= sys_safecopyto(endpt
, grant
, 0, (vir_bytes
)&map
,
616 struct pciio_map map
;
618 if ((r
= sys_safecopyfrom(endpt
, grant
, 0,
619 (vir_bytes
)&map
, sizeof(map
))) != OK
)
622 r
= vm_unmap_phys(user_endpt
, map
.vaddr
, map
.size
);
625 case PCI_IOC_RESERVE
:
627 struct pciio_acl acl
;
629 if ((r
= sys_safecopyfrom(endpt
, grant
, 0,
630 (vir_bytes
)&acl
, sizeof(acl
))) != OK
)
633 r
= _pci_find_dev(acl
.bus
, acl
.device
, acl
.function
, &devind
);
639 r
= _pci_grant_access(devind
, user_endpt
);
642 case PCI_IOC_RELEASE
:
644 struct pciio_acl acl
;
646 if ((r
= sys_safecopyfrom(endpt
, grant
, 0,
647 (vir_bytes
)&acl
, sizeof(acl
))) != OK
)
650 r
= _pci_find_dev(acl
.bus
, acl
.device
, acl
.function
, &devind
);
661 case PCI_IOC_CFGREAD
:
662 case PCI_IOC_CFGWRITE
:
670 pci_other(message
*m
, int ipc_status
)
674 case BUSC_PCI_INIT
: do_init(m
); break;
675 case BUSC_PCI_FIRST_DEV
: do_first_dev(m
); break;
676 case BUSC_PCI_NEXT_DEV
: do_next_dev(m
); break;
677 case BUSC_PCI_FIND_DEV
: do_find_dev(m
); break;
678 case BUSC_PCI_IDS
: do_ids(m
); break;
679 case BUSC_PCI_RESERVE
: do_reserve(m
); break;
680 case BUSC_PCI_ATTR_R8
: do_attr_r8(m
); break;
681 case BUSC_PCI_ATTR_R16
: do_attr_r16(m
); break;
682 case BUSC_PCI_ATTR_R32
: do_attr_r32(m
); break;
683 case BUSC_PCI_ATTR_W8
: do_attr_w8(m
); break;
684 case BUSC_PCI_ATTR_W16
: do_attr_w16(m
); break;
685 case BUSC_PCI_ATTR_W32
: do_attr_w32(m
); break;
686 case BUSC_PCI_RESCAN
: do_rescan_bus(m
); break;
687 case BUSC_PCI_DEV_NAME_S
: do_dev_name(m
); break;
688 case BUSC_PCI_SLOT_NAME_S
: do_slot_name(m
); break;
689 case BUSC_PCI_SET_ACL
: do_set_acl(m
); break;
690 case BUSC_PCI_DEL_ACL
: do_del_acl(m
); break;
691 case BUSC_PCI_GET_BAR
: do_get_bar(m
); break;
693 printf("PCI: unhandled message from %d, type %d\n",
694 m
->m_source
, m
->m_type
);
699 static struct chardriver driver
=
701 .cdr_open
= pci_open
,
702 .cdr_close
= pci_close
,
703 .cdr_ioctl
= pci_ioctl
,
704 .cdr_other
= pci_other
,
707 /*======================================================================*
709 *======================================================================*/
710 /* NOTE: sef_cb_init is in pci.c. */
712 sef_local_startup(void)
715 * Register init callbacks. Use the same function for all event types
717 sef_setcb_init_fresh(sef_cb_init
);
718 sef_setcb_init_restart(sef_cb_init
);
720 /* Let SEF perform startup. */
724 /*======================================================================*
726 *======================================================================*/
731 * Perform initialization.
738 chardriver_task(&driver
);