18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/drivers/misc/xillybus.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2011 Xillybus Ltd, http://xillybus.com 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Header file for the Xillybus FPGA/host framework. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __XILLYBUS_H 118c2ecf20Sopenharmony_ci#define __XILLYBUS_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/list.h> 148c2ecf20Sopenharmony_ci#include <linux/device.h> 158c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 168c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 178c2ecf20Sopenharmony_ci#include <linux/sched.h> 188c2ecf20Sopenharmony_ci#include <linux/cdev.h> 198c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 208c2ecf20Sopenharmony_ci#include <linux/mutex.h> 218c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct xilly_endpoint_hardware; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistruct xilly_buffer { 268c2ecf20Sopenharmony_ci void *addr; 278c2ecf20Sopenharmony_ci dma_addr_t dma_addr; 288c2ecf20Sopenharmony_ci int end_offset; /* Counting elements, not bytes */ 298c2ecf20Sopenharmony_ci}; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct xilly_idt_handle { 328c2ecf20Sopenharmony_ci unsigned char *chandesc; 338c2ecf20Sopenharmony_ci unsigned char *idt; 348c2ecf20Sopenharmony_ci int entries; 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* 388c2ecf20Sopenharmony_ci * Read-write confusion: wr_* and rd_* notation sticks to FPGA view, so 398c2ecf20Sopenharmony_ci * wr_* buffers are those consumed by read(), since the FPGA writes to them 408c2ecf20Sopenharmony_ci * and vice versa. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct xilly_channel { 448c2ecf20Sopenharmony_ci struct xilly_endpoint *endpoint; 458c2ecf20Sopenharmony_ci int chan_num; 468c2ecf20Sopenharmony_ci int log2_element_size; 478c2ecf20Sopenharmony_ci int seekable; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci struct xilly_buffer **wr_buffers; /* FPGA writes, driver reads! */ 508c2ecf20Sopenharmony_ci int num_wr_buffers; 518c2ecf20Sopenharmony_ci unsigned int wr_buf_size; /* In bytes */ 528c2ecf20Sopenharmony_ci int wr_fpga_buf_idx; 538c2ecf20Sopenharmony_ci int wr_host_buf_idx; 548c2ecf20Sopenharmony_ci int wr_host_buf_pos; 558c2ecf20Sopenharmony_ci int wr_empty; 568c2ecf20Sopenharmony_ci int wr_ready; /* Significant only when wr_empty == 1 */ 578c2ecf20Sopenharmony_ci int wr_sleepy; 588c2ecf20Sopenharmony_ci int wr_eof; 598c2ecf20Sopenharmony_ci int wr_hangup; 608c2ecf20Sopenharmony_ci spinlock_t wr_spinlock; 618c2ecf20Sopenharmony_ci struct mutex wr_mutex; 628c2ecf20Sopenharmony_ci wait_queue_head_t wr_wait; 638c2ecf20Sopenharmony_ci wait_queue_head_t wr_ready_wait; 648c2ecf20Sopenharmony_ci int wr_ref_count; 658c2ecf20Sopenharmony_ci int wr_synchronous; 668c2ecf20Sopenharmony_ci int wr_allow_partial; 678c2ecf20Sopenharmony_ci int wr_exclusive_open; 688c2ecf20Sopenharmony_ci int wr_supports_nonempty; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci struct xilly_buffer **rd_buffers; /* FPGA reads, driver writes! */ 718c2ecf20Sopenharmony_ci int num_rd_buffers; 728c2ecf20Sopenharmony_ci unsigned int rd_buf_size; /* In bytes */ 738c2ecf20Sopenharmony_ci int rd_fpga_buf_idx; 748c2ecf20Sopenharmony_ci int rd_host_buf_pos; 758c2ecf20Sopenharmony_ci int rd_host_buf_idx; 768c2ecf20Sopenharmony_ci int rd_full; 778c2ecf20Sopenharmony_ci spinlock_t rd_spinlock; 788c2ecf20Sopenharmony_ci struct mutex rd_mutex; 798c2ecf20Sopenharmony_ci wait_queue_head_t rd_wait; 808c2ecf20Sopenharmony_ci int rd_ref_count; 818c2ecf20Sopenharmony_ci int rd_allow_partial; 828c2ecf20Sopenharmony_ci int rd_synchronous; 838c2ecf20Sopenharmony_ci int rd_exclusive_open; 848c2ecf20Sopenharmony_ci struct delayed_work rd_workitem; 858c2ecf20Sopenharmony_ci unsigned char rd_leftovers[4]; 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistruct xilly_endpoint { 898c2ecf20Sopenharmony_ci /* 908c2ecf20Sopenharmony_ci * One of pdev and dev is always NULL, and the other is a valid 918c2ecf20Sopenharmony_ci * pointer, depending on the type of device 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_ci struct pci_dev *pdev; 948c2ecf20Sopenharmony_ci struct device *dev; 958c2ecf20Sopenharmony_ci struct xilly_endpoint_hardware *ephw; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci struct list_head ep_list; 988c2ecf20Sopenharmony_ci int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */ 998c2ecf20Sopenharmony_ci __iomem void *registers; 1008c2ecf20Sopenharmony_ci int fatal_error; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci struct mutex register_mutex; 1038c2ecf20Sopenharmony_ci wait_queue_head_t ep_wait; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci /* Channels and message handling */ 1068c2ecf20Sopenharmony_ci struct cdev cdev; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci int major; 1098c2ecf20Sopenharmony_ci int lowest_minor; /* Highest minor = lowest_minor + num_channels - 1 */ 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci int num_channels; /* EXCLUDING message buffer */ 1128c2ecf20Sopenharmony_ci struct xilly_channel **channels; 1138c2ecf20Sopenharmony_ci int msg_counter; 1148c2ecf20Sopenharmony_ci int failed_messages; 1158c2ecf20Sopenharmony_ci int idtlen; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci u32 *msgbuf_addr; 1188c2ecf20Sopenharmony_ci dma_addr_t msgbuf_dma_addr; 1198c2ecf20Sopenharmony_ci unsigned int msg_buf_size; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistruct xilly_endpoint_hardware { 1238c2ecf20Sopenharmony_ci struct module *owner; 1248c2ecf20Sopenharmony_ci void (*hw_sync_sgl_for_cpu)(struct xilly_endpoint *, 1258c2ecf20Sopenharmony_ci dma_addr_t, 1268c2ecf20Sopenharmony_ci size_t, 1278c2ecf20Sopenharmony_ci int); 1288c2ecf20Sopenharmony_ci void (*hw_sync_sgl_for_device)(struct xilly_endpoint *, 1298c2ecf20Sopenharmony_ci dma_addr_t, 1308c2ecf20Sopenharmony_ci size_t, 1318c2ecf20Sopenharmony_ci int); 1328c2ecf20Sopenharmony_ci int (*map_single)(struct xilly_endpoint *, 1338c2ecf20Sopenharmony_ci void *, 1348c2ecf20Sopenharmony_ci size_t, 1358c2ecf20Sopenharmony_ci int, 1368c2ecf20Sopenharmony_ci dma_addr_t *); 1378c2ecf20Sopenharmony_ci}; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistruct xilly_mapping { 1408c2ecf20Sopenharmony_ci void *device; 1418c2ecf20Sopenharmony_ci dma_addr_t dma_addr; 1428c2ecf20Sopenharmony_ci size_t size; 1438c2ecf20Sopenharmony_ci int direction; 1448c2ecf20Sopenharmony_ci}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ciirqreturn_t xillybus_isr(int irq, void *data); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistruct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, 1498c2ecf20Sopenharmony_ci struct device *dev, 1508c2ecf20Sopenharmony_ci struct xilly_endpoint_hardware 1518c2ecf20Sopenharmony_ci *ephw); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ciint xillybus_endpoint_discovery(struct xilly_endpoint *endpoint); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_civoid xillybus_endpoint_remove(struct xilly_endpoint *endpoint); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci#endif /* __XILLYBUS_H */ 158