pci.h revision 1.28
1/*	$NetBSD: pci.h,v 1.28 2018/08/27 07:20:05 riastradh Exp $	*/
2
3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _LINUX_PCI_H_
33#define _LINUX_PCI_H_
34
35#ifdef _KERNEL_OPT
36#if defined(i386) || defined(amd64)
37#include "acpica.h"
38#else	/* !(i386 || amd64) */
39#define NACPICA	0
40#endif	/* i386 || amd64 */
41#endif
42
43#include <sys/types.h>
44#include <sys/param.h>
45#include <sys/bus.h>
46#include <sys/cdefs.h>
47#include <sys/kmem.h>
48#include <sys/systm.h>
49
50#include <machine/limits.h>
51
52#include <dev/pci/pcidevs.h>
53#include <dev/pci/pcireg.h>
54#include <dev/pci/pcivar.h>
55#include <dev/pci/agpvar.h>
56
57#if NACPICA > 0
58#include <dev/acpi/acpivar.h>
59#include <dev/acpi/acpi_pci.h>
60#else
61struct acpi_devnode;
62#endif
63
64#include <linux/dma-mapping.h>
65#include <linux/ioport.h>
66#include <linux/kernel.h>
67
68struct pci_driver;
69
70struct pci_bus {
71	u_int			number;
72	pci_chipset_tag_t	pb_pc;
73};
74
75struct pci_device_id {
76	uint32_t	vendor;
77	uint32_t	device;
78	uint32_t	subvendor;
79	uint32_t	subdevice;
80	uint32_t	class;
81	uint32_t	class_mask;
82	unsigned long	driver_data;
83};
84
85#define	PCI_ANY_ID		((pcireg_t)-1)
86
87#define	PCI_BASE_CLASS_DISPLAY	PCI_CLASS_DISPLAY
88
89#define	PCI_CLASS_DISPLAY_VGA						\
90	((PCI_CLASS_DISPLAY << 8) | PCI_SUBCLASS_DISPLAY_VGA)
91#define	PCI_CLASS_BRIDGE_ISA						\
92	((PCI_CLASS_BRIDGE << 8) | PCI_SUBCLASS_BRIDGE_ISA)
93CTASSERT(PCI_CLASS_BRIDGE_ISA == 0x0601);
94
95/* XXX This is getting silly...  */
96#define	PCI_VENDOR_ID_ASUSTEK	PCI_VENDOR_ASUSTEK
97#define	PCI_VENDOR_ID_ATI	PCI_VENDOR_ATI
98#define	PCI_VENDOR_ID_DELL	PCI_VENDOR_DELL
99#define	PCI_VENDOR_ID_IBM	PCI_VENDOR_IBM
100#define	PCI_VENDOR_ID_HP	PCI_VENDOR_HP
101#define	PCI_VENDOR_ID_INTEL	PCI_VENDOR_INTEL
102#define	PCI_VENDOR_ID_NVIDIA	PCI_VENDOR_NVIDIA
103#define	PCI_VENDOR_ID_SONY	PCI_VENDOR_SONY
104#define	PCI_VENDOR_ID_VIA	PCI_VENDOR_VIATECH
105
106#define	PCI_DEVICE_ID_ATI_RADEON_QY	PCI_PRODUCT_ATI_RADEON_RV100_QY
107
108#define	PCI_DEVFN(DEV, FN)						\
109	(__SHIFTIN((DEV), __BITS(3, 7)) | __SHIFTIN((FN), __BITS(0, 2)))
110#define	PCI_SLOT(DEVFN)		__SHIFTOUT((DEVFN), __BITS(3, 7))
111#define	PCI_FUNC(DEVFN)		__SHIFTOUT((DEVFN), __BITS(0, 2))
112
113#define	PCI_NUM_RESOURCES	((PCI_MAPREG_END - PCI_MAPREG_START) / 4)
114#define	DEVICE_COUNT_RESOURCE	PCI_NUM_RESOURCES
115
116#define	PCI_CAP_ID_AGP	PCI_CAP_AGP
117
118typedef int pci_power_t;
119
120#define	PCI_D0		0
121#define	PCI_D1		1
122#define	PCI_D2		2
123#define	PCI_D3hot	3
124#define	PCI_D3cold	4
125
126#define	__pci_iomem
127
128struct pci_dev {
129	struct pci_attach_args	pd_pa;
130	int			pd_kludges;	/* Gotta lose 'em...  */
131#define	NBPCI_KLUDGE_GET_MUMBLE	0x01
132#define	NBPCI_KLUDGE_MAP_ROM	0x02
133	bus_space_tag_t		pd_rom_bst;
134	bus_space_handle_t	pd_rom_bsh;
135	bus_size_t		pd_rom_size;
136	bus_space_handle_t	pd_rom_found_bsh;
137	bus_size_t		pd_rom_found_size;
138	void			*pd_rom_vaddr;
139	device_t		pd_dev;
140	struct drm_device	*pd_drm_dev; /* XXX Nouveau kludge!  */
141	struct {
142		pcireg_t		type;
143		bus_addr_t		addr;
144		bus_size_t		size;
145		int			flags;
146		bus_space_tag_t		bst;
147		bus_space_handle_t	bsh;
148		void __pci_iomem	*kva;
149	}			pd_resources[PCI_NUM_RESOURCES];
150	struct pci_conf_state	*pd_saved_state;
151	struct acpi_devnode	*pd_ad;
152	pci_intr_handle_t	*pd_intr_handles;
153
154	/* Linx API only below */
155	struct pci_bus		*bus;
156	uint32_t		devfn;
157	uint16_t		vendor;
158	uint16_t		device;
159	uint16_t		subsystem_vendor;
160	uint16_t		subsystem_device;
161	uint8_t			revision;
162	uint32_t		class;
163	bool			msi_enabled;
164};
165
166static inline device_t
167pci_dev_dev(struct pci_dev *pdev)
168{
169	return pdev->pd_dev;
170}
171
172/* XXX Nouveau kludge!  */
173static inline struct drm_device *
174pci_get_drvdata(struct pci_dev *pdev)
175{
176	return pdev->pd_drm_dev;
177}
178
179static inline void
180linux_pci_dev_init(struct pci_dev *pdev, device_t dev,
181    const struct pci_attach_args *pa, int kludges)
182{
183	const uint32_t subsystem_id = pci_conf_read(pa->pa_pc, pa->pa_tag,
184	    PCI_SUBSYS_ID_REG);
185	unsigned i;
186
187	pdev->pd_pa = *pa;
188	pdev->pd_kludges = kludges;
189	pdev->pd_rom_vaddr = NULL;
190	pdev->pd_dev = dev;
191#if (NACPICA > 0)
192	pdev->pd_ad = acpi_pcidev_find(0 /*XXX segment*/, pa->pa_bus,
193	    pa->pa_device, pa->pa_function);
194#else
195	pdev->pd_ad = NULL;
196#endif
197	pdev->bus = kmem_zalloc(sizeof(struct pci_bus), KM_NOSLEEP);
198	pdev->bus->number = pa->pa_bus;
199	pdev->bus->pb_pc = pa->pa_pc;
200	pdev->devfn = PCI_DEVFN(pa->pa_device, pa->pa_function);
201	pdev->vendor = PCI_VENDOR(pa->pa_id);
202	pdev->device = PCI_PRODUCT(pa->pa_id);
203	pdev->subsystem_vendor = PCI_SUBSYS_VENDOR(subsystem_id);
204	pdev->subsystem_device = PCI_SUBSYS_ID(subsystem_id);
205	pdev->revision = PCI_REVISION(pa->pa_class);
206	pdev->class = __SHIFTOUT(pa->pa_class, 0xffffff00UL); /* ? */
207
208	CTASSERT(__arraycount(pdev->pd_resources) == PCI_NUM_RESOURCES);
209	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
210		const int reg = PCI_BAR(i);
211
212		pdev->pd_resources[i].type = pci_mapreg_type(pa->pa_pc,
213		    pa->pa_tag, reg);
214		if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, reg,
215			pdev->pd_resources[i].type,
216			&pdev->pd_resources[i].addr,
217			&pdev->pd_resources[i].size,
218			&pdev->pd_resources[i].flags)) {
219			pdev->pd_resources[i].addr = 0;
220			pdev->pd_resources[i].size = 0;
221			pdev->pd_resources[i].flags = 0;
222		}
223		pdev->pd_resources[i].kva = NULL;
224	}
225}
226
227static inline int
228pci_find_capability(struct pci_dev *pdev, int cap)
229{
230	return pci_get_capability(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag, cap,
231	    NULL, NULL);
232}
233
234static inline int
235pci_read_config_dword(struct pci_dev *pdev, int reg, uint32_t *valuep)
236{
237	KASSERT(!ISSET(reg, 3));
238	*valuep = pci_conf_read(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag, reg);
239	return 0;
240}
241
242static inline int
243pci_read_config_word(struct pci_dev *pdev, int reg, uint16_t *valuep)
244{
245	KASSERT(!ISSET(reg, 1));
246	*valuep = pci_conf_read(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
247	    (reg &~ 2)) >> (8 * (reg & 2));
248	return 0;
249}
250
251static inline int
252pci_read_config_byte(struct pci_dev *pdev, int reg, uint8_t *valuep)
253{
254	*valuep = pci_conf_read(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
255	    (reg &~ 3)) >> (8 * (reg & 3));
256	return 0;
257}
258
259static inline int
260pci_write_config_dword(struct pci_dev *pdev, int reg, uint32_t value)
261{
262	KASSERT(!ISSET(reg, 3));
263	pci_conf_write(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag, reg, value);
264	return 0;
265}
266
267static inline int
268pci_bus_read_config_dword(struct pci_bus *bus, unsigned devfn, int reg,
269    uint32_t *valuep)
270{
271	pcitag_t tag = pci_make_tag(bus->pb_pc, bus->number, PCI_SLOT(devfn),
272	    PCI_FUNC(devfn));
273
274	KASSERT(!ISSET(reg, 1));
275	*valuep = pci_conf_read(bus->pb_pc, tag, reg & ~3) >> (8 * (reg & 3));
276
277	return 0;
278}
279
280static inline int
281pci_bus_read_config_word(struct pci_bus *bus, unsigned devfn, int reg,
282    uint16_t *valuep)
283{
284	pcitag_t tag = pci_make_tag(bus->pb_pc, bus->number, PCI_SLOT(devfn),
285	    PCI_FUNC(devfn));
286	KASSERT(!ISSET(reg, 1));
287	*valuep = pci_conf_read(bus->pb_pc, tag, reg &~ 2) >> (8 * (reg & 2));
288	return 0;
289}
290
291static inline int
292pci_bus_read_config_byte(struct pci_bus *bus, unsigned devfn, int reg,
293    uint8_t *valuep)
294{
295	pcitag_t tag = pci_make_tag(bus->pb_pc, bus->number, PCI_SLOT(devfn),
296	    PCI_FUNC(devfn));
297	*valuep = pci_conf_read(bus->pb_pc, tag, reg &~ 3) >> (8 * (reg & 3));
298	return 0;
299}
300
301static inline int
302pci_bus_write_config_dword(struct pci_bus *bus, unsigned devfn, int reg,
303    uint32_t value)
304{
305	pcitag_t tag = pci_make_tag(bus->pb_pc, bus->number, PCI_SLOT(devfn),
306	    PCI_FUNC(devfn));
307	KASSERT(!ISSET(reg, 3));
308	pci_conf_write(bus->pb_pc, tag, reg, value);
309	return 0;
310}
311
312static inline void
313pci_rmw_config(pci_chipset_tag_t pc, pcitag_t tag, int reg, unsigned int bytes,
314    uint32_t value)
315{
316	const uint32_t mask = ~((~0UL) << (8 * bytes));
317	const int reg32 = (reg &~ 3);
318	const unsigned int shift = (8 * (reg & 3));
319	uint32_t value32;
320
321	KASSERT(bytes <= 4);
322	KASSERT(!ISSET(value, ~mask));
323	value32 = pci_conf_read(pc, tag, reg32);
324	value32 &=~ (mask << shift);
325	value32 |= (value << shift);
326	pci_conf_write(pc, tag, reg32, value32);
327}
328
329static inline int
330pci_write_config_word(struct pci_dev *pdev, int reg, uint16_t value)
331{
332	KASSERT(!ISSET(reg, 1));
333	pci_rmw_config(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag, reg, 2, value);
334	return 0;
335}
336
337static inline int
338pci_write_config_byte(struct pci_dev *pdev, int reg, uint8_t value)
339{
340	pci_rmw_config(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag, reg, 1, value);
341	return 0;
342}
343
344static inline int
345pci_bus_write_config_word(struct pci_bus *bus, unsigned devfn, int reg,
346    uint16_t value)
347{
348	pcitag_t tag = pci_make_tag(bus->pb_pc, bus->number, PCI_SLOT(devfn),
349	    PCI_FUNC(devfn));
350	KASSERT(!ISSET(reg, 1));
351	pci_rmw_config(bus->pb_pc, tag, reg, 2, value);
352	return 0;
353}
354
355static inline int
356pci_bus_write_config_byte(struct pci_bus *bus, unsigned devfn, int reg,
357    uint8_t value)
358{
359	pcitag_t tag = pci_make_tag(bus->pb_pc, bus->number, PCI_SLOT(devfn),
360	    PCI_FUNC(devfn));
361	pci_rmw_config(bus->pb_pc, tag, reg, 1, value);
362	return 0;
363}
364
365static inline int
366pci_enable_msi(struct pci_dev *pdev)
367{
368#ifdef notyet
369	const struct pci_attach_args *const pa = &pdev->pd_pa;
370
371	if (pci_msi_alloc_exact(pa, &pdev->pd_intr_handles, 1))
372		return -EINVAL;
373
374	pdev->msi_enabled = 1;
375	return 0;
376#else
377	return -ENOSYS;
378#endif
379}
380
381static inline void
382pci_disable_msi(struct pci_dev *pdev __unused)
383{
384	const struct pci_attach_args *const pa = &pdev->pd_pa;
385
386	if (pdev->pd_intr_handles != NULL) {
387		pci_intr_release(pa->pa_pc, pdev->pd_intr_handles, 1);
388		pdev->pd_intr_handles = NULL;
389	}
390	pdev->msi_enabled = 0;
391}
392
393static inline void
394pci_set_master(struct pci_dev *pdev)
395{
396	pcireg_t csr;
397
398	csr = pci_conf_read(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
399	    PCI_COMMAND_STATUS_REG);
400	csr |= PCI_COMMAND_MASTER_ENABLE;
401	pci_conf_write(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
402	    PCI_COMMAND_STATUS_REG, csr);
403}
404
405static inline void
406pci_clear_master(struct pci_dev *pdev)
407{
408	pcireg_t csr;
409
410	csr = pci_conf_read(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
411	    PCI_COMMAND_STATUS_REG);
412	csr &= ~(pcireg_t)PCI_COMMAND_MASTER_ENABLE;
413	pci_conf_write(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
414	    PCI_COMMAND_STATUS_REG, csr);
415}
416
417#define	PCIBIOS_MIN_MEM	0x100000	/* XXX bogus x86 kludge bollocks */
418
419static inline bus_addr_t
420pcibios_align_resource(void *p, const struct resource *resource,
421    bus_addr_t addr, bus_size_t size)
422{
423	panic("pcibios_align_resource has accessed unaligned neurons!");
424}
425
426static inline int
427pci_bus_alloc_resource(struct pci_bus *bus, struct resource *resource,
428    bus_size_t size, bus_size_t align, bus_addr_t start, int type __unused,
429    bus_addr_t (*align_fn)(void *, const struct resource *, bus_addr_t,
430	bus_size_t) __unused,
431    struct pci_dev *pdev)
432{
433	const struct pci_attach_args *const pa = &pdev->pd_pa;
434	bus_space_tag_t bst;
435	int error;
436
437	switch (resource->flags) {
438	case IORESOURCE_MEM:
439		bst = pa->pa_memt;
440		break;
441
442	case IORESOURCE_IO:
443		bst = pa->pa_iot;
444		break;
445
446	default:
447		panic("I don't know what kind of resource you want!");
448	}
449
450	resource->r_bst = bst;
451	error = bus_space_alloc(bst, start, __type_max(bus_addr_t),
452	    size, align, 0, 0, &resource->start, &resource->r_bsh);
453	if (error)
454		return error;
455
456	resource->size = size;
457	return 0;
458}
459
460/*
461 * XXX Mega-kludgerific!  pci_get_bus_and_slot and pci_get_class are
462 * defined only for their single purposes in i915drm, in
463 * i915_get_bridge_dev and intel_detect_pch.  We can't define them more
464 * generally without adapting pci_find_device (and pci_enumerate_bus
465 * internally) to pass a cookie through.
466 */
467
468static inline int		/* XXX inline?  */
469pci_kludgey_match_bus0_dev0_func0(const struct pci_attach_args *pa)
470{
471
472	if (pa->pa_bus != 0)
473		return 0;
474	if (pa->pa_device != 0)
475		return 0;
476	if (pa->pa_function != 0)
477		return 0;
478
479	return 1;
480}
481
482static inline struct pci_dev *
483pci_get_bus_and_slot(int bus, int slot)
484{
485	struct pci_attach_args pa;
486
487	KASSERT(bus == 0);
488	KASSERT(slot == PCI_DEVFN(0, 0));
489
490	if (!pci_find_device(&pa, &pci_kludgey_match_bus0_dev0_func0))
491		return NULL;
492
493	struct pci_dev *const pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP);
494	linux_pci_dev_init(pdev, NULL, &pa, NBPCI_KLUDGE_GET_MUMBLE);
495
496	return pdev;
497}
498
499static inline int		/* XXX inline?  */
500pci_kludgey_match_isa_bridge(const struct pci_attach_args *pa)
501{
502
503	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE)
504		return 0;
505	if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA)
506		return 0;
507
508	return 1;
509}
510
511static inline void
512pci_dev_put(struct pci_dev *pdev)
513{
514
515	if (pdev == NULL)
516		return;
517
518	KASSERT(ISSET(pdev->pd_kludges, NBPCI_KLUDGE_GET_MUMBLE));
519	kmem_free(pdev, sizeof(*pdev));
520}
521
522static inline struct pci_dev *
523pci_get_class(uint32_t class_subclass_shifted __unused, struct pci_dev *from)
524{
525	struct pci_attach_args pa;
526
527	KASSERT(class_subclass_shifted == (PCI_CLASS_BRIDGE_ISA << 8));
528
529	if (from != NULL) {
530		pci_dev_put(from);
531		return NULL;
532	}
533
534	if (!pci_find_device(&pa, &pci_kludgey_match_isa_bridge))
535		return NULL;
536
537	struct pci_dev *const pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP);
538	linux_pci_dev_init(pdev, NULL, &pa, NBPCI_KLUDGE_GET_MUMBLE);
539
540	return pdev;
541}
542
543#define	__pci_rom_iomem
544
545static inline void
546pci_unmap_rom(struct pci_dev *pdev, void __pci_rom_iomem *vaddr __unused)
547{
548
549	/* XXX Disable the ROM address decoder.  */
550	KASSERT(ISSET(pdev->pd_kludges, NBPCI_KLUDGE_MAP_ROM));
551	KASSERT(vaddr == pdev->pd_rom_vaddr);
552	bus_space_unmap(pdev->pd_rom_bst, pdev->pd_rom_bsh, pdev->pd_rom_size);
553	pdev->pd_kludges &= ~NBPCI_KLUDGE_MAP_ROM;
554	pdev->pd_rom_vaddr = NULL;
555}
556
557/* XXX Whattakludge!  Should move this in sys/arch/.  */
558static int
559pci_map_rom_md(struct pci_dev *pdev)
560{
561#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
562	const bus_addr_t rom_base = 0xc0000;
563	const bus_size_t rom_size = 0x20000;
564	bus_space_handle_t rom_bsh;
565	int error;
566
567	if (PCI_CLASS(pdev->pd_pa.pa_class) != PCI_CLASS_DISPLAY)
568		return ENXIO;
569	if (PCI_SUBCLASS(pdev->pd_pa.pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
570		return ENXIO;
571	/* XXX Check whether this is the primary VGA card?  */
572	error = bus_space_map(pdev->pd_pa.pa_memt, rom_base, rom_size,
573	    (BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE), &rom_bsh);
574	if (error)
575		return ENXIO;
576
577	pdev->pd_rom_bst = pdev->pd_pa.pa_memt;
578	pdev->pd_rom_bsh = rom_bsh;
579	pdev->pd_rom_size = rom_size;
580	pdev->pd_kludges |= NBPCI_KLUDGE_MAP_ROM;
581
582	return 0;
583#else
584	return ENXIO;
585#endif
586}
587
588static inline void __pci_rom_iomem *
589pci_map_rom(struct pci_dev *pdev, size_t *sizep)
590{
591
592	KASSERT(!ISSET(pdev->pd_kludges, NBPCI_KLUDGE_MAP_ROM));
593
594	if (pci_mapreg_map(&pdev->pd_pa, PCI_MAPREG_ROM, PCI_MAPREG_TYPE_ROM,
595		(BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR),
596		&pdev->pd_rom_bst, &pdev->pd_rom_bsh, NULL, &pdev->pd_rom_size)
597	    != 0)
598		goto fail_mi;
599	pdev->pd_kludges |= NBPCI_KLUDGE_MAP_ROM;
600
601	/* XXX This type is obviously wrong in general...  */
602	if (pci_find_rom(&pdev->pd_pa, pdev->pd_rom_bst, pdev->pd_rom_bsh,
603		pdev->pd_rom_size, PCI_ROM_CODE_TYPE_X86,
604		&pdev->pd_rom_found_bsh, &pdev->pd_rom_found_size)) {
605		pci_unmap_rom(pdev, NULL);
606		goto fail_mi;
607	}
608	goto success;
609
610fail_mi:
611	if (pci_map_rom_md(pdev) != 0)
612		goto fail_md;
613
614	/* XXX This type is obviously wrong in general...  */
615	if (pci_find_rom(&pdev->pd_pa, pdev->pd_rom_bst, pdev->pd_rom_bsh,
616		pdev->pd_rom_size, PCI_ROM_CODE_TYPE_X86,
617		&pdev->pd_rom_found_bsh, &pdev->pd_rom_found_size)) {
618		pci_unmap_rom(pdev, NULL);
619		goto fail_md;
620	}
621
622success:
623	KASSERT(pdev->pd_rom_found_size <= SIZE_T_MAX);
624	*sizep = pdev->pd_rom_found_size;
625	pdev->pd_rom_vaddr = bus_space_vaddr(pdev->pd_rom_bst,
626	    pdev->pd_rom_found_bsh);
627	return pdev->pd_rom_vaddr;
628
629fail_md:
630	return NULL;
631}
632
633static inline void __pci_rom_iomem *
634pci_platform_rom(struct pci_dev *pdev __unused, size_t *sizep)
635{
636
637	*sizep = 0;
638	return NULL;
639}
640
641static inline int
642pci_enable_rom(struct pci_dev *pdev)
643{
644	const pci_chipset_tag_t pc = pdev->pd_pa.pa_pc;
645	const pcitag_t tag = pdev->pd_pa.pa_tag;
646	pcireg_t addr;
647	int s;
648
649	/* XXX Don't do anything if the ROM isn't there.  */
650
651	s = splhigh();
652	addr = pci_conf_read(pc, tag, PCI_MAPREG_ROM);
653	addr |= PCI_MAPREG_ROM_ENABLE;
654	pci_conf_write(pc, tag, PCI_MAPREG_ROM, addr);
655	splx(s);
656
657	return 0;
658}
659
660static inline void
661pci_disable_rom(struct pci_dev *pdev)
662{
663	const pci_chipset_tag_t pc = pdev->pd_pa.pa_pc;
664	const pcitag_t tag = pdev->pd_pa.pa_tag;
665	pcireg_t addr;
666	int s;
667
668	s = splhigh();
669	addr = pci_conf_read(pc, tag, PCI_MAPREG_ROM);
670	addr &= ~(pcireg_t)PCI_MAPREG_ROM_ENABLE;
671	pci_conf_write(pc, tag, PCI_MAPREG_ROM, addr);
672	splx(s);
673}
674
675static inline bus_addr_t
676pci_resource_start(struct pci_dev *pdev, unsigned i)
677{
678
679	KASSERT(i < PCI_NUM_RESOURCES);
680	return pdev->pd_resources[i].addr;
681}
682
683static inline bus_size_t
684pci_resource_len(struct pci_dev *pdev, unsigned i)
685{
686
687	KASSERT(i < PCI_NUM_RESOURCES);
688	return pdev->pd_resources[i].size;
689}
690
691static inline bus_addr_t
692pci_resource_end(struct pci_dev *pdev, unsigned i)
693{
694
695	return pci_resource_start(pdev, i) + (pci_resource_len(pdev, i) - 1);
696}
697
698static inline int
699pci_resource_flags(struct pci_dev *pdev, unsigned i)
700{
701
702	KASSERT(i < PCI_NUM_RESOURCES);
703	return pdev->pd_resources[i].flags;
704}
705
706static inline void __pci_iomem *
707pci_iomap(struct pci_dev *pdev, unsigned i, bus_size_t size)
708{
709	int error;
710
711	KASSERT(i < PCI_NUM_RESOURCES);
712	KASSERT(pdev->pd_resources[i].kva == NULL);
713
714	if (PCI_MAPREG_TYPE(pdev->pd_resources[i].type) != PCI_MAPREG_TYPE_MEM)
715		return NULL;
716	if (pdev->pd_resources[i].size < size)
717		return NULL;
718	error = bus_space_map(pdev->pd_pa.pa_memt, pdev->pd_resources[i].addr,
719	    size, BUS_SPACE_MAP_LINEAR | pdev->pd_resources[i].flags,
720	    &pdev->pd_resources[i].bsh);
721	if (error) {
722		/* Horrible hack: try asking the fake AGP device.  */
723		if (!agp_i810_borrow(pdev->pd_resources[i].addr, size,
724			&pdev->pd_resources[i].bsh))
725			return NULL;
726	}
727	pdev->pd_resources[i].bst = pdev->pd_pa.pa_memt;
728	pdev->pd_resources[i].kva = bus_space_vaddr(pdev->pd_resources[i].bst,
729	    pdev->pd_resources[i].bsh);
730
731	return pdev->pd_resources[i].kva;
732}
733
734static inline void
735pci_iounmap(struct pci_dev *pdev, void __pci_iomem *kva)
736{
737	unsigned i;
738
739	CTASSERT(__arraycount(pdev->pd_resources) == PCI_NUM_RESOURCES);
740	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
741		if (pdev->pd_resources[i].kva == kva)
742			break;
743	}
744	KASSERT(i < PCI_NUM_RESOURCES);
745
746	pdev->pd_resources[i].kva = NULL;
747	bus_space_unmap(pdev->pd_resources[i].bst, pdev->pd_resources[i].bsh,
748	    pdev->pd_resources[i].size);
749}
750
751static inline void
752pci_save_state(struct pci_dev *pdev)
753{
754
755	KASSERT(pdev->pd_saved_state == NULL);
756	pdev->pd_saved_state = kmem_alloc(sizeof(*pdev->pd_saved_state),
757	    KM_SLEEP);
758	pci_conf_capture(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
759	    pdev->pd_saved_state);
760}
761
762static inline void
763pci_restore_state(struct pci_dev *pdev)
764{
765
766	KASSERT(pdev->pd_saved_state != NULL);
767	pci_conf_restore(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag,
768	    pdev->pd_saved_state);
769	kmem_free(pdev->pd_saved_state, sizeof(*pdev->pd_saved_state));
770	pdev->pd_saved_state = NULL;
771}
772
773static inline bool
774pci_is_pcie(struct pci_dev *pdev)
775{
776
777	return (pci_find_capability(pdev, PCI_CAP_PCIEXPRESS) != 0);
778}
779
780static inline bool
781pci_dma_supported(struct pci_dev *pdev, uintmax_t mask)
782{
783
784	/* XXX Cop-out.  */
785	if (mask > DMA_BIT_MASK(32))
786		return pci_dma64_available(&pdev->pd_pa);
787	else
788		return true;
789}
790
791static inline bool
792pci_is_root_bus(struct pci_bus *bus)
793{
794
795	/* XXX Cop-out. */
796	return false;
797}
798
799#endif  /* _LINUX_PCI_H_ */
800