summaryrefslogtreecommitdiff
path: root/setup/FreeBSD/oss/build/bsdpci.inc
blob: 5cb0b55e9af0eacd9ad7d6dc05507849e558605c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Purpose: Wrapper functions for PCI drivers under FreeBSD
 */
/*
 * Copyright (C) 4Front Technologies 2005-2007. Released under BSD license.
 */
#include <dev/pci/pcivar.h>	/* For pci_get macros! */
#include <dev/pci/pcireg.h>

/* PCI Support Functions */

static oss_device_t *device_list[16];
static device_t bsd_devices[16];
static int ndevs = 0;

/*
 * Compare the device ID of this device against the IDs that this driver
 * supports.  If there is a match, set the description and return success.
 */
static int
osspci_probe (device_t dev)
{
#ifdef DEVTYPE_PCI
  int i, ok = 0;
  int vendor, device, class;
  oss_device_t *osdev;

  for (i = 0; i < ndevs; i++)
    if (dev == bsd_devices[i])	/* Already detected */
      {
	return ENXIO;
      }

  if (ndevs >= 16)
    {
      printf (DRIVER_NICK ": Too many instances\n");
      return ENXIO;
    }

  vendor = pci_get_vendor (dev);
  device = pci_get_device (dev);
  class = pci_get_class (dev);
// printf("PCI dev %08lx c=%x, v=%04x, d=%04x\n", (unsigned long)dev, class, vendor, device);

  if (class != 4)		/* Not a multimedia device */
    return ENXIO;

  for (i = 0; id_table[i].vendor != 0; i++)
    if (vendor == id_table[i].vendor && device == id_table[i].device)	/* Match */
      {
	ok = 1;
	break;
      }

  if (!ok)
    {
      return (ENXIO);
    }

  if ((osdev =
       osdev_create (dev, DRIVER_TYPE, ndevs, DRIVER_NICK, NULL)) == NULL)
    {
      return ENOMEM;
    }
  if (!DRIVER_ATTACH (osdev))
    return EIO;

  bsd_devices[ndevs] = dev;
  device_list[ndevs++] = osdev;
#endif
  return (BUS_PROBE_DEFAULT);
}

/* Attach function is only called if the probe is successful */

static int
osspci_attach (device_t dev)
{
  return 0;
}

/* Detach device. */

static int
osspci_detach (device_t dev)
{
  oss_device_t *osdev;
  int i;

  for (i = 0; i < ndevs; i++)
    {
      osdev = device_list[i];
      if (osdev->dip == dev)
	{
	  if (device_get_state(dev) == DS_BUSY)
	    device_unbusy(dev);
	  if (!DRIVER_DETACH (osdev))
	    {
	      printf (DRIVER_NICK ": Unloading busy device\n");
	      return EBUSY;
	    }
	  osdev_delete (osdev);
	}
    }

  return (0);
}

/* Called during system shutdown after sync. */

static int
osspci_shutdown (device_t dev)
{

  printf ("Mypci shutdown!\n");
  return (0);
}

/*
 * Device suspend routine.
 */
static int
osspci_suspend (device_t dev)
{

  printf ("Mypci suspend!\n");
  return (0);
}

/*
 * Device resume routine.
 */
static int
osspci_resume (device_t dev)
{

  printf ("Mypci resume!\n");
  return (0);
}

static device_method_t osspci_methods[] = {
  /* Device interface */
  DEVMETHOD (device_probe, osspci_probe),
  DEVMETHOD (device_attach, osspci_attach),
  DEVMETHOD (device_detach, osspci_detach),
  DEVMETHOD (device_shutdown, osspci_shutdown),
  DEVMETHOD (device_suspend, osspci_suspend),
  DEVMETHOD (device_resume, osspci_resume),

  {0, 0}
};

static devclass_t osspci_devclass;