This function returns a device handle for a device that matches the given device and vendor ID.
A driver can query multiple devices with the same device and vendor ID by starting with index 0 and calling this function until PCI_DEVICE_NOT_FOUND is returned.
find_pci_device:
Input:
D0.L Device ID in bits 31..16 (0 - $FFFF),
Vendor ID in bits 15..0 (0 - $FFFE)
D1.W Index (0 - # of cards with these IDs)
Output:
D0.L device handle or error code
As a special case, Vendor ID $FFFF
can be used to query all cards found in
the system, the specified device ID is ignored in this case.
This function returns a device handle for a device that matches the given class code.
A driver can query multiple devices with the same class code by starting with index 0 and calling this function until PCI_DEVICE_NOT_FOUND is returned.
find_pci_classcode:
Input:
D0.L class code in bits 23..0:
Base class in bit 23..16 (0 - $FF),
Sub class in bit 15..8 (0 - $FF),
Prog. If. in bit 7..0 (0)
mask in bits 26..24:
bit 26: if 0 = compare base class, else ignore it
bit 25: if 0 = compare sub class, else ignore it
bit 24: if 0 = compare prog. if, else ignore it
D1.W Index (0 - # of cards with these IDs)
Output:
D0.L device handle or error code
These three functions read data from the PCI configuration space of a given card.
The data is in little endian format, as described in the PCI specification.
read_config_byte:
read_config_word:
read_config_longword:
Input:
D0.L device handle
A0.L pointer to space for read data
D1.B Register number (0,1,2,... for Byte access)
D1.B Register number (0,2,4,... for Word access)
D1.B Register number (0,4,8,... for Longword access)
Output:
D0.L error code
read data at buffer pointed to by A0
These three functions read data from the PCI configuration space of a given card. They do only minimal error checking and are meant to be used only when access to configuration space is needed in interrupt handlers.
The data is in little endian format, as described in the PCI specification.
fast_read_config_byte:
fast_read_config_word:
fast_read_config_longword:
Input:
D0.L device handle
D1.B Register number (0,1,2,... for Byte access)
D1.B Register number (0,2,4,... for Word access)
D1.B Register number (0,4,8,... for Longword access)
Output:
D0 read data (8, 16 or 32 bits)
SR: carry flag may be set if an error occurred
(implementation dependent)
These three functions write data to the PCI configuration space of a given card.
The data is in little endian format, as described in the PCI specification.
write_config_byte:
write_config_word:
write_config_longword:
Input:
D0.L device handle
D1.B Register number (0,1,2,... for Byte access)
D1.B Register number (0,2,4,... for Word access)
D1.B Register number (0,4,8,... for Longword access)
D2 data to write (8/16/32 bits)
Output:
D0.L error code
This function hooks the driver into the interrupt chain to which a specific interrupt on the given card is routed. The interrupt is enabled on the system level, however, it is the drivers responsibility to enable the interrupt on the card as needed.
The driver should first hook into the interrupt chain, and then enable the interrupt on the card, in order not to cause spurious interrupts.
hook_interrupt:
Input:
D0.L device handle
A0.L pointer to interrupt handler
A1.L parameter for interrupt handler.
Output:
D0.L error code
The parameter (from A1) is passed to the interrupt handler unmodified - its
meaning is totally driver dependent.
This function removes the driver from the interrupt chain to which a specific interrupt on the given card is routed. The driver must turn off interrupt generation on the card before calling this function.
unhook_interrupt:
Input:
D0.L device handle
Output:
D0.L error code
This function generates a special cycle on the PCI bus.
special_cycle:
Input:
D0.B bus number
D1.L special cycle data
Output:
D0.L error code
to be defined. Not for use by device drivers.
to be defined. Not for use by device drivers.
This function returns data about the resources which a device uses. The returned structure may not be modified by the driver.
The driver can then use these information and directly access the device if he knows the type of byte ordering, or it can use the system routines (read|write_mem|io...) which handle this transparently.
The function returns a pointer to the first resource descriptor for this device. The driver can get the next descriptor by adding the length field to the address of the current descriptor.
The descriptors are in the same order as the base address registers in the PCI configuration space of the device.
If bit 15 of the flags is set, there is no next descriptor.
A device can have multiple resources of the same type.
get_resource:
Input:
D0.L device handle
Output:
D0.L pointer to array of resource descriptors or error code
The resource descriptors look like this:
struct resource_descriptor:
next DS.W 1 ; length of this structure in bytes
; Use this to get next descriptor
flags DS.W 1 ; type of resource and misc flags
start DS.L 1 ; start address of resource in PCI address space
length DS.L 1 ; length of resource
offset DS.L 1 ; offset from PCI to physical CPU address
dmaoffset DS.L 1 ; offset for DMA-Memory transfers.
private DS.B n ; private data, used only by the PCI BIOS. Do not touch.
The flags
field is bit-coded as follows:
RSC_IO = $4000 ; This is an IO area (Memory area if bit is clear)
RSC_LAST = $8000 ; last resource for this device
FLG_8BIT = $0100 ; 8-bit accesses are supported
FLG_16BIT = $0200 ; 16-bit accesses are supported
FLG_32BIT = $0400 ; 32-bit accesses are supported
FLG_ENDMASK = $000F ; Bit 0..3 specify which byte ordering is used:
0 = Motorola.
1 = Intel, address-swapped
2 = Intel, lane-swapped
3..14 = reserved
15 = unknown. Access card only via BIOS functions.
The start
field contains the start address on the PCI bus of the
resource. If the resource is not directly accessible, the start address is
0.
The length
field contains its length.
The offset
field contains the offset from physical CPU to PCI address
for the resource - ie. the value that must be added to the PCI address to
get the physical address in CPU address space.
The dmaoffset
gives the offset that must be added to a PCI address to
get the physical address in CPU address space when doing DMA transfers.
Motorola byte ordering (big endian) is what you would expect on a 680x0 system: 8/16/32 bit accesses work as expected.
When address-swapped Intel (little endian) byte ordering is used, 32 bit accesses work without modifications. On 16 bit accesses, the address needs to be XOR'd with a value of 2, on 8-bit accesses the address is XOR'd with a value of 3. The data read or written is in correct format.
When lane-swapped Intel (little endian) byte ordering is used, the address needs no modifications. 8-bit accesses work normal, on 16 and 32 bit accesses the read or written data needs to be swapped (ror.w #8,d0 for 16 bit, ror.w d0:swap d0:ror.w d0 for 32 bit).
These functions read or write 8, 16 or 32-bit values from a memory region and take care of the byte ordering - ie. the data and address are converted as if Motorola byte ordering was in use.
A driver can use these functions for access to registers and small buffers. For larger amounts of data, the driver can choose to use his own copy routines, provided it knows the byte order in use.
read_mem_byte:
read_mem_word:
read_mem_longword:
Input:
D0.L device handle
D1.L address to access (in PCI memory address space)
A0.L pointer to data in memory
Output:
D0.L error code
read data at buffer pointed to by A0
write_mem_byte:
write_mem_word:
write_mem_longword:
Input:
D0.L device handle
D1.L address to access (in PCI memory address space)
D2 data to write (8/16/32 bits)
Output:
D0.L error code
These functions read or write 8, 16 or 32-bit values from a IO region and take care of the byte ordering - ie. the data and address are converted as if Motorola byte ordering was in use.
read_io_byte:
read_io_word:
read_io_longword:
Input:
D0.L device handle
D1.L address to access (in PCI IO address space)
A0.L pointer to data in memory
Output:
D0.L error code
write_io_byte:
write_io_word:
write_io_longword:
Input:
D0.L device handle
D1.L address to access (in PCI IO address space)
D2 data to write (8/16/32 bits)
Output:
D0.L error code
These functions are alternatives for the normal memory/io read functions. They return the read value in D0 and return no error code, which makes them easier to use in C.
fast_read_mem_byte:
fast_read_mem_word:
fast_read_mem_longword:
fast_read_io_byte:
fast_read_io_word:
fast_read_io_longword:
Input:
D0.L device handle
D1.L address to access (in PCI IO address space)
Output:
D0.L read data
find_pci_device
or find_pci_classcode
to find out if there is a supported card and get a device handle for the
cardget_resource*
to read the start address and length of a used
resource, then add the offset from the resource descriptor to the
address to directly access the card.