1
/*********************************************************
2
* Copyright (C) 1999 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation version 2 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*********************************************************/
20
* compat_pci.h: PCI compatibility wrappers.
23
#ifndef __COMPAT_PCI_H__
24
#define __COMPAT_PCI_H__
26
#include "compat_ioport.h"
27
#include <linux/pci.h>
29
# include <linux/bios32.h>
33
/* 2.0.x has useless struct pci_dev; remap it to our own */
35
#define pci_dev vmw_pci_driver_instance
39
/* 2.0/2.2 does not have pci driver API */
40
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
41
struct vmw_pci_driver_instance {
42
struct vmw_pci_driver_instance *next;
44
struct pci_driver *pcidrv;
46
struct pci_dev *pcidev;
56
/* 2.0 has pcibios_* calls only... We have to provide pci_* compatible wrappers. */
59
pci_read_config_byte(struct pci_dev *pdev, // IN: PCI slot
60
unsigned char where, // IN: Byte to read
61
u8 *value) // OUT: Value read
63
return pcibios_read_config_byte(pdev->bus, pdev->devfn, where, value);
67
pci_read_config_dword(struct pci_dev *pdev, // IN: PCI slot
68
unsigned char where, // IN: Dword to read
69
u32 *value) // OUT: Value read
71
return pcibios_read_config_dword(pdev->bus, pdev->devfn, where, value);
75
pci_write_config_dword(struct pci_dev *pdev, // IN: PCI slot
76
unsigned char where, // IN: Dword to write
77
u32 value) // IN: Value to write
79
return pcibios_write_config_dword(pdev->bus, pdev->devfn, where, value);
85
*-----------------------------------------------------------------------------
89
* Return human readable PCI slot name. Note that some implementations
90
* return a pointer to the static storage, so returned value may be
91
* overwritten by subsequent calls to this function.
94
* Returns pointer to the string with slot name.
99
*-----------------------------------------------------------------------------
102
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
103
#define compat_pci_name(pdev) pci_name(pdev)
104
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
105
#define compat_pci_name(pdev) (pdev)->slot_name
106
#elif defined(KERNEL_2_1)
107
static inline const char*
108
compat_pci_name(struct pci_dev* pdev)
110
static char slot_name[12];
111
sprintf(slot_name, "%02X:%02X.%X", pdev->bus->number,
112
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
116
static inline const char*
117
compat_pci_name(struct pci_dev* pdev)
119
static char slot_name[12];
120
sprintf(slot_name, "%02X:%02X.%X", pdev->bus,
121
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
127
/* pci_resource_start comes in 4 flavors - 2.0, 2.2, early 2.3, 2.4+ */
129
static inline unsigned long
130
compat_pci_resource_start(struct pci_dev *pdev,
135
if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
136
printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
137
index, compat_pci_name(pdev));
140
if (addr & PCI_BASE_ADDRESS_SPACE) {
141
return addr & PCI_BASE_ADDRESS_IO_MASK;
143
return addr & PCI_BASE_ADDRESS_MEM_MASK;
146
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
147
# define compat_pci_resource_start(dev, index) \
148
(((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
149
? ((dev)->base_address[index] & PCI_BASE_ADDRESS_IO_MASK) \
150
: ((dev)->base_address[index] & PCI_BASE_ADDRESS_MEM_MASK))
151
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)
152
# define compat_pci_resource_start(dev, index) \
153
((dev)->resource[index].start)
155
# define compat_pci_resource_start(dev, index) \
156
pci_resource_start(dev, index)
159
/* since 2.3.15, a new set of s/w res flags IORESOURCE_ is introduced,
160
* we fake them by returning either IORESOURCE_{IO, MEM} prior to 2.3.15 since
161
* this is what compat_pci_request_region uses
164
static inline unsigned long
165
compat_pci_resource_flags(struct pci_dev *pdev,
170
if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
171
printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
172
index, compat_pci_name(pdev));
175
if (addr & PCI_BASE_ADDRESS_SPACE) {
176
return IORESOURCE_IO;
178
return IORESOURCE_MEM;
181
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
182
# define compat_pci_resource_flags(dev, index) \
183
(((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
184
? IORESOURCE_IO: IORESOURCE_MEM)
185
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
186
/* IORESOURCE_xxx appeared in 2.3.15 and is set in resource[].flags */
187
# define compat_pci_resource_flags(dev, index) ((dev)->resource[index].flags)
189
# define compat_pci_resource_flags(dev, index) pci_resource_flags(dev, index)
192
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
193
static inline unsigned long
194
compat_pci_resource_len(struct pci_dev *pdev, // IN
195
unsigned int index) // IN
198
unsigned char reg = PCI_BASE_ADDRESS_0 + index * 4;
200
if (pci_read_config_dword(pdev, reg, &addr) || addr == 0xFFFFFFFF) {
204
pci_write_config_dword(pdev, reg, 0xFFFFFFFF);
205
pci_read_config_dword(pdev, reg, &mask);
206
pci_write_config_dword(pdev, reg, addr);
208
if (mask == 0 || mask == 0xFFFFFFFF) {
211
if (addr & PCI_BASE_ADDRESS_SPACE) {
212
return 65536 - (mask & PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
214
return -(mask & PCI_BASE_ADDRESS_MEM_MASK);
218
#define compat_pci_resource_len(dev, index) pci_resource_len(dev, index)
221
/* pci_request_region appears in 2.4.20 */
222
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
224
compat_pci_request_region(struct pci_dev *pdev, int bar, char *name)
226
if (compat_pci_resource_len(pdev, bar) == 0) {
230
if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
231
if (!compat_request_region(compat_pci_resource_start(pdev, bar),
232
compat_pci_resource_len(pdev, bar),
236
} else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
237
if (!compat_request_mem_region(compat_pci_resource_start(pdev, bar),
238
compat_pci_resource_len(pdev, bar),
248
compat_pci_release_region(struct pci_dev *pdev, int bar)
250
if (compat_pci_resource_len(pdev, bar) != 0) {
251
if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
252
release_region(compat_pci_resource_start(pdev, bar),
253
compat_pci_resource_len(pdev, bar));
254
} else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
255
compat_release_mem_region(compat_pci_resource_start(pdev, bar),
256
compat_pci_resource_len(pdev, bar));
261
#define compat_pci_request_region(pdev, bar, name) pci_request_region(pdev, bar, name)
262
#define compat_pci_release_region(pdev, bar) pci_release_region(pdev, bar)
265
/* pci_request_regions appeears in 2.4.3 */
266
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)
268
compat_pci_request_regions(struct pci_dev *pdev, char *name)
272
for (i = 0; i < 6; i++) {
273
if (compat_pci_request_region(pdev, i, name)) {
281
compat_pci_release_region(pdev, i);
286
compat_pci_release_regions(struct pci_dev *pdev)
290
for (i = 0; i < 6; i++) {
291
compat_pci_release_region(pdev, i);
295
#define compat_pci_request_regions(pdev, name) pci_request_regions(pdev, name)
296
#define compat_pci_release_regions(pdev) pci_release_regions(pdev)
299
/* pci_enable_device is available since 2.4.0 */
300
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
301
#define compat_pci_enable_device(pdev) (0)
303
#define compat_pci_enable_device(pdev) pci_enable_device(pdev)
307
/* pci_set_master is available since 2.2.0 */
308
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
309
#define compat_pci_set_master(pdev) (0)
311
#define compat_pci_set_master(pdev) pci_set_master(pdev)
315
/* pci_disable_device is available since 2.4.4 */
316
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 4)
317
#define compat_pci_disable_device(pdev) do {} while (0)
319
#define compat_pci_disable_device(pdev) pci_disable_device(pdev)
323
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
325
* Devices supported by particular pci driver. While 2.4+ kernels
326
* can do match on subsystem and class too, we support match on
327
* vendor/device IDs only.
329
struct pci_device_id {
330
unsigned int vendor, device;
331
unsigned long driver_data;
333
#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev)
338
const struct pci_device_id *id_table;
339
int (*probe)(struct pci_dev* dev, const struct pci_device_id* id);
340
void (*remove)(struct pci_dev* dev);
345
* Note that this is static variable. Maybe everything below should be in
346
* separate compat_pci.c file, but currently only user of this file is vmxnet,
347
* and vmxnet has only one file, so it is fine. Also with vmxnet all
348
* functions below are called just once, so difference between 'inline' and
349
* separate compat_pci.c should be very small.
352
static struct vmw_pci_driver_instance *pci_driver_instances = NULL;
355
#define vmw_pci_device(instance) (instance)->pcidev
357
#define vmw_pci_device(instance) (instance)
362
*-----------------------------------------------------------------------------
364
* pci_register_driver --
366
* Create driver instances for all matching PCI devices in the box.
369
* Returns 0 for success, negative error value for failure.
374
*-----------------------------------------------------------------------------
378
pci_register_driver(struct pci_driver *drv)
380
const struct pci_device_id *chipID;
382
for (chipID = drv->id_table; chipID->vendor; chipID++) {
384
struct pci_dev *pdev;
387
(pdev = pci_find_device(chipID->vendor, chipID->device, pdev)) != NULL; ) {
390
unsigned char bus, devfn, irq;
393
pcibios_find_device(chipID->vendor, chipID->device, adapter,
397
struct vmw_pci_driver_instance *pdi;
400
pdi = kmalloc(sizeof *pdi, GFP_KERNEL);
402
printk(KERN_ERR "Not enough memory.\n");
411
if (pci_read_config_byte(pdi, PCI_INTERRUPT_LINE, &irq)) {
417
pdi->driver_data = NULL;
418
pdi->next = pci_driver_instances;
419
pci_driver_instances = pdi;
420
err = drv->probe(vmw_pci_device(pdi), chipID);
422
pci_driver_instances = pdi->next;
432
*-----------------------------------------------------------------------------
434
* compat_pci_unregister_driver --
436
* Shut down PCI driver - unbind all device instances from driver.
444
*-----------------------------------------------------------------------------
448
pci_unregister_driver(struct pci_driver *drv)
450
struct vmw_pci_driver_instance **ppdi;
452
ppdi = &pci_driver_instances;
454
struct vmw_pci_driver_instance *pdi = *ppdi;
459
if (pdi->pcidrv == drv) {
460
drv->remove(vmw_pci_device(pdi));
469
/* provide PCI_DEVICE for early 2.4.x kernels */
471
#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev), \
472
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
477
/* provide dummy MODULE_DEVICE_TABLE for 2.0/2.2 */
478
#ifndef MODULE_DEVICE_TABLE
479
#define MODULE_DEVICE_TABLE(bus, devices)
484
*-----------------------------------------------------------------------------
488
* Set per-device driver's private data.
496
*-----------------------------------------------------------------------------
500
*-----------------------------------------------------------------------------
504
* Retrieve per-device driver's private data.
507
* per-device driver's data previously set by pci_set_drvdata,
508
* or NULL on failure.
513
*-----------------------------------------------------------------------------
517
/* 2.0.x is simple, we have driver_data directly in pci_dev */
518
#define pci_set_drvdata(pdev, data) do { (pdev)->driver_data = (data); } while (0)
519
#define pci_get_drvdata(pdev) (pdev)->driver_data
520
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
521
/* 2.2.x is trickier, we have to find driver instance first */
523
pci_set_drvdata(struct pci_dev *pdev, void* data)
525
struct vmw_pci_driver_instance *pdi;
527
for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
528
if (pdi->pcidev == pdev) {
529
pdi->driver_data = data;
533
printk(KERN_ERR "pci_set_drvdata issued for unknown device %p\n", pdev);
537
pci_get_drvdata(struct pci_dev *pdev)
539
struct vmw_pci_driver_instance *pdi;
541
for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
542
if (pdi->pcidev == pdev) {
543
return pdi->driver_data;
546
printk(KERN_ERR "pci_get_drvdata issued for unknown device %p\n", pdev);
551
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)
552
# define PCI_DMA_BIDIRECTIONAL 0
553
# define PCI_DMA_TODEVICE 1
554
# define PCI_DMA_FROMDEVICE 2
555
# define PCI_DMA_NONE 3
559
* Power Management related compat wrappers.
561
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
562
# define compat_pci_save_state(pdev) pci_save_state((pdev), NULL)
563
# define compat_pci_restore_state(pdev) pci_restore_state((pdev), NULL)
565
# define compat_pci_save_state(pdev) pci_save_state((pdev))
566
# define compat_pci_restore_state(pdev) pci_restore_state((pdev))
569
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
570
# define pm_message_t u32
571
# define compat_pci_choose_state(pdev, state) (state)
575
# define compat_pci_choose_state(pdev, state) pci_choose_state((pdev), (state))
578
/* 2.6.14 changed the PCI shutdown callback */
579
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
580
# define COMPAT_PCI_SHUTDOWN(func) .driver = { .shutdown = (func), }
581
# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct device *(var))
582
# define COMPAT_PCI_TO_DEV(dev) (to_pci_dev(dev))
584
# define COMPAT_PCI_SHUTDOWN(func) .shutdown = (func)
585
# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct pci_dev *(var))
586
# define COMPAT_PCI_TO_DEV(dev) (dev)
590
#endif /* __COMPAT_PCI_H__ */