36#include <sys/malloc.h>
37#include <sys/module.h>
38#include <sys/linker.h>
41#include <sys/kernel.h>
45#include <sys/rwlock.h>
46#include <sys/sglist.h>
50#include <vm/vm_extern.h>
52#include <vm/vm_object.h>
53#include <vm/vm_page.h>
54#include <vm/vm_pager.h>
57#include <machine/bus.h>
59#include <machine/resource.h>
68#ifdef COMPAT_FREEBSD32
72 u_int16_t pc_subvendor;
73 u_int16_t pc_subdevice;
82 char pd_name[PCI_MAXNAMELEN + 1];
86struct pci_match_conf32 {
88 char pd_name[PCI_MAXNAMELEN + 1];
97 u_int32_t pat_buf_len;
98 u_int32_t num_patterns;
100 u_int32_t match_buf_len;
101 u_int32_t num_matches;
104 u_int32_t generation;
108#define PCIOCGETCONF32 _IOC_NEWTYPE(PCIOCGETCONF, struct pci_conf_io32)
120 .d_version = D_VERSION,
129pci_open(
struct cdev *
dev,
int oflags,
int devtype,
struct thread *td)
133 if (oflags & FWRITE) {
134 error = securelevel_gt(td->td_ucred, 0);
157 struct pci_conf *match_buf)
161 if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
164 for (i = 0; i < num_matches; i++) {
168 if (matches[i].flags == PCI_GETCONF_NO_MATCH)
176 if (((matches[i].flags & PCI_GETCONF_MATCH_DOMAIN) != 0)
177 && (match_buf->pc_sel.pc_domain !=
178 matches[i].pc_sel.pc_domain))
181 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0)
182 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
185 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0)
186 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
189 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0)
190 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
193 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0)
194 && (match_buf->pc_vendor != matches[i].pc_vendor))
197 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0)
198 && (match_buf->pc_device != matches[i].pc_device))
201 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0)
202 && (match_buf->pc_class != matches[i].pc_class))
205 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0)
206 && (match_buf->pd_unit != matches[i].pd_unit))
209 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0)
210 && (strncmp(matches[i].pd_name, match_buf->pd_name,
211 sizeof(match_buf->pd_name)) != 0))
220#ifdef COMPAT_FREEBSD32
222pci_conf_match32(
struct pci_match_conf32 *matches,
int num_matches,
223 struct pci_conf *match_buf)
227 if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
230 for (i = 0; i < num_matches; i++) {
234 if (matches[i].flags == PCI_GETCONF_NO_MATCH)
242 if (((matches[i].flags & PCI_GETCONF_MATCH_DOMAIN) != 0)
243 && (match_buf->pc_sel.pc_domain !=
244 matches[i].pc_sel.pc_domain))
247 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0)
248 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
251 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0)
252 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
255 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0)
256 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
259 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0)
260 && (match_buf->pc_vendor != matches[i].pc_vendor))
263 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0)
264 && (match_buf->pc_device != matches[i].pc_device))
267 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0)
268 && (match_buf->pc_class != matches[i].pc_class))
271 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0)
272 && (match_buf->pd_unit != matches[i].pd_unit))
275 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0)
276 && (strncmp(matches[i].pd_name, match_buf->pd_name,
277 sizeof(match_buf->pd_name)) != 0))
287#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
288 defined(COMPAT_FREEBSD6)
292 PCI_GETCONF_NO_MATCH_OLD = 0x00,
293 PCI_GETCONF_MATCH_BUS_OLD = 0x01,
294 PCI_GETCONF_MATCH_DEV_OLD = 0x02,
295 PCI_GETCONF_MATCH_FUNC_OLD = 0x04,
296 PCI_GETCONF_MATCH_NAME_OLD = 0x08,
297 PCI_GETCONF_MATCH_UNIT_OLD = 0x10,
298 PCI_GETCONF_MATCH_VENDOR_OLD = 0x20,
299 PCI_GETCONF_MATCH_DEVICE_OLD = 0x40,
300 PCI_GETCONF_MATCH_CLASS_OLD = 0x80
301} pci_getconf_flags_old;
310 struct pcisel_old pc_sel;
312 u_int16_t pc_subvendor;
313 u_int16_t pc_subdevice;
319 u_int8_t pc_subclass;
322 char pd_name[PCI_MAXNAMELEN + 1];
326struct pci_match_conf_old {
327 struct pcisel_old pc_sel;
328 char pd_name[PCI_MAXNAMELEN + 1];
333 pci_getconf_flags_old flags;
337 struct pcisel_old pi_sel;
343#ifdef COMPAT_FREEBSD32
344struct pci_conf_old32 {
345 struct pcisel_old pc_sel;
347 uint16_t pc_subvendor;
348 uint16_t pc_subdevice;
357 char pd_name[PCI_MAXNAMELEN + 1];
361struct pci_match_conf_old32 {
362 struct pcisel_old pc_sel;
363 char pd_name[PCI_MAXNAMELEN + 1];
368 pci_getconf_flags_old flags;
371#define PCIOCGETCONF_OLD32 _IOWR('p', 1, struct pci_conf_io32)
374#define PCIOCGETCONF_OLD _IOWR('p', 1, struct pci_conf_io)
375#define PCIOCREAD_OLD _IOWR('p', 2, struct pci_io_old)
376#define PCIOCWRITE_OLD _IOWR('p', 3, struct pci_io_old)
379pci_conf_match_old(
struct pci_match_conf_old *matches,
int num_matches,
380 struct pci_conf *match_buf)
384 if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
387 for (i = 0; i < num_matches; i++) {
388 if (match_buf->pc_sel.pc_domain != 0)
394 if (matches[i].flags == PCI_GETCONF_NO_MATCH_OLD)
402 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS_OLD) != 0)
403 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
406 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV_OLD) != 0)
407 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
410 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC_OLD) != 0)
411 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
414 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR_OLD) != 0)
415 && (match_buf->pc_vendor != matches[i].pc_vendor))
418 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE_OLD) != 0)
419 && (match_buf->pc_device != matches[i].pc_device))
422 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS_OLD) != 0)
423 && (match_buf->pc_class != matches[i].pc_class))
426 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT_OLD) != 0)
427 && (match_buf->pd_unit != matches[i].pd_unit))
430 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME_OLD) != 0)
431 && (strncmp(matches[i].pd_name, match_buf->pd_name,
432 sizeof(match_buf->pd_name)) != 0))
441#ifdef COMPAT_FREEBSD32
443pci_conf_match_old32(
struct pci_match_conf_old32 *matches,
int num_matches,
444 struct pci_conf *match_buf)
448 if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
451 for (i = 0; i < num_matches; i++) {
452 if (match_buf->pc_sel.pc_domain != 0)
458 if (matches[i].flags == PCI_GETCONF_NO_MATCH_OLD)
466 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS_OLD) != 0) &&
467 (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
470 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV_OLD) != 0) &&
471 (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
474 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC_OLD) != 0) &&
475 (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
478 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR_OLD) != 0) &&
479 (match_buf->pc_vendor != matches[i].pc_vendor))
482 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE_OLD) != 0) &&
483 (match_buf->pc_device != matches[i].pc_device))
486 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS_OLD) != 0) &&
487 (match_buf->pc_class != matches[i].pc_class))
490 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT_OLD) != 0) &&
491 ((u_int32_t)match_buf->pd_unit != matches[i].pd_unit))
494 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME_OLD) != 0) &&
495 (strncmp(matches[i].pd_name, match_buf->pd_name,
496 sizeof(match_buf->pd_name)) != 0))
509#ifdef COMPAT_FREEBSD32
510 struct pci_conf32 pc32;
513 struct pci_conf_old pco;
514#ifdef COMPAT_FREEBSD32
515 struct pci_conf_old32 pco32;
522 struct pci_conf *match_buf)
528 (
struct pci_match_conf *)matches, num_matches, match_buf));
529#ifdef COMPAT_FREEBSD32
531 return (pci_conf_match32((
struct pci_match_conf32 *)matches,
532 num_matches, match_buf));
535 case PCIOCGETCONF_OLD:
536 return (pci_conf_match_old(
537 (
struct pci_match_conf_old *)matches, num_matches,
539#ifdef COMPAT_FREEBSD32
540 case PCIOCGETCONF_OLD32:
541 return (pci_conf_match_old32(
542 (
struct pci_match_conf_old32 *)matches, num_matches,
556#define PVE_NEXT_LEN(pve, datalen) \
557 ((struct pci_vpd_element *)((char *)(pve) + \
558 sizeof(struct pci_vpd_element) + (datalen)))
563 struct pci_vpd_element vpd_element, *vpd_user;
577 len =
sizeof(
struct pci_vpd_element) + strlen(vpd->vpd_ident);
579 len +=
sizeof(
struct pci_vpd_element) + vpd->
vpd_ros[i].
len;
581 len +=
sizeof(
struct pci_vpd_element) + vpd->
vpd_w[i].
len;
583 if (lvio->plvi_len == 0) {
584 lvio->plvi_len = len;
587 if (lvio->plvi_len < len) {
588 lvio->plvi_len = len;
597 KASSERT(datalen <= 255, (
"invalid VPD ident length"));
598 vpd_user = lvio->plvi_data;
599 vpd_element.pve_keyword[0] =
'\0';
600 vpd_element.pve_keyword[1] =
'\0';
601 vpd_element.pve_flags = PVE_FLAG_IDENT;
602 vpd_element.pve_datalen = datalen;
603 error = copyout(&vpd_element, vpd_user,
sizeof(vpd_element));
606 error = copyout(vpd->
vpd_ident, vpd_user->pve_data, datalen);
609 vpd_user =
PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
610 vpd_element.pve_flags = 0;
614 vpd_element.pve_datalen = vpd->
vpd_ros[i].
len;
615 error = copyout(&vpd_element, vpd_user,
sizeof(vpd_element));
618 error = copyout(vpd->
vpd_ros[i].
value, vpd_user->pve_data,
622 vpd_user =
PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
624 vpd_element.pve_flags = PVE_FLAG_RW;
625 for (i = 0; i < vpd->
vpd_wcnt; i++) {
628 vpd_element.pve_datalen = vpd->
vpd_w[i].
len;
629 error = copyout(&vpd_element, vpd_user,
sizeof(vpd_element));
632 error = copyout(vpd->
vpd_w[i].
value, vpd_user->pve_data,
636 vpd_user =
PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
638 KASSERT((
char *)vpd_user - (
char *)lvio->plvi_data == len,
639 (
"length mismatch"));
640 lvio->plvi_len = len;
650 return (
sizeof(
struct pci_match_conf));
651#ifdef COMPAT_FREEBSD32
653 return (
sizeof(
struct pci_match_conf32));
656 case PCIOCGETCONF_OLD:
657 return (
sizeof(
struct pci_match_conf_old));
658#ifdef COMPAT_FREEBSD32
659 case PCIOCGETCONF_OLD32:
660 return (
sizeof(
struct pci_match_conf_old32));
675 return (
sizeof(
struct pci_conf));
676#ifdef COMPAT_FREEBSD32
678 return (
sizeof(
struct pci_conf32));
681 case PCIOCGETCONF_OLD:
682 return (
sizeof(
struct pci_conf_old));
683#ifdef COMPAT_FREEBSD32
684 case PCIOCGETCONF_OLD32:
685 return (
sizeof(
struct pci_conf_old32));
697#if defined(COMPAT_FREEBSD32)
698 struct pci_conf_io32 *cio32;
704 case PCIOCGETCONF_OLD:
706 *cio = *(
struct pci_conf_io *)
data;
709#ifdef COMPAT_FREEBSD32
712 case PCIOCGETCONF_OLD32:
714 cio32 = (
struct pci_conf_io32 *)
data;
715 cio->pat_buf_len = cio32->pat_buf_len;
716 cio->num_patterns = cio32->num_patterns;
717 cio->patterns = (
void *)(uintptr_t)cio32->patterns;
718 cio->match_buf_len = cio32->match_buf_len;
719 cio->num_matches = cio32->num_matches;
720 cio->matches = (
void *)(uintptr_t)cio32->matches;
721 cio->offset = cio32->offset;
722 cio->generation = cio32->generation;
723 cio->status = cio32->status;
737 struct pci_conf_io *d_cio;
738#if defined(COMPAT_FREEBSD32)
739 struct pci_conf_io32 *cio32;
745 case PCIOCGETCONF_OLD:
747 d_cio = (
struct pci_conf_io *)
data;
748 d_cio->status = cio->status;
749 d_cio->generation = cio->generation;
750 d_cio->offset = cio->offset;
751 d_cio->num_matches = cio->num_matches;
754#ifdef COMPAT_FREEBSD32
757 case PCIOCGETCONF_OLD32:
759 cio32 = (
struct pci_conf_io32 *)
data;
761 cio32->status = cio->status;
762 cio32->generation = cio->generation;
763 cio32->offset = cio->offset;
764 cio32->num_matches = cio->num_matches;
779 memset(pcup, 0,
sizeof(*pcup));
786#ifdef COMPAT_FREEBSD32
788 pcup->pc32.pc_sel = pcp->pc_sel;
789 pcup->pc32.pc_hdr = pcp->pc_hdr;
790 pcup->pc32.pc_subvendor = pcp->pc_subvendor;
791 pcup->pc32.pc_subdevice = pcp->pc_subdevice;
792 pcup->pc32.pc_vendor = pcp->pc_vendor;
793 pcup->pc32.pc_device = pcp->pc_device;
794 pcup->pc32.pc_class = pcp->pc_class;
795 pcup->pc32.pc_subclass = pcp->pc_subclass;
796 pcup->pc32.pc_progif = pcp->pc_progif;
797 pcup->pc32.pc_revid = pcp->pc_revid;
798 strlcpy(pcup->pc32.pd_name, pcp->pd_name,
799 sizeof(pcup->pc32.pd_name));
800 pcup->pc32.pd_unit = (uint32_t)pcp->pd_unit;
805#ifdef COMPAT_FREEBSD32
806 case PCIOCGETCONF_OLD32:
807 pcup->pco32.pc_sel.pc_bus = pcp->pc_sel.pc_bus;
808 pcup->pco32.pc_sel.pc_dev = pcp->pc_sel.pc_dev;
809 pcup->pco32.pc_sel.pc_func = pcp->pc_sel.pc_func;
810 pcup->pco32.pc_hdr = pcp->pc_hdr;
811 pcup->pco32.pc_subvendor = pcp->pc_subvendor;
812 pcup->pco32.pc_subdevice = pcp->pc_subdevice;
813 pcup->pco32.pc_vendor = pcp->pc_vendor;
814 pcup->pco32.pc_device = pcp->pc_device;
815 pcup->pco32.pc_class = pcp->pc_class;
816 pcup->pco32.pc_subclass = pcp->pc_subclass;
817 pcup->pco32.pc_progif = pcp->pc_progif;
818 pcup->pco32.pc_revid = pcp->pc_revid;
819 strlcpy(pcup->pco32.pd_name, pcp->pd_name,
820 sizeof(pcup->pco32.pd_name));
821 pcup->pco32.pd_unit = (uint32_t)pcp->pd_unit;
825 case PCIOCGETCONF_OLD:
826 pcup->pco.pc_sel.pc_bus = pcp->pc_sel.pc_bus;
827 pcup->pco.pc_sel.pc_dev = pcp->pc_sel.pc_dev;
828 pcup->pco.pc_sel.pc_func = pcp->pc_sel.pc_func;
829 pcup->pco.pc_hdr = pcp->pc_hdr;
830 pcup->pco.pc_subvendor = pcp->pc_subvendor;
831 pcup->pco.pc_subdevice = pcp->pc_subdevice;
832 pcup->pco.pc_vendor = pcp->pc_vendor;
833 pcup->pco.pc_device = pcp->pc_device;
834 pcup->pco.pc_class = pcp->pc_class;
835 pcup->pco.pc_subclass = pcp->pc_subclass;
836 pcup->pco.pc_progif = pcp->pc_progif;
837 pcup->pco.pc_revid = pcp->pc_revid;
838 strlcpy(pcup->pco.pd_name, pcp->pd_name,
839 sizeof(pcup->pco.pd_name));
840 pcup->pco.pd_unit = pcp->pd_unit;
866 map = &td->td_proc->p_vmspace->vm_map;
867 if ((pbm->pbm_flags & ~(PCIIO_BAR_MMAP_FIXED | PCIIO_BAR_MMAP_EXCL |
868 PCIIO_BAR_MMAP_RW | PCIIO_BAR_MMAP_ACTIVATE)) != 0 ||
869 pbm->pbm_memattr != (vm_memattr_t)pbm->pbm_memattr ||
870 !pmap_is_valid_memattr(map->pmap, pbm->pbm_memattr))
881 error = bus_translate_resource(pcidev, SYS_RES_MEMORY,
886 pbase = trunc_page(membase);
889 prot = VM_PROT_READ | (((pbm->pbm_flags & PCIIO_BAR_MMAP_RW) != 0) ?
893 sg = sglist_alloc(1, M_WAITOK);
894 error = sglist_append_phys(sg, pbase, plen);
897 obj = vm_pager_allocate(OBJT_SG, sg, plen, prot, 0, td->td_ucred);
902 obj->memattr = pbm->pbm_memattr;
905 if ((pbm->pbm_flags & PCIIO_BAR_MMAP_FIXED) != 0) {
906 addr = (uintptr_t)pbm->pbm_map_base;
909 if ((pbm->pbm_flags & PCIIO_BAR_MMAP_EXCL) != 0)
910 flags |= MAP_CHECK_EXCL;
911 error = vm_mmap_object(map, &
addr, plen, prot, prot, flags, obj, 0,
914 vm_object_deallocate(obj);
917 pbm->pbm_map_base = (
void *)
addr;
918 pbm->pbm_map_length = plen;
919 pbm->pbm_bar_off = membase - pbase;
931 struct resource *res;
932 uint32_t offset,
width;
933 int bar, error,
type;
935 if (pbi->pbi_op != PCIBARIO_READ &&
936 pbi->pbi_op != PCIBARIO_WRITE)
944 offset = pbi->pbi_offset;
945 width = pbi->pbi_width;
947 if (offset +
width < offset ||
958 res = bus_alloc_resource_any(pcidev,
type, &bar, RF_ACTIVE);
963 switch (pbi->pbi_op) {
965 switch (pbi->pbi_width) {
967 pbi->pbi_value = bus_read_1(res, offset);
970 pbi->pbi_value = bus_read_2(res, offset);
973 pbi->pbi_value = bus_read_4(res, offset);
977 pbi->pbi_value = bus_read_8(res, offset);
986 switch (pbi->pbi_width) {
988 bus_write_1(res, offset, pbi->pbi_value);
991 bus_write_2(res, offset, pbi->pbi_value);
994 bus_write_4(res, offset, pbi->pbi_value);
998 bus_write_8(res, offset, pbi->pbi_value);
1008 bus_release_resource(pcidev,
type, bar, res);
1018 struct devlist *devlist_head;
1019 struct pci_conf_io *cio = NULL;
1020 struct pci_devinfo *dinfo;
1022 struct pci_bar_ioreq *pbi;
1024 struct pci_list_vpd_io *lvio;
1025 struct pci_match_conf *pattern_buf;
1028 size_t confsz, iolen;
1029 int error, ionum, i, num_patterns;
1032 struct pci_io iodata;
1033 struct pci_io_old *io_old;
1043 if ((flag & FWRITE) == 0) {
1046#ifdef COMPAT_FREEBSD32
1047 case PCIOCGETCONF32:
1050 case PCIOCGETCONF_OLD:
1051#ifdef COMPAT_FREEBSD32
1052 case PCIOCGETCONF_OLD32:
1071#ifdef COMPAT_FREEBSD32
1072 case PCIOCGETCONF32:
1075 case PCIOCGETCONF_OLD:
1076#ifdef COMPAT_FREEBSD32
1077 case PCIOCGETCONF_OLD32:
1080 cio = malloc(
sizeof(
struct pci_conf_io), M_TEMP,
1087 cio->num_matches = 0;
1095 if ((cio->offset != 0)
1097 cio->status = PCI_GETCONF_LIST_CHANGED;
1107 cio->status = PCI_GETCONF_LAST_DEVICE;
1122 iolen = min(cio->match_buf_len - (cio->match_buf_len % confsz),
1129 ionum = iolen / confsz;
1135 if ((cio->num_patterns > 0) && (cio->num_patterns <
pci_numdevs)
1136 && (cio->pat_buf_len > 0)) {
1153 cio->status = PCI_GETCONF_ERROR;
1161 pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
1163 error = copyin(cio->patterns, pattern_buf,
1169 num_patterns = cio->num_patterns;
1170 }
else if ((cio->num_patterns > 0)
1171 || (cio->pat_buf_len > 0)) {
1175 cio->status = PCI_GETCONF_ERROR;
1184 for (cio->num_matches = 0, i = 0,
1185 dinfo = STAILQ_FIRST(devlist_head);
1187 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
1188 if (i < cio->offset)
1194 name = device_get_name(dinfo->cfg.dev);
1196 strncpy(dinfo->conf.pd_name,
name,
1197 sizeof(dinfo->conf.pd_name));
1198 dinfo->conf.pd_name[PCI_MAXNAMELEN] = 0;
1199 dinfo->conf.pd_unit =
1200 device_get_unit(dinfo->cfg.dev);
1202 dinfo->conf.pd_name[0] =
'\0';
1203 dinfo->conf.pd_unit = 0;
1206 if (pattern_buf == NULL ||
1208 &dinfo->conf) == 0) {
1217 if (cio->num_matches >= ionum) {
1223 error = copyout(&pcu,
1224 (caddr_t)cio->matches +
1225 confsz * cio->num_matches, confsz);
1251 cio->status = PCI_GETCONF_LAST_DEVICE;
1253 cio->status = PCI_GETCONF_MORE_DEVS;
1258 free(pattern_buf, M_TEMP);
1264 case PCIOCWRITE_OLD:
1265 io_old = (
struct pci_io_old *)
data;
1266 iodata.pi_sel.pc_domain = 0;
1267 iodata.pi_sel.pc_bus = io_old->pi_sel.pc_bus;
1268 iodata.pi_sel.pc_dev = io_old->pi_sel.pc_dev;
1269 iodata.pi_sel.pc_func = io_old->pi_sel.pc_func;
1270 iodata.pi_reg = io_old->pi_reg;
1271 iodata.pi_width = io_old->pi_width;
1272 iodata.pi_data = io_old->pi_data;
1273 data = (caddr_t)&iodata;
1278 io = (
struct pci_io *)
data;
1279 switch(io->pi_width) {
1284 if (io->pi_reg < 0 ||
1285 io->pi_reg & (io->pi_width - 1)) {
1296 io->pi_sel.pc_bus, io->pi_sel.pc_dev,
1297 io->pi_sel.pc_func);
1300 if (cmd == PCIOCWRITE || cmd == PCIOCWRITE_OLD)
1302 if (cmd == PCIOCWRITE)
1304 pci_write_config(pcidev,
1309 else if (cmd == PCIOCREAD_OLD)
1311 pci_read_config(pcidev,
1317 pci_read_config(pcidev,
1322#ifdef COMPAT_FREEBSD4
1323 if (cmd == PCIOCREAD_OLD) {
1324 io_old->pi_data = -1;
1345 bio->pbi_sel.pc_bus, bio->pbi_sel.pc_dev,
1346 bio->pbi_sel.pc_func);
1347 if (pcidev == NULL) {
1363 io = (
struct pci_io *)
data;
1364 pcidev =
pci_find_dbsf(io->pi_sel.pc_domain, io->pi_sel.pc_bus,
1365 io->pi_sel.pc_dev, io->pi_sel.pc_func);
1367 io->pi_data = device_is_attached(pcidev);
1372 lvio = (
struct pci_list_vpd_io *)
data;
1379 lvio->plvi_sel.pc_bus, lvio->plvi_sel.pc_dev,
1380 lvio->plvi_sel.pc_func);
1381 if (pcidev == NULL) {
1390 if ((flag & FWRITE) == 0 &&
1391 (pbm->pbm_flags & PCIIO_BAR_MMAP_RW) != 0) {
1396 pbm->pbm_sel.pc_bus, pbm->pbm_sel.pc_dev,
1397 pbm->pbm_sel.pc_func);
1398 error = pcidev == NULL ? ENODEV :
pci_bar_mmap(pcidev, pbm);
1402 pbi = (
struct pci_bar_ioreq *)
data;
1405 pbi->pbi_sel.pc_bus, pbi->pbi_sel.pc_dev,
1406 pbi->pbi_sel.pc_func);
1407 if (pcidev == NULL) {
struct pci_map * pci_find_bar(device_t dev, int reg)
device_t pci_find_dbsf(uint32_t domain, uint8_t bus, uint8_t slot, uint8_t func)
int pci_bar_enabled(device_t dev, struct pci_map *pm)
struct pcicfg_vpd * pci_fetch_vpd_list(device_t dev)
#define PVE_NEXT_LEN(pve, datalen)
static void pci_conf_io_update_data(const struct pci_conf_io *cio, caddr_t data, u_long cmd)
static size_t pci_conf_size(u_long cmd)
static int pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
static d_ioctl_t pci_ioctl
static int pci_conf_match_native(struct pci_match_conf *matches, int num_matches, struct pci_conf *match_buf)
static d_close_t pci_close
static void pci_conf_for_copyout(const struct pci_conf *pcp, union pci_conf_union *pcup, u_long cmd)
static int pci_bar_mmap(device_t pcidev, struct pci_bar_mmap *pbm)
static size_t pci_match_conf_size(u_long cmd)
static int pci_bar_io(device_t pcidev, struct pci_bar_ioreq *pbi)
static void pci_conf_io_init(struct pci_conf_io *cio, caddr_t data, u_long cmd)
static int pci_conf_match(u_long cmd, struct pci_match_conf *matches, int num_matches, struct pci_conf *match_buf)
#define PCIM_BAR_MEM_BASE
struct vpd_readonly * vpd_ros