Writing Device Drivers

Common Device Access Functions

uint8_t ddi_get8(ddi_acc_handle_t handle, uint8_t *dev_addr);
uint16_t ddi_get16(ddi_acc_handle_t handle, uint16_t *dev_addr);
uint32_t ddi_get32(ddi_acc_handle_t handle, uint32_t *dev_addr);
uint64_t ddi_get64(ddi_acc_handle_t handle, uint64_t *dev_addr);

ddi_get8(9F), ddi_get16(9F), ddi_get32(9F), and ddi_get64(9F) read data from the mapped memory address, device register, or allocated DMA memory address.

The ddi_get8(9F), ddi_get16(9F), ddi_get32(9F), and ddi_get64(9F) functions read 8 bits, 16 bits, 32 bits, and 64 bits of data respectively from the device address, dev_addr.

Each individual datum is automatically translated to maintain a consistent view between the host and the device, based on the encoded information in the data access handle. The translation may involve byte-swapping if the host and the device have incompatible endian characteristics.

void ddi_put8(ddi_acc_handle_t handle,  	
			uint8_t *dev_addr, uint8_t value);
void ddi_put16(ddi_acc_handle_t handle,  	
			uint16_t *dev_addr, uint16_t value);
void ddi_put32(ddi_acc_handle_t handle,  	
			uint32_t *dev_addr, uint32_t value);
void ddi_put64(ddi_acc_handle_t handle,  	
			uint64_t *dev_addr, uint64_t value);

These routines generate a write of various sizes to the mapped memory or device register. The ddi_put8(9F), ddi_put16(9F), ddi_put32(9F), and ddi_put64(9F) functions write 8 bits, 16 bits, 32 bits, and 64 bits of data respectively to the device address, dev_addr.

Each individual datum is automatically translated to maintain a consistent view between the host and the device, based on the encoded information in the data access handle. The translation may involve byte-swapping if the host and the device have incompatible endian characteristics.

void ddi_rep_get8(ddi_acc_handle_t handle,  	
			uint8_t *host_addr, uint8_t *dev_addr, size_t repcount, uint_t flags);
void ddi_rep_get16(ddi_acc_handle_t handle,  
			uint16_t *host_addr, uint16_t *dev_addr, size_t repcount, uint_t flags);
void ddi_rep_get32(ddi_acc_handle_t handle,  	
			uint32_t *host_addr, uint32_t *dev_addr, size_t repcount, uint_t flags);
void ddi_rep_get64(ddi_acc_handle_t handle,  	
			uint64_t *host_addr, uint64_t *dev_addr, size_t repcount, uint_t flags);

These routines generate multiple reads from the mapped memory or device register. repcount data is copied from the device address, dev_addr, to the host address, host_addr. For each input datum, the ddi_rep_get8(9F), ddi_rep_get16(9F), ddi_rep_get32(9F), and ddi_rep_get64(9F) functions read 8 bits, 16 bits, 32 bits, and 64 bits of data respectively from the device address, dev_addr. dev_addr and host_addr must be aligned to the datum boundary described by the function.

Each individual datum is automatically translated to maintain a consistent view between the host and the device, based on the encoded information in the data access handle. The translation may involve byte-swapping if the host and the device have incompatible endian characteristics.

void ddi_rep_put8(ddi_acc_handle_t handle,  	
			uint8_t *host_addr, uint8_t *dev_addr, size_t repcount, uint_t flags);
void ddi_rep_put16(ddi_acc_handle_t handle,  
			uint16_t *host_addr, uint16_t *dev_addr, size_t repcount, uint_t flags);
void ddi_rep_put32(ddi_acc_handle_t handle,  	
			uint32_t *host_addr, uint32_t *dev_addr, size_t repcount, uint_t flags);
void ddi_rep_put64(ddi_acc_handle_t handle,  
			uint64_t *host_addr, uint64_t *dev_addr, size_t repcount, uint_t flags);

These routines generate multiple writes to the mapped memory or device register. repcount data is copied from the host address, host_addr, to the device address, dev_addr. For each input datum, the ddi_rep_put8(9F), ddi_rep_put16(9F), ddi_rep_put32(9F), and ddi_rep_put64(9F) functions write 8 bits, 16 bits, 32 bits, and 64 bits of data respectively to the device address, dev_addr. dev_addr and host_addr must be aligned to the datum boundary described by the function.

Each individual datum is automatically translated to maintain a consistent view between the host and the device, based on the encoded information in the data access handle. The translation may involve byte-swapping if the host and the device have incompatible endian characteristics.

int ddi_device_copy(ddi_acc_handle_t src_handle,  	
		caddr_t src_addr, ssize_t src_advcnt, ddi_acc_handle_t dest_handle,  	
		caddr_t dest_addr, ssize_t dest_advcnt, size_t bytecount, 
		uint_t dev_datasz);

The attributes encoded in the access handles, src_handle and dest_handle, govern how data is actually copied from the source to the destination. Only matching data sizes between the source and destination are supported.

Data will automatically be translated to maintain a consistent view between the source and the destination. The translation may involve byte-swapping if the source and the destination devices have incompatible endian characteristics.

void ddi_device_zero(ddi_acc_handle_t handle,  	
		caddr_t dev_addr, size_t bytecount, ssize_t dev_advcnt, uint_t dev_datasz);

ddi_device_zero(9F) function fills the given bytecount with the number of bytes of zeroes to the device register or memory.

The dev_advcnt argument determines the value of the device address, dev_addr, on each access. A value of 0 will use the same device address, dev_addr, on every access. A positive value increments the device address in the next access, while a negative value decrements the address. The device address is incremented or decremented in dev_datasz units.